Skip to main content
Outbound webhooks deliver signed lifecycle notifications to your HTTPS endpoint: mandate approvals and revocations, authorization outcomes, and the rest of the journal. A notification is a trigger, never the proof. It tells you something happened; you confirm what happened by fetching current state and the evidence bundle.

Register an endpoint

Up to five non-deleted endpoints per organization. The signing secret is 32 random bytes, presented exactly once as att_wh_<base64url>. Store it server-side. After a secret rotation, retries and new deliveries are signed with the new secret; update your receiver promptly, and note that failed verifications count toward the endpoint’s failure budget.

The delivery

The envelope carries the event id, its type, the occurrence time, and the cross-references (mandate_id, authorization_id when the event belongs to one, state when it names one, version). Events that name a state carry it; authorization.committed and its terminal siblings do not. Journal payload contents never cross. Respond 2xx; anything else is a failure and the delivery retries.

Verify every delivery

  1. Parse t and v1 from Attesso-Signature. t is a canonical base-10 integer in seconds; v1 is exactly 64 hex characters.
  2. Check t is within 300 seconds of your clock (replay window).
  3. Decode the presented secret: strip the att_wh_ prefix, base64url-decode the remainder to its 32 raw bytes, and recompute HMAC-SHA256 over the string t + "." + body with those raw bytes. Compare in constant time against v1.
Verify the exact raw body bytes. A re-serialization changes the bytes and breaks the signature. Runnable verifiers with shared vectors:

Retries and disabling

Failures retry with exponential backoff starting at 30 seconds (plus or minus 20 percent, about nine attempts over roughly 21 hours). After the window the delivery fails terminally and the endpoint’s exhausted-delivery counter grows. An endpoint that fails 20 attempts in a row or exhausts 10 deliveries in a row is disabled automatically; reactivate it (counters reset) once it is healthy again. Deliveries may arrive more than once: deduplicate on the event id. A disabled endpoint’s pending deliveries are frozen and resume on reactivation; a deleted endpoint keeps its history with those deliveries recorded and never retried.

Then fetch state

The notification is not the proof. After verifying the signature, fetch the current mandate state and, when you need a durable artifact, the signed evidence bundle (GET /v1/mandates/{mandate_id}/evidence); confirm the event carries the version you acted on. Delivery stops if the worker is stopped; state and evidence are the source of truth either way.