> ## 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.

# Lead Webhooks — Full Payload Reference | Grow CRM

> Complete payload reference for all Grow CRM lead webhook events: created, updated, deleted, sundry, activity, and imported, with JSON examples.

Grow CRM fires six distinct event keys for lead records: `lead.created`, `lead.updated`, `lead.deleted`, `lead.sundry`, `lead.activity`, and `lead.imported`. Use these events to power pipeline automation, sync leads into external CRMs, trigger follow-up workflows on status changes, and process bulk imports as a single batched notification.

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

***

## The lead object

Every event key except `lead.deleted` carries the full lead object. For `lead.created` it appears flat directly inside `data`; for `lead.updated` and `lead.sundry` it is nested under `data.lead`.

```json theme={null}
{
  "id": 88,
  "title": "Acme Inc - Website Redesign",
  "value": "5000.00",
  "status": { "id": 2, "title": "Contacted", "color": "info" },
  "active_state": "active",
  "category": { "id": 3, "name": "Referral" },
  "source": "Website",
  "contact": {
    "first_name": "Jane",
    "last_name": "Doe",
    "email": "jane@acme.example",
    "phone": "+1 555 0100",
    "company_name": "Acme Inc"
  },
  "converted": { "is_converted": false, "client_id": null, "date": null },
  "assigned": [ { "id": 34, "name": "John Smith" } ],
  "tags": ["hot"],
  "dates": { "created": "2026-07-10T09:00:00.000000Z", "updated": "2026-07-16T08:12:00.000000Z" }
}
```

<ResponseField name="id" type="integer">
  The lead's primary key (`lead_id`).
</ResponseField>

<ResponseField name="title" type="string">
  The lead title / opportunity name.
</ResponseField>

<ResponseField name="value" type="string">
  Monetary value of the lead, expressed as a decimal string.
</ResponseField>

<ResponseField name="status" type="object">
  `{ id, title, color }` — the pipeline status currently assigned to this lead.
</ResponseField>

<ResponseField name="active_state" type="string">
  Either `active` or `archived`.
</ResponseField>

<ResponseField name="category" type="object">
  `{ id, name }` — the lead category.
</ResponseField>

<ResponseField name="source" type="string | null">
  How the lead was acquired; `null` when not set.
</ResponseField>

<ResponseField name="contact" type="object">
  `first_name`, `last_name`, `email`, `phone`, `company_name`. There is no separate top-level name, phone, or email — sundry field events still deliver this full nested object.
</ResponseField>

<ResponseField name="converted" type="object">
  `is_converted` (boolean), `client_id`, and `date` — all populated once the lead converts to a client.
</ResponseField>

<ResponseField name="assigned" type="array">
  `[{ id, name }]` — one entry per user currently assigned to this lead.
</ResponseField>

<ResponseField name="tags" type="array of strings">
  Tag titles attached to the lead.
</ResponseField>

<ResponseField name="dates" type="object">
  `created` and `updated`, both ISO 8601 timestamps with microseconds.
</ResponseField>

***

## `lead.created`

Grow CRM fires `lead.created` immediately after a new lead record is saved, **including when a lead is cloned**. `data` is the full lead object shown above.

```json theme={null}
{
  "event": "lead.created",
  "id": 88,
  "created": "2026-07-16T08:00:00+00:00",
  "data": {
    "id": 88,
    "title": "Acme Inc - Website Redesign",
    "value": "0.00",
    "status": { "id": 1, "title": "New", "color": "default" },
    "active_state": "active",
    "category": { "id": 1, "name": "Default" },
    "source": null,
    "contact": {
      "first_name": "Jane",
      "last_name": "Doe",
      "email": null,
      "phone": null,
      "company_name": "Acme Inc"
    },
    "converted": { "is_converted": false, "client_id": null, "date": null },
    "assigned": [],
    "tags": [],
    "dates": { "created": "2026-07-16T08:00:00.000000Z", "updated": "2026-07-16T08:00:00.000000Z" }
  }
}
```

<Tip>
  Leads created through a bulk import do **not** trigger `lead.created`. Use `lead.imported` instead to capture those records.
</Tip>

***

## `lead.updated`

Grow CRM fires `lead.updated` whenever a significant field on the lead changes. Inspect `data.change` to determine what changed; `data.lead` always carries the complete, up-to-date lead object.

| `data.change`  | Fires when                                                         |
| -------------- | ------------------------------------------------------------------ |
| `edited`       | The main lead edit form is saved.                                  |
| `status`       | The lead's pipeline status changes (single or bulk status change). |
| `converted`    | The lead is converted to a client.                                 |
| `value`        | The lead's value is updated.                                       |
| `assigned`     | The lead's assigned user(s) change.                                |
| `active_state` | The lead is archived or restored.                                  |

```json theme={null}
{
  "event": "lead.updated",
  "id": 88,
  "created": "2026-07-16T08:05:00+00:00",
  "data": {
    "change": "converted",
    "lead": {
      "id": 88,
      "converted": { "is_converted": true, "client_id": 45, "date": "2026-07-16" },
      "...": "..."
    }
  }
}
```

