Skip to main content
Webhooks let Folio call your server the moment a document reaches a terminal state, eliminating polling. This guide covers registering an endpoint, verifying the signature, handling retries, and replaying events.

Register a webhook endpoint

1

Create the endpoint

Send a POST /v1/webhook-endpoints with the URL you want Folio to call. Optionally restrict which event types are delivered; omitting events subscribes to all types.
Response (201 Created):
The secret is returned only once in the creation response. Store it securely (e.g. as an environment variable) — you cannot retrieve it again.
2

Verify the signature on every delivery

Folio signs each delivery with an X-Signature header. The header value has the format:
The HMAC-SHA256 is computed over "<timestamp>." + raw_body (the timestamp as a decimal string, a literal ., then the raw request bytes), keyed with your endpoint secret. Always verify this signature before acting on the payload. Use a constant-time comparison to prevent timing attacks.
Compute the HMAC over the raw bytes of the body before any JSON parsing. Parsing and re-serialising can alter whitespace and break the signature.
3

Handle the event payload

Every delivery is a POST with Content-Type: application/json. The payload contains the event object:
Respond with any 2xx status as quickly as possible. Offload heavy work to a background queue — Folio considers a delivery successful on any 2xx.

Event types

Retries and backoff

If your server returns a non-2xx response (or times out), Folio retries the delivery with exponential backoff. Each delivery attempt is tracked with a WebhookDeliverySummary object containing status (pending | succeeded | failed | dead), attempts, last_status_code, and next_attempt_at. A delivery is marked dead after all retry attempts are exhausted.

List your endpoints

The list response omits the secret — only the secret_prefix is shown.

Fetch an event

Use the event ID from any delivery payload to retrieve the full event object, including all delivery attempts:

Replay an event

Re-deliver an event to all active endpoints — useful for testing or recovering from a missed delivery:
The replay returns the updated event object with a fresh delivery entry.