> ## Documentation Index
> Fetch the complete documentation index at: https://webhooks.docs.crm.africa/llms.txt
> Use this file to discover all available pages before exploring further.

# Grow CRM Project Webhook Events: Payload Reference

> Reference for project.created, project.updated, project.deleted, project.sundry, project.activity, and project.imported webhook event payloads.

Grow CRM emits six webhook event keys for the Projects resource: `project.created`, `project.updated`, `project.deleted`, `project.sundry`, `project.activity`, and `project.imported`. Use these events to sync project state, trigger automations, and react to activity on any project in your workspace. Every key except `project.deleted` carries the full project object; `project.imported` delivers a batch shape instead of a single record.

<Note>
  The webhook envelope structure, delivery behaviour, and retry logic are documented in [Introduction](/introduction). Signature verification is covered in [Verification](/verification). Those conventions apply to every event on this page and are not repeated here.
</Note>

***

## The project object

Every event key except `project.deleted` and `project.imported` carries this shape — flat inside `data` for `project.created`, or nested under `data.project` for `project.updated` and `project.sundry`.

| Field          | Type             | Notes                                                                                            |
| -------------- | ---------------- | ------------------------------------------------------------------------------------------------ |
| `id`           | integer          | `project_id`.                                                                                    |
| `title`        | string           |                                                                                                  |
| `description`  | string\|null     |                                                                                                  |
| `status`       | string           |                                                                                                  |
| `active_state` | string           | `active` or `archived`.                                                                          |
| `progress`     | integer          | 0–100.                                                                                           |
| `client`       | object           | `{ id, name }`.                                                                                  |
| `category`     | object           | `{ id, name }`.                                                                                  |
| `dates`        | object           | `start` and `due` are date-only strings; `created` and `updated` are ISO 8601 with microseconds. |
| `assigned`     | array            | `[{ id, name }]`, one entry per assigned user.                                                   |
| `tags`         | array of strings |                                                                                                  |

```json theme={null}
{
  "id": 305,
  "title": "Website Redesign",
  "description": "Full site rebuild.",
  "status": "in_progress",
  "active_state": "active",
  "progress": 40,
  "client": { "id": 12, "name": "Acme Inc" },
  "category": { "id": 2, "name": "Design" },
  "dates": {
    "start": "2026-07-01",
    "due": "2026-09-01",
    "created": "2026-06-28T10:00:00.000000Z",
    "updated": "2026-07-16T08:12:00.000000Z"
  },
  "assigned": [{ "id": 34, "name": "John Smith" }],
  "tags": ["priority"]
}
```

***

## `project.created`

Fires when a project is created, **including via clone**. `data` is the full project object.

```json theme={null}
{
  "event": "project.created",
  "id": 305,
  "created": "2026-07-16T08:00:00+00:00",
  "data": {
    "id": 305,
    "title": "Website Redesign",
    "description": null,
    "status": "not_started",
    "active_state": "active",
    "progress": 0,
    "client": { "id": 12, "name": "Acme Inc" },
    "category": { "id": 1, "name": "Default" },
    "dates": {
      "start": null,
      "due": null,
      "created": "2026-07-16T08:00:00.000000Z",
      "updated": "2026-07-16T08:00:00.000000Z"
    },
    "assigned": [],
    "tags": []
  }
}
```

***

## `project.updated`

Fires on a significant change to a project. Read `data.change` to determine what changed; `data.project` contains the full project object reflecting the new state.

| `data.change`  | Fires when                                     |
| -------------- | ---------------------------------------------- |
| `edited`       | The main project edit form is saved.           |
| `status`       | The project's status changes.                  |
| `progress`     | The project's progress percentage changes.     |
| `assigned`     | The project's assigned user(s) change.         |
| `automation`   | The project's automation settings are updated. |
| `active_state` | The project is archived or restored.           |

```json theme={null}
{
  "event": "project.updated",
  "id": 305,
  "created": "2026-07-16T08:05:00+00:00",
  "data": {
    "change": "progress",
    "project": { "id": 305, "progress": 40, "...": "..." }
  }
}
```

***

## `project.sundry`

Fires on a minor, cosmetic field edit. Read `data.field` to determine which field changed; `data.project` contains the full project object.

<Info>
  Use `project.sundry` when you need to react to low-significance edits without commingling them with the higher-significance `project.updated` stream.
</Info>

| `data.field`  | Fires when                                      |
| ------------- | ----------------------------------------------- |
| `description` | The project's description is edited on its own. |
| `category`    | The project's category is changed.              |

