For the complete documentation index, see llms.txt. This page is also available as Markdown.
Connections

Build an event-driven pipeline

Be told when work finishes instead of asking.

Goal. Submit documents and have Document AI call you when each one finishes, replacing the polling loop entirely.

Extraction takes around 90 seconds per page. Polling for that is workable but wasteful; at volume it is a lot of requests that mostly say "not yet". Webhooks invert it — you register an endpoint once and receive a signed POST per completion.

Before you start

  • An API key, exported as $DOCAI_API_KEY.

  • A publicly reachable HTTPS endpoint. It must be reachable from the platform, so localhost will not do during development — use a tunnel.

  • Owner or Admin access to the portal, to configure the endpoint and read the signing key.

Step 1 — Register your endpoint

Webhook endpoints are configured in the portal, not through the API.

  1. Sign in as Admin or Owner.

  2. Settings → Edit Account Information.

  3. Enter your URL in Webhook URL and save.

  4. In the same panel, Reveal the Webhook Signing Key (whk_…) and store it as WEBHOOK_PRIVATE_KEY.

Endpoints are account-wide — every completion goes to every configured URL. There is no per-event subscription, and extraction and classification requests cannot override the destination. Generation is the exception: its request accepts a per-job webhookUrl.

Step 2 — Verify signatures before trusting anything

Your endpoint is a public URL that receives document data. The x-signature header is the only thing separating a genuine delivery from anyone who finds the address.

Step 3 — Make the handler idempotent

Deliveries retry, so the same event will sometimes arrive twice. Every payload carries an eventId:

Design for at-least-once delivery. Deduplicating on eventId is far simpler than trying to make the platform deliver exactly once.

Step 4 — Acknowledge quickly, process afterwards

Respond 200 as soon as you have verified and stored the event. Do the real work on a queue.

Two reasons. A slow endpoint eventually times out and the delivery is treated as failed even though you received it. And 4xx responses are terminal — the platform stops retrying that destination rather than backing off. Returning 4xx because your database was briefly unavailable permanently discards the event.

Your response
Platform behaviour

2xx

Delivered

4xx

Permanent failure — retries stop

5xx or timeout

Retried with backoff

Retries are 3 attempts with exponential backoff starting at 30 seconds, capped at 8 minutes. Deliveries stuck in processing can be retried after 24 hours. See Webhooks & Integrations.

Step 5 — Submit work

Nothing changes about submission. Use the asynchronous endpoints and ignore the returned ID if you like — the webhook will bring it back.

Step 6 — Handle grouped completions

When one file yields several documents, you get one delivery per child, not one for the set:

Do not assume they arrive in order. Count distinct extractionGroupIndex values against extractionGroupTotal to decide when a group is complete, then fetch the whole thing with GET /document-extractions/group/{id} — see Extract many documents at once.

Batch jobs also emit a summary-level delivery with webhookType: "batch_extraction", which is separate from the per-document events.

Step 7 — Monitor

The Webhook Monitor in the portal lists every delivery with its status and attempt count, and lets you retrigger one by hand after fixing a downstream problem. Use it when something did not arrive — it will tell you whether the platform tried.

When it goes wrong

Symptom
Cause
Fix

No deliveries at all

No URL configured, or not publicly reachable

Check Settings → Edit Account Information; test from outside your network

Every signature mismatches

Verifying a re-serialised body, or the wrong key

Verify raw bytes; re-reveal the signing key

Deliveries stop after one failure

You returned 4xx

Return 5xx for transient problems so retries continue

Same document processed twice

No idempotency

Deduplicate on eventId

webhookStatus: Failed, 0 attempts

No endpoint configured

Configure one

Last updated