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

# Expense approval events

> The expense.approval.status_changed event, covering the expense lifecycle from creation to accounting sync

## `expense.approval.status_changed`

Fired as an expense moves through its lifecycle: created, submitted for approval, approved or declined, and finally synced to your accounting system. It covers everything **except** the money movement, which is [`expense.transaction.status_changed`](/webhooks/events/expense-transaction).

`status` is where the expense now sits. `reason` is what moved it there.

### Statuses

| `status` | Meaning |
| - | - |
| `DRAFTED` | With the employee, not yet submitted |
| `PENDING` | Submitted, waiting for approval |
| `APPROVED` | Approved |
| `DECLINED` | An approver rejected it |
| `OUT_OF_POLICY` | Flagged as breaching policy |
| `SYNCED` | Pushed to your accounting system |
| `SKIPPED` | Deliberately not synced |

### Reasons

| `reason` | Meaning |
| - | - |
| `CREATED` | The expense was created |
| `SUBMITTED` | Sent for approval |
| `APPROVED`, `DECLINED` | An approver actioned it |
| `MARKED_OUT_OF_POLICY` | Flagged as out of policy |
| `MARKED_IN_POLICY` | The out-of-policy flag was removed. `status` is `PENDING` if the expense could be resubmitted, otherwise `DRAFTED` |
| `SYNCED`, `SKIPPED` | Accounting sync completed or was skipped |

<Warning>
  Always read `status` together with `reason`. The same status can have two causes:

  * `DRAFTED` arrives on creation (`CREATED`), or when an out-of-policy flag is removed from an expense that can't be resubmitted (`MARKED_IN_POLICY`).
  * `PENDING` arrives on a normal submission (`SUBMITTED`), or when clearing an out-of-policy flag resubmits the expense automatically (`MARKED_IN_POLICY`).
</Warning>

### Fields

| Field | Type | Description |
| - | - | - |
| `id` | string | The expense id. Use it with [Expense Details](/apis/expense-details) |
| `status` | string | See the table above |
| `reason` | string | See the table above |
| `expenseType` | string \| null | `UPI` or `PREPAID_CARD` |
| `amount` | string (decimal) | The expense amount |
| `currency` | string | ISO 4217 code |
| `actor` | object \| null | `{ id, name }`, who performed the action. `null` for system-driven changes. `name` can be `null` |
| `createdAt` | string (ISO 8601) \| null | When the expense was created |
| `metadata` | object \| null | Carries `remark` on declines and policy changes |

### Example: out-of-policy flag removed

```json theme={null}
{
  "id": "exp_8fk21ma",
  "status": "DRAFTED",
  "reason": "MARKED_IN_POLICY",
  "expenseType": "PREPAID_CARD",
  "amount": "2499.00",
  "currency": "INR",
  "actor": { "id": "usr_2mfk1", "name": "A. Sharma" },
  "createdAt": "2026-08-10T09:14:21.000Z",
  "metadata": { "remark": "Receipt provided, within policy" }
}
```

<Note>
  This event carries no merchant or card details. Subscribe to `expense.transaction.status_changed` for those, or fetch the expense by `id`.
</Note>


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.