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

# Webhooks

> Receive parse results on your backend, with signed, retried delivery.

When a report completes (sync or async), Swippee `POST`s the result to every
active webhook endpoint on your organization.

## Signature

Each delivery is signed so you can verify it came from Swippee:

```
X-Swippee-Signature: t=<unix>,v1=<hex>
```

`v1` is an HMAC-SHA256 of `<t>.<raw body>` using your webhook signing secret.
Reject deliveries where the timestamp is too old or the signature doesn't
match.

## Payload

Every delivery shares one envelope. The event is split into a grouping
(`event_type`) and a specific code (`event_code`); `event` is the canonical
dotted name. Switch on `event_code`.

```json theme={null}
{
  "event": "report.ready",
  "event_type": "REPORT",
  "event_code": "READY",
  "report_id": "rep_abc123",
  "environment": "live",
  "created_at": "2026-05-27T10:23:41Z",
  "result": { }
}
```

| `event`         | When                                                                        |
| --------------- | --------------------------------------------------------------------------- |
| `report.ready`  | A report finished parsing. `result` is the full `StatementReport`.          |
| `report.failed` | A report could not be produced. `error` is `{ error_code, error_message }`. |

Webhooks are hints — always reconcile against `GET /v1/reports/{id}` as the
source of truth, since deliveries can arrive out of order or be retried.

## Retries

Failed deliveries retry with exponential backoff for up to **24 hours**. Return
a `2xx` quickly and process asynchronously to avoid timeouts.
