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

# Webhooks

> Subscribe to events and react in real time.

Webhooks notify your server when something happens — a journal is posted, a statement is ready —
so you don't have to poll.

## The event shape

Every event shares a common envelope with a typed `data` payload:

```json theme={null}
{
  "id": "evt_1a2b3c",
  "type": "journal.posted",
  "createdAt": "2026-11-08T09:24:11Z",
  "data": {
    "id": "jrnl_7x2a9",
    "businessId": "biz_9f2",
    "status": "posted",
    "balanced": true
  }
}
```

## Events

| Event | Sent when |
| - | - |
| `journal.posted` | A journal is successfully posted to a business's ledger. |
| `statement.ready` | A requested statement has finished computing. |

## Receiving events

1. Expose an HTTPS endpoint and register its URL in the dashboard.
2. Return a `2xx` within **5 seconds** to acknowledge receipt. Do slow work asynchronously.
3. **Verify the signature** on the `X-3Rings-Signature` header before trusting a payload (see below).
4. **Deduplicate** on the event `id` — an event may be delivered more than once.

> [!WARNING]
>
> Always verify the signature. Without it, anyone who learns your endpoint URL could post fake
> events. Never act on an unverified payload.

## Retries

If your endpoint fails or times out, we retry with exponential backoff for up to 24 hours. Because
retries and at-least-once delivery mean duplicates are possible, make your handler idempotent on the
event `id`.


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