Sheaf
SheafDocsAPIWebhooks

Webhooks

Optional. Signed deliveries of ledger rows to your server, with retries. Off until a Manager adds an endpoint.

Polling is the whole integration. Webhooks are for when you would rather be told.

Set one up

A Manager adds an endpoint in the app under Settings, in Webhooks: a URL, and the events to receive, or none selected for all of them. The signing secret, whsec_…, is shown once. Test sends one signed delivery on the spot and shows what your server answered.

Nothing from before the endpoint existed is ever replayed.

A delivery

{
  "id": "whd-8Hq2mZ1xPq0a",
  "type": "workflow.auto_filed",
  "at": "2026-09-17T21:22:48.377Z",
  "application": "euw8ydHxTW",
  "data": {
    "actor": { "kind": "system", "name": "Workflow", "authenticatedAs": "LOS integration (API)" },
    "target": { "type": "run", "id": "run-20260917-212242-ef09" },
    "detail": { "workflow": "standard-intake v1", "approved": 1, "leftUnassigned": 0, "failed": 0 }
  }
}

It is one ledger row. type is the ledger's own action name.

Events worth subscribing to

EventMeaning
application.createdA case was started.
file.receivedA file landed on a case.
run.ingestedA run's results landed.
workflow.auto_filedA workflow finished filing what it recommended.
document.approved, document.rejectedA filing decision, by a person or a workflow.
run.failedA run failed, or the analyzer went silent for 3 minutes, and the case was put back.
run.cancelledA person stopped the run and the case was put back.

The full list is the WebhookEvent enum in the contract.

Verify the signature

Deliveries follow the Standard Webhooks specification. Three headers arrive with each one:

HeaderValue
webhook-idThe delivery id. The same on every retry, so use it to drop duplicates.
webhook-timestampSeconds since the epoch.
webhook-signaturev1, followed by the base64 HMAC-SHA256 of id.timestamp.body, keyed with your secret.

The key is the base64 part of the secret, after whsec_. Any Standard Webhooks library does this for you. Reject a delivery whose signature does not match or whose timestamp is more than a few minutes old.

Retries

Answer 2xx within 15 seconds. Otherwise the delivery is retried 14 times over about 13 hours, from 30 seconds apart up to 2 hours apart, and then marked failed. Answering 410 turns the endpoint off; add it again to resume. The endpoint's row in Settings shows its latest delivery.

This page as markdown · llms.txt · API contract