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

# Invoice events

> The eight invoice.* events that report an invoice being created, submitted, approved, declined, synced to your accounting system or paid

Invoice events fire as an invoice moves through its lifecycle in Pazy. There are eight event types. The outcome is in the event name, so the payload has no `status` field.

| Event type | Fired when |
| - | - |
| `invoice.created` | An invoice is created, by any channel: web form, upload, email, WhatsApp, Slack, API or conversion from a purchase order |
| `invoice.submitted` | An invoice is submitted for approval, including a resubmission after a decline |
| `invoice.approved` | An invoice receives its final approval |
| `invoice.declined` | An approver declines the invoice. It goes back to draft for changes |
| `invoice.sync_requested` | Someone starts an accounting sync, such as Sync now or a bulk sync |
| `invoice.synced` | The accounting sync completes. Only for organizations with a native accounting integration |
| `invoice.sync_skipped` | Someone skips the accounting sync |
| `invoice.paid` | The invoice is fully settled |

All eight share one payload shape. Subscribe with `invoice.*` to receive them all, or subscribe to only the types you need. For example, an ERP bridge can subscribe to `invoice.sync_requested` alone.

## Things to know

* **Intermediate approval levels don't fire events.** `invoice.approved` fires once, on the final approval.
* **`invoice.sync_requested` fires whenever someone starts a sync.** It says a sync was attempted, not that it finished.
* **`invoice.synced` fires only for organizations with a native accounting integration.** It reports that the sync completed.
* **A declined invoice returns to draft.** When it is submitted again, you receive `invoice.submitted` again.
* **Not covered:** archiving, deleting or restoring an invoice, and sync failures don't raise events.

## Fields

| Field | Type | Description |
| - | - | - |
| `id` | string | The invoice id. Use it with [Invoice Details](/apis/invoice-details) |
| `invoiceNumber` | string \| null | The vendor's invoice number. `null` until it is extracted, for uploaded documents |
| `amount` | string (decimal) \| null | The invoice total. `null` until it is extracted |
| `currency` | string \| null | ISO 4217 code |
| `vendor` | object \| null | `{ id, name }`. `null` until a vendor is matched |
| `actor` | object \| null | `{ id, name }`, the user who caused the change. `null` for system, ERP and scheduled-job changes |
| `createdAt` | string (ISO 8601) \| null | When the invoice was created |
| `metadata` | object \| null | Event-specific extras. See below |

<Note>
  For an uploaded document, `invoice.created` fires before extraction finishes. `invoiceNumber`, `amount` and `vendor` can be `null` on that event. They are filled in on later events, or fetch the invoice by `id`.
</Note>

The payload carries no line items and no accounting system identifiers. Fetch the invoice by `id` for the full record.

### `metadata`

| Event type | `metadata` |
| - | - |
| `invoice.declined` | `{ "comment": "..." }`, when the approver gave a comment |
| `invoice.paid` | `{ "source": "..." }`. See below |

For other event types, `metadata` is `null` unless a later release adds keys. Ignore keys you don't recognize.

#### `source` on `invoice.paid`

| Value | Meaning |
| - | - |
| `PLATFORM` | Paid through Pazy |
| `MARK_AS_PAID` | Marked as paid in Pazy, with the money moved outside it |
| `ERP` | Recorded from your accounting system |
| `SETTLEMENT` | Settled by an advance or a vendor credit |

## Example: `invoice.approved`

```json theme={null}
{
  "id": "018f1a2b-3c4d-7e8f-9a0b-1c2d3e4f5a80",
  "type": "invoice.approved",
  "version": "1",
  "createdAt": "2026-08-10T09:14:21.000Z",
  "data": {
    "id": "iX3k9Qm2Lp7vTn4Rz8Wcq",
    "invoiceNumber": "INV-4471",
    "amount": "12500.00",
    "currency": "INR",
    "vendor": { "id": "vK7d2Hs9Fq3mPx6B", "name": "Acme Supplies Pvt Ltd" },
    "actor": { "id": "uR5w8Jc4Yh2nGa9L", "name": "A. Sharma" },
    "createdAt": "2026-08-07T11:02:45.000Z",
    "metadata": null
  }
}
```

## Example: `invoice.paid`

```json theme={null}
{
  "id": "018f1a2b-3c4d-7e8f-9a0b-1c2d3e4f5a81",
  "type": "invoice.paid",
  "version": "1",
  "createdAt": "2026-08-14T06:30:09.000Z",
  "data": {
    "id": "iX3k9Qm2Lp7vTn4Rz8Wcq",
    "invoiceNumber": "INV-4471",
    "amount": "12500.00",
    "currency": "INR",
    "vendor": { "id": "vK7d2Hs9Fq3mPx6B", "name": "Acme Supplies Pvt Ltd" },
    "actor": null,
    "createdAt": "2026-08-07T11:02:45.000Z",
    "metadata": { "source": "PLATFORM" }
  }
}
```

## `invoice.paid` and `payment.invoice.completed`

The two events answer different questions.

| Event | Reports | Fires |
| - | - | - |
| [`payment.invoice.completed`](/webhooks/events/payment) | Money movement | Once per payment, including each partial payment |
| `invoice.paid` | The invoice's state | Exactly once, when the invoice becomes fully settled |

Use `payment.invoice.*` when you need each payment, its amount or its reference. Use `invoice.paid` when you only need to know the invoice is settled. An invoice settled by an advance or a vendor credit raises `invoice.paid` with `source` set to `SETTLEMENT`, and has no payment event.

## Fetch the full invoice

Use `data.id` with [Invoice Details](/apis/invoice-details) (`GET /v1.0/invoice/:id`) to get line items and the rest of the record. Treat the API as the source of truth if you suspect you missed an event.


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