***

## `lead.sundry`

Grow CRM fires `lead.sundry` for minor, inline field edits that don't warrant a full `lead.updated` signal. Inspect `data.field` to identify which field changed; `data.lead` carries the full lead object — it is not a partial diff.

| `data.field`    | Fires when                                      |
| --------------- | ----------------------------------------------- |
| `description`   | The lead's description is edited on its own.    |
| `title`         | The lead's title is edited on its own.          |
| `name`          | The lead's contact name is edited on its own.   |
| `tags`          | The lead's tags are changed.                    |
| `category`      | The lead's category is changed.                 |
| `phone`         | The lead's contact phone is edited on its own.  |
| `email`         | The lead's contact email is edited on its own.  |
| `source`        | The lead's source is edited.                    |
| `contacted`     | The lead's "last contacted" date is updated.    |
| `date_added`    | The lead's date-added value is edited.          |
| `organisation`  | The lead's organisation/company name is edited. |
| `custom_fields` | One or more custom field values are updated.    |

```json theme={null}
{
  "event": "lead.sundry",
  "id": 88,
  "created": "2026-07-16T08:07:00+00:00",
  "data": {
    "field": "description",
    "lead": { "id": 88, "title": "Acme Inc - Website Redesign", "...": "..." }
  }
}
```

***

## `lead.activity`

Grow CRM fires `lead.activity` whenever a child record attached to a lead is created, updated, or deleted. Use `data.type` and `data.action` together to identify the exact operation; `data.item` describes the child record.

<Note>
  Leads have **two** separate attachment systems. Files added through the lead's own attachment control and files uploaded through the Files section both fire `type: "attachment"`, but their item shapes differ slightly — see the table below.
</Note>

| `data.type`         | `data.action`                                   | `data.item` shape                                                                                                                                         |
| ------------------- | ----------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `comment`           | `added`, `deleted`                              | `{ id, text, author, created }` — `author` is the commenter's first name only.                                                                            |
| `attachment`        | `added`                                         | `{ id, uniqueid, filename, created }` (lead attachment control).                                                                                          |
| `attachment`        | `deleted`                                       | `{ id }` only — the attachment record is already removed when this fires.                                                                                 |
| `log`               | `added`, `updated`                              | `{ id, text, created }`                                                                                                                                   |
| `log`               | `deleted`                                       | `{ id }` only — the log record is already removed when this fires.                                                                                        |
| `checklist`         | `added`, `updated`, `deleted`, `status_changed` | `{ id, text, status, created }` — `status_changed` fires when an item is ticked or un-ticked; `status` is `pending` or `completed`.                       |
| `checklist_comment` | `added`, `deleted`                              | `{ id, checklist_id, text, author, created }` — kept separate from `comment` so a note on a checklist item is not confused with a top-level lead comment. |

<Tabs>
  <Tab title="attachment added">
    ```json theme={null}
    {
      "event": "lead.activity",
      "id": 88,
      "created": "2026-07-16T08:10:00+00:00",
      "data": {
        "type": "attachment",
        "action": "added",
        "item": {
          "id": 210,
          "uniqueid": "gr84y6837rh",
          "filename": "proposal.pdf",
          "created": "2026-07-16T08:10:00.000000Z"
        }
      }
    }
    ```
  </Tab>

  <Tab title="attachment deleted">
    ```json theme={null}
    {
      "event": "lead.activity",
      "id": 88,
      "created": "2026-07-16T08:11:00+00:00",
      "data": {
        "type": "attachment",
        "action": "deleted",
        "item": { "id": 210 }
      }
    }
    ```
  </Tab>
</Tabs>

***

## `lead.deleted`

Grow CRM fires `lead.deleted` after the lead record is permanently removed. Because the record no longer exists, `data` contains only the lead's `id`.

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

***

## `lead.imported`

Grow CRM fires `lead.imported` once when a bulk lead import job completes. Imported leads do **not** individually fire `lead.created`. See [Imports](/events#imports) for the batch shape, batching rules, and the fields common to every import event.

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

| Field        | Type           |
| ------------ | -------------- |
| `id`         | integer        |
| `title`      | string \| null |
| `first_name` | string \| null |
| `last_name`  | string \| null |
| `email`      | string \| null |
| `created`    | string         |

```json theme={null}
{
  "event": "lead.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": 300, "skipped": 4, "errors": 0 },
    "records": [
      {
        "id": 88,
        "title": "Website redesign",
        "first_name": "Sam",
        "last_name": "Reyes",
        "email": "sam@example.com",
        "created": "2026-07-31T10:00:00.000000Z"
      }
    ]
  }
}
```

<Info>
  `batch_count` tells you the total number of delivery batches for this import run. Wait until you have received all `batch_count` payloads sharing the same `import_ref` before treating the import as fully processed.
</Info>
