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

# Expenses

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

# Expenses

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

Expenses expose all five keys: `expense.created`, `expense.updated`, `expense.deleted`,
`expense.sundry`, `expense.activity`.

## The expense object

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

```json theme={null}
{
  "id": 214,
  "description": "AWS hosting — July",
  "date": "2026-07-16",
  "amount": "120.00",
  "billable": "billable",
  "billing_status": "not_invoiced",
  "category": { "id": 3, "name": "Hosting" },
  "client": { "id": 12, "name": "Acme Inc" },
  "project_id": 305,
  "dates": { "date": "2026-07-16", "created": "2026-07-16T08:00:00.000000Z" },
  "tags": []
}
```

| Field            | Type             | Notes                                                                                                                 |
| ---------------- | ---------------- | --------------------------------------------------------------------------------------------------------------------- |
| `id`             | integer          | `expense_id`.                                                                                                         |
| `description`    | string\|null     |                                                                                                                       |
| `date`           | string           | Date only — duplicated in `dates.date` for convenience.                                                               |
| `amount`         | string           | Decimal as string.                                                                                                    |
| `billable`       | string           | `billable` or `not_billable`.                                                                                         |
| `billing_status` | string           | `invoiced` or `not_invoiced`.                                                                                         |
| `category`       | object           | `{ id, name }`.                                                                                                       |
| `client`         | object           | `{ id, name }`.                                                                                                       |
| `project_id`     | integer\|null    |                                                                                                                       |
| `dates`          | object           | `date` is a raw date; `created` is ISO 8601 with microseconds (`Expense` recasts `expense_created` via `CREATED_AT`). |
| `tags`           | array of strings |                                                                                                                       |

## `expense.created`

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

```json theme={null}
{
  "event": "expense.created",
  "id": 214,
  "created": "2026-07-16T08:00:00+00:00",
  "data": {
    "id": 214,
    "description": "AWS hosting — July",
    "date": "2026-07-16",
    "amount": "120.00",
    "billable": "billable",
    "billing_status": "not_invoiced",
    "category": { "id": 3, "name": "Hosting" },
    "client": { "id": 12, "name": "Acme Inc" },
    "project_id": 305,
    "dates": { "date": "2026-07-16", "created": "2026-07-16T08:00:00.000000Z" },
    "tags": []
  }
}
```

## `expense.updated`

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

| `change`    | Fires when                                               |
| ----------- | -------------------------------------------------------- |
| `edited`    | The main expense edit form is saved.                     |
| `recurring` | The expense's recurring settings are updated or stopped. |
| `project`   | The expense is attached to a project.                    |

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

## `expense.sundry`

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

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

```json theme={null}
{
  "event": "expense.sundry",
  "id": 214,
  "created": "2026-07-16T08:07:00+00:00",
  "data": {
    "field": "category",
    "expense": { "id": 214, "category": { "id": 3, "name": "Hosting" }, "...": "..." }
  }
}
```

## `expense.activity`

Fires when a child record on the expense changes. Expenses only produce `type: "attachment"`.

| `type`       | `action`  | Item shape                                                                                                                                |
| ------------ | --------- | ----------------------------------------------------------------------------------------------------------------------------------------- |
| `attachment` | `added`   | `{ id, uniqueid, filename, created }`                                                                                                     |
| `attachment` | `deleted` | `{ id, uniqueid, filename, created }` — the attachment record is looked up **before** it's removed, so the full shape is still available. |

```json theme={null}
{
  "event": "expense.activity",
  "id": 214,
  "created": "2026-07-16T08:10:00+00:00",
  "data": {
    "type": "attachment",
    "action": "added",
    "item": { "id": 88, "uniqueid": "ryy388jf", "filename": "receipt.jpg", "created": "2026-07-16T08:10:00.000000Z" }
  }
}
```

## `expense.deleted`

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

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