Skip to main content

Webhooks

Webhooks deliver compliance results asynchronously when the request uses responseMode: "async". The webhook URL and a per-job signing secret are supplied with the original request and returned in the 202 response — no upfront endpoint registration is required. For a full submit → receive → verify walkthrough, see the Async + Webhook Execution guide.

Event types

Delivery guarantees

  • At-least-once delivery. Use the top-level eventId to deduplicate on your side.
  • HMAC signature in the X-ZebraTruth-Signature header: sha256=<hex(hmac(secret, body))>.
  • Replay protection. X-ZebraTruth-Timestamp is an ISO 8601 timestamp; reject deliveries with drift greater than 5 minutes.
  • Per-attempt timeout. Each HTTP attempt has a 10-second timeout.
  • Retry policy. Up to 4 attempts (initial + 3 retries) with delays 1 s, 5 s, 25 s. Total worst-case window: ~31 s.
  • Dead-letter recording. After exhaustion, the delivery is recorded with status dead in the internal delivery log.

Webhook payload

callbackId is the opaque tag you supplied on the original request — included so you can correlate the webhook with whatever record triggered it.

Headers on every delivery

Verifying a webhook

Always verify against the raw bytes of the body — re-stringifying parsed JSON breaks the HMAC even if the payload is semantically identical. The secret is the webhookSecret returned in the 202 response when the job was submitted. Store it keyed by jobId. Each async job gets a fresh secret; secrets are not shared across jobs.

Failed delivery and recovery

If your webhook handler returns a non-2xx status (or the request times out), we retry with the schedule above. After all attempts fail, the result is still available via the polling endpoint:
Polling is the recovery / verification fallback. Use it to backfill missed webhooks or to confirm that a webhook payload matches what’s actually in our system. You can also list dead-letter deliveries for the tenant:

When the orchestrator fails

A pipeline error fires compliance.failed:
Common error codes: