Both are signed the same way. Webhooks complement polling — keep
GET /v1/jobs/{jobId} as your recovery path for when your receiver is down.
Per-job callbacks
SendcallbackUrl and callbackSecret together. The secret is yours: 32 to 512
characters, never echoed back, and used only to sign deliveries to you.
status is done, cancelled, failed or qa_failed. Only done carries
artifacts; for the other outcomes artifacts is null. Poll the job for the
details, and never publish media from a qa_failed job.
Webhook subscriptions
A subscription delivers matching events for the whole workspace to one URL.
Subscriptions cover footage edits, media analysis and publishing. For renders
from
POST /v1/video/render and 3D jobs, use a per-job callback or poll.
Each delivery has this shape; read the full job from data.resourceUrl:
GET, PATCH and DELETE
on /v1/webhook-subscriptions/{subscriptionId}. The secret is stored encrypted
and never returned.
Verify signatures
Every delivery carries these headers:
Compute HMAC-SHA256 with your secret over the exact string
<X-Sigmora-Timestamp>.<raw request body> and compare it to
X-Sigmora-Signature in constant time. Verify the raw bytes you received —
parsing and re-serializing the JSON changes them.
Handle deliveries
- Respond fast. Return any
2xxas soon as the signature checks out, then do the work in your own queue. - Expect retries. Network errors,
408,429and5xxresponses are retried with increasing backoff. Other4xxresponses are treated as a permanent rejection. - Deduplicate by event id. Deliveries are at least once, and an event can be
replayed during recovery. Store
X-Sigmora-Event-Idand skip ids you have processed; do not rely on the timestamp being recent. - Keep polling as a fallback. If a job stays in flight longer than expected,
read it with
GET /v1/jobs/{jobId}. - Protect the secret. Never log it, and act on a delivery only after its signature verifies.