```json theme={null}
{
  "event": "project.sundry",
  "id": 305,
  "created": "2026-07-16T08:07:00+00:00",
  "data": {
    "field": "category",
    "project": { "id": 305, "category": { "id": 2, "name": "Design" }, "...": "..." }
  }
}
```

***

## `project.activity`

Fires when a child record on a project changes. Projects produce the widest range of activity types of any resource — comments, files, notes, checklists, checklist comments, and milestones all arrive here. Read `data.type` and `data.action` together to determine exactly what happened; `data.item` contains the affected child record.

| `data.type`         | `data.action`                                   | `data.item` shape                                                                                                                                  |
| ------------------- | ----------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------- |
| `comment`           | `added`, `deleted`                              | `{ id, text, author, created }` — `author` is the commenter's first name only.                                                                     |
| `attachment`        | `added`, `deleted`                              | `{ id, uniqueid, filename }` — files on the project's Files tab. The delete event reads the record before removal, so the full shape is available. |
| `note`              | `added`, `updated`, `deleted`                   | `{ id, title, text, created }`                                                                                                                     |
| `checklist`         | `added`, `updated`, `deleted`, `status_changed` | `{ id, text, status, created }`                                                                                                                    |
| `checklist_comment` | `added`, `deleted`                              | `{ id, checklist_id, text, author, created }`                                                                                                      |
| `milestone`         | `added`, `updated`, `deleted`                   | `{ id, title, color, created }`                                                                                                                    |

```json theme={null}
{
  "event": "project.activity",
  "id": 305,
  "created": "2026-07-16T08:10:00+00:00",
  "data": {
    "type": "comment",
    "action": "added",
    "item": {
      "id": 601,
      "text": "Kickoff scheduled for Monday.",
      "author": "Jane",
      "created": "2026-07-16T08:10:00.000000Z"
    }
  }
}
```

<Expandable title="Checklist status_changed">
  `status_changed` is a checklist-specific action, fired when an item is ticked or un-ticked. It lets you react to progress changes without diffing state — `item.status` is always `pending` or `completed`.

  ```json theme={null}
  {
    "event": "project.activity",
    "id": 305,
    "created": "2026-07-31T08:20:00+00:00",
    "data": {
      "type": "checklist",
      "action": "status_changed",
      "item": {
        "id": 77,
        "text": "Sign off wireframes",
        "status": "completed",
        "created": "2026-07-30 14:00:00"
      }
    }
  }
  ```
</Expandable>

<Expandable title="checklist_comment vs comment">
  Comments left on a checklist item arrive as `type: "checklist_comment"`, kept separate from `type: "comment"` so a note on a checklist item is never mistaken for a comment on the project. The `checklist_id` field names the checklist item the comment belongs to.
</Expandable>

<Expandable title="Milestone example">
  ```json theme={null}
  {
    "event": "project.activity",
    "id": 305,
    "created": "2026-07-31T08:25:00+00:00",
    "data": {
      "type": "milestone",
      "action": "added",
      "item": {
        "id": 14,
        "title": "Phase 2 — build",
        "color": "info",
        "created": "2026-07-31 08:25:00"
      }
    }
  }
  ```
</Expandable>

<Warning>
  **Notes marked private are never delivered.** Personal notes attached to a user rather than a project are also excluded. Reordering checklist items or milestones does not fire an event. Importing a checklist fires nothing per item.
</Warning>

***

## `project.deleted`

Fires after the project is deleted. Because the record no longer exists at delivery time, `data` contains only the project id.

```json theme={null}
{
  "event": "project.deleted",
  "id": 305,
  "created": "2026-07-16T08:15:00+00:00",
  "data": { "id": 305 }
}
```

***

## `project.imported`

Fires when a bulk project import finishes. Imported projects do **not** additionally fire `project.created`.

<Note>
  See [Imports](/events#imports) for the batch shape, batching rules, and the fields common to every import event.
</Note>

Each project record inside `data.records` carries the following fields:

| Field       | Type          |
| ----------- | ------------- |
| `id`        | integer       |
| `title`     | string        |
| `client_id` | integer\|null |
| `created`   | string        |

```json theme={null}
{
  "event": "project.imported",
  "id": "8f3ka92m",
  "created": "2026-07-31T10:00:00+00:00",
  "data": {
    "import_ref": "8f3ka92m",
    "imported_by": 3,
    "batch": 1,
    "batch_count": 1,
    "totals": { "imported": 120, "skipped": 0, "errors": 2 },
    "records": [
      {
        "id": 305,
        "title": "Acme website rebuild",
        "client_id": 12,
        "created": "2026-07-31 10:00:00"
      }
    ]
  }
}
```
