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

# Estimates

> Payload reference for estimate.created, estimate.updated, estimate.sundry, estimate.activity and estimate.deleted webhooks.

# Estimates

> New to webhooks? Start with **[Getting started](/getting-started)** (envelope, delivery, retries)
> and **[Verification](/verification)** (confirming a request came from Grow CRM). Those conventions
> apply to every event below and are not repeated here.

Estimates expose all five keys: `estimate.created`, `estimate.updated`, `estimate.deleted`,
`estimate.sundry`, `estimate.activity`.

## The estimate object

Every key except `.deleted` carries this shape, either flat (`.created`) or nested under `estimate`
(`.updated`/`.sundry`):

```json theme={null}
{
  "id": 118,
  "status": "draft",
  "client": { "id": 12, "name": "Acme Inc" },
  "project_id": null,
  "category": { "id": 4, "name": "Default" },
  "dates": { "date": "2026-07-16", "expiry_date": "2026-08-15", "created": "2026-07-16T08:00:00.000000Z" },
  "notes": null,
  "tax_type": "summary",
  "totals": {
    "subtotal": "250.00",
    "discount_type": "amount",
    "discount_amount": "25.00",
    "tax_total_amount": "22.50",
    "final_amount": "247.50"
  },
  "line_items": [
    { "id": 1, "description": "Item A", "unit": "hours", "quantity": "2.00", "rate": "100.00",
      "total": "200.00", "type": "plain", "tax_status": "taxable",
      "discount": { "type": "none", "value": "0.00", "amount": "0.00" } }
  ],
  "taxes": [ { "name": "VAT", "rate": "10.00" } ],
  "tags": ["priority"]
}
```

| Field        | Type             | Notes                                                                                                                                                        |
| ------------ | ---------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `id`         | integer          | `bill_estimateid`.                                                                                                                                           |
| `status`     | string           | `draft`, `new`, `accepted`, `revised`, `declined`, or `expired` — the raw status value, no title/color object on this transformer (unlike invoices/tickets). |
| `client`     | object           | `{ id, name }`.                                                                                                                                              |
| `project_id` | integer\|null    |                                                                                                                                                              |
| `category`   | object           | `{ id, name }`.                                                                                                                                              |
| `dates`      | object           | `date`, `expiry_date` are raw dates (date only); `created` is ISO 8601 with microseconds (`Estimate` recasts `bill_created` via `CREATED_AT`).               |
| `notes`      | string\|null     |                                                                                                                                                              |
| `tax_type`   | string           | `summary`, `inline`, or `none`.                                                                                                                              |
| `totals`     | object           | `subtotal`, `discount_type` (`amount`, `percentage`, or `none`), `discount_amount`, `tax_total_amount`, `final_amount` — decimals as strings.                |
| `line_items` | array            | See **[the line item shape](#the-line-item-shape)** below.                                                                                                   |
| `taxes`      | array            | `[{ name, rate }]`.                                                                                                                                          |
| `tags`       | array of strings |                                                                                                                                                              |

### The line item shape

Shared with invoices:

| Field         | Type         | Notes                                                                   |
| ------------- | ------------ | ----------------------------------------------------------------------- |
| `id`          | integer      | `lineitem_id`.                                                          |
| `description` | string       |                                                                         |
| `unit`        | string\|null |                                                                         |
| `quantity`    | string       | Decimal as string.                                                      |
| `rate`        | string       | Decimal as string.                                                      |
| `total`       | string       | Decimal as string.                                                      |
| `type`        | string       | `plain`, `time`, or `dimensions`.                                       |
| `tax_status`  | string       | `taxable` or `exempt`.                                                  |
| `discount`    | object       | `{ type, value, amount }` — `type` is `none`, `fixed`, or `percentage`. |

## `estimate.created`

Fires when an estimate is created, **including via clone**. `data` is the full estimate object
above.

```json theme={null}
{
  "event": "estimate.created",
  "id": 118,
  "created": "2026-07-16T08:00:00+00:00",
  "data": { "id": 118, "status": "draft", "client": { "id": 12, "name": "Acme Inc" }, "...": "..." }
}
```

## `estimate.updated`

Fires on a significant change. `data.change` tells you which; `data.estimate` is the full object.

| `change`     | Fires when                                                                                                                          |
| ------------ | ----------------------------------------------------------------------------------------------------------------------------------- |
| `edited`     | The main estimate edit form is saved.                                                                                               |
| `status`     | The estimate's status changes.                                                                                                      |
| `accepted`   | The client accepts the estimate.                                                                                                    |
| `declined`   | The client declines the estimate.                                                                                                   |
| `published`  | The estimate is published.                                                                                                          |
| `sent`       | The estimate email is (re)sent.                                                                                                     |
| `converted`  | The estimate is converted to an invoice. `data.estimate` still describes the estimate — check invoice webhooks for the new invoice. |
| `tax_type`   | The tax type (summary/inline/none) is changed.                                                                                      |
| `automation` | The estimate's automation settings are updated.                                                                                     |
| `project`    | The estimate is attached to or detached from a project.                                                                             |

```json theme={null}
{
  "event": "estimate.updated",
  "id": 118,
  "created": "2026-07-16T08:05:00+00:00",
  "data": {
    "change": "accepted",
    "estimate": { "id": 118, "status": "accepted", "...": "..." }
  }
}
```

## `estimate.sundry`

Fires on a minor, cosmetic field edit. `data.field` names it; `data.estimate` is the full object
(same shape as `.updated`, just a lower-significance discriminator).

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

```json theme={null}
{
  "event": "estimate.sundry",
  "id": 118,
  "created": "2026-07-16T08:07:00+00:00",
  "data": {
    "field": "category",
    "estimate": { "id": 118, "category": { "id": 4, "name": "Default" }, "...": "..." }
  }
}
```

## `estimate.activity`

Fires when a child record on the estimate changes. Estimates only produce `type: "attachment"` —
estimates are not part of core's comment system.

| `type`       | `action`  | Item shape                                                                                                                 |
| ------------ | --------- | -------------------------------------------------------------------------------------------------------------------------- |
| `attachment` | `added`   | `{ id, uniqueid, filename }` — no `created` on this shape (unlike the `App\Models\Attachment`-backed resources).           |
| `attachment` | `deleted` | `{ id, uniqueid, filename }` — the file record is looked up **before** it's removed, so the full shape is still available. |

```json theme={null}
{
  "event": "estimate.activity",
  "id": 118,
  "created": "2026-07-16T08:10:00+00:00",
  "data": {
    "type": "attachment",
    "action": "added",
    "item": { "id": 44, "uniqueid": "dg746287", "filename": "scope.pdf" }
  }
}
```

## `estimate.deleted`

Fires after the estimate is deleted. `data` is just the id — the record no longer exists to
describe.

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