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

# Document events

> The document.* webhooks and reacting to status changes

Instead of polling the status, subscribe to events: when a document in your tenant
passes another stage, Doodocs People sends a `POST` to your URL itself. Subscriptions
are managed by the `webhooks:manage` scope — the shared mechanism is covered on the
[Webhooks](/en/api-reference/webhooks) page.

```bash theme={null}
curl -X POST -H "X-API-Key: ddp_YOUR_KEY" -H "Content-Type: application/json" \
  https://app.doodocs.kz/api/developer/v1/webhook_endpoints \
  -d '{
    "url": "https://keruen.example/hooks/doodocs",
    "event_types": ["document.sent", "document.completed", "document.rejected"]
  }'
```

## Event types

The events cover the whole lifecycle — from sending to completion or breakoff.

| Type                        | When                                                               |
| --------------------------- | ------------------------------------------------------------------ |
| `document.sent`             | The document was sent along the route (`DRAFT` launched)           |
| `document.approval_started` | The approval stage began (`ON_APPROVAL`)                           |
| `document.signing_started`  | The signing stage began (`ON_SIGN`)                                |
| `document.completed`        | All steps passed, the document is signed (`COMPLETED`)             |
| `document.rejected`         | The document was rejected by a participant (`REJECTED`)            |
| `document.change_requested` | A participant requested changes (`CHANGE_REQUESTED`)               |
| `document.revoked`          | The document was revoked by the initiator or a manager (`REVOKED`) |
| `document.deleted`          | The document was deleted — a re-read returns `404`                 |

## Thin payload

An event carries the type, the document identifier, and the time — but not the document
itself:

```json theme={null}
{
  "id": "evt_7a1b…",
  "type": "document.completed",
  "occurred_at": "2026-02-10T09:30:00Z",
  "data": { "document_id": "8c2d…" }
}
```

Fetch the current state with a normal request using your key:

```bash theme={null}
curl -H "X-API-Key: ddp_YOUR_KEY" \
  https://app.doodocs.kz/api/developer/v1/documents/8c2d…
```

That way the key's scope and the owner's permissions apply to the data automatically,
and the document contents never leave for an external URL. Delivery is at-least-once:
deduplicate on the event `id` field.

<Note>
  Verify the signature of every delivery: the `Doodocs-Signature: t=<unix>,v1=<hex>`
  header, where `v1` is `HMAC-SHA256(secret, "{t}.{body}")`. How to do this and reject
  stale deliveries is on the [Webhooks](/en/api-reference/webhooks) page.
</Note>

<Warning>
  Document events are delivered for **every** document in the tenant — regardless of which
  documents the endpoint owner may access by permissions. The payload discloses only the
  identifier and the time of the status change, but never the contents. The contents
  themselves stay behind permissions: re-reading an unavailable document returns `404`
  `DOCUMENT_NOT_FOUND` (see [Documents overview](/en/guides/documents/overview)). Do not
  treat receiving an event as confirmation of access to the document.
</Warning>

## Next

<Columns cols={2}>
  <Card title="Webhooks" icon="bell" href="/en/api-reference/webhooks">
    Subscribing, signature verification, and delivery reliability.
  </Card>

  <Card title="Documents overview" icon="file-lines" href="/en/guides/documents/overview">
    Statuses and the structure of the object you re-read.
  </Card>
</Columns>
