Jobs (crawls, batches, videos, routine runs) post their events to the URL you pass in webhook. Each delivery is signed with a secret that belongs to that URL. Jobs, streams and webhooks shows the payload and how to verify it; this page covers the secret and the history.

Get the secret

bash
curl -s https://beta-api.b3os.org/v1/webhooks/secret \ -H "Authorization: Bearer $B3OS_API_KEY" \ -H "Content-Type: application/json" \ -d '{"url": "https://example.com/hooks/b3os"}'

The first call for a URL creates its secret (whsec_...); later calls return the same one until you rotate it. URLs are compared after lowercasing the scheme and host and dropping a default port, so HTTPS://Example.com:443/hooks/b3os and https://example.com/hooks/b3os share a secret. The call needs platform:write.

Test the receiver

bash
curl -s https://beta-api.b3os.org/v1/webhooks/test \ -H "Authorization: Bearer $B3OS_API_KEY" \ -H "Content-Type: application/json" \ -d '{"url": "https://example.com/hooks/b3os"}'

B3OS sends one signed webhook.test event now and returns the delivery with the outcome of that single attempt: status, last_status_code and last_error. Test deliveries are not retried.

Delivery history

GET /v1/webhooks/deliveries lists the last 7 days of deliveries, newest first, with their attempts, last status code, last error and next attempt. Filter with url, job_id or status (pending, retrying, succeeded, failed). Each delivery's id is the event ID in its body.

Failed deliveries are retried with backoff for 24 hours. Answer with a 2xx status quickly and do the work afterwards; deliveries come from the node through the egress guard, so receivers on private or loopback addresses never get them.

Rotate the secret

bash
curl -s https://beta-api.b3os.org/v1/webhooks/secret/rotate \ -H "Authorization: Bearer $B3OS_API_KEY" \ -H "Content-Type: application/json" \ -d '{"url": "https://example.com/hooks/b3os", "grace_s": 86400}'

For grace_s seconds (a day by default, up to 7 days) every delivery carries two v1 signatures, one per secret, and previous_valid_until says when the old one stops. Deploy the new secret to your receiver within that window; a receiver that accepts any matching v1 keeps working throughout.

Other webhooks

  • Firecrawl-compatible jobs post Firecrawl's payloads with X-Firecrawl-Signature: sha256=<hex>, signed with this same per-URL secret. See Firecrawl compatibility.
  • Webhooks into B3OS, which start routine runs, are a different thing: see triggers.
Ask a question... ⌘I