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

# Proposal Webhooks — Payload Reference | Grow CRM

> Full payload reference for Grow CRM proposal webhooks — created, updated, sundry, and deleted — covering signing, publication, and status events.

Grow CRM fires four distinct event keys for proposal records: `proposal.created`, `proposal.updated`, `proposal.deleted`, and `proposal.sundry`. Use these events to trigger contract workflows on acceptance, notify sales teams when a proposal is signed, and keep external document management systems in sync. There is **no `proposal.activity`** event — proposals have no comments, attachments, or logs.

<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 proposal object

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

```json theme={null}
{
  "id": 77,
  "title": "Website Redesign Proposal",
  "status": "draft",
  "client": { "id": 12, "name": "Acme Inc" },
  "lead_id": null,
  "category": { "id": 1, "name": "Default" },
  "project_id": null,
  "dates": {
    "start": "2026-07-16",
    "end": "2026-08-16",
    "created": "2026-07-16T08:00:00.000000Z",
    "published": null
  },
  "signed": { "date": null, "first_name": null, "last_name": null },
  "tags": []
}
```

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

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

<ResponseField name="status" type="string">
  One of `draft`, `new`, `accepted`, `declined`, `revised`, or `expired` — the raw status value. There is no `{ title, color }` wrapper object around this value.
</ResponseField>

<ResponseField name="client" type="object">
  `{ id, name }` — both fields are `null` when the proposal belongs to a lead rather than a client (see `lead_id`).
</ResponseField>

<ResponseField name="lead_id" type="integer | null">
  Set when the proposal belongs to a lead rather than a client. A proposal belongs to either a client or a lead — never both simultaneously.
</ResponseField>

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

<ResponseField name="project_id" type="integer | null">
  Set when the proposal is attached to a project; otherwise `null`.
</ResponseField>

<ResponseField name="dates" type="object">
  `start`, `end`, and `published` are date-only strings (or `null`); `created` is an ISO 8601 timestamp with microseconds.
</ResponseField>

<ResponseField name="signed" type="object">
  `date`, `first_name`, `last_name` — all `null` until the proposal is signed.
</ResponseField>

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

***

## `proposal.created`

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

```json theme={null}
{
  "event": "proposal.created",
  "id": 77,
  "created": "2026-07-16T08:00:00+00:00",
  "data": {
    "id": 77,
    "title": "Website Redesign Proposal",
    "status": "draft",
    "...": "..."
  }
}
```

***

## `proposal.updated`

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

<Note>
  There is no `edited` change value for proposals. Grow CRM has no `ProposalUpdated` event for general edits because proposals are modified through the builder interface, not a standard form.
</Note>

| `data.change` | Fires when                                              |
| ------------- | ------------------------------------------------------- |
| `status`      | The proposal's status changes.                          |
| `accepted`    | The client accepts the proposal.                        |
| `declined`    | The client declines the proposal.                       |
| `published`   | The proposal is published.                              |
| `sent`        | The proposal email is sent or resent.                   |
| `signed`      | The proposal is signed.                                 |
| `automation`  | The proposal's automation settings are updated.         |
| `project`     | The proposal is attached to or detached from a project. |

```json theme={null}
{
  "event": "proposal.updated",
  "id": 77,
  "created": "2026-07-16T08:05:00+00:00",
  "data": {
    "change": "signed",
    "proposal": {
      "id": 77,
      "signed": { "date": "2026-07-16", "first_name": "Jane", "last_name": "Doe" },
      "...": "..."
    }
  }
}
```

***

## `proposal.sundry`

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

| `data.field` | Fires when                          |
| ------------ | ----------------------------------- |
| `category`   | The proposal's category is changed. |

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

***

## `proposal.deleted`

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

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