Webhooks
Get a signed job.completed event instead of polling — endpoint registration, HMAC-SHA256 signature verification, retries, and auto-disable rules.
Register an endpoint
Webhooks push a metadata-only job.completed event when a batch job reaches a terminal status. Registration requires the opt-in webhooks:manage scope:
curl -sS -X POST https://api.transmute.403fin.io/v1/webhooks \
-H "Authorization: Bearer $TRANSMUTE_KEY" \
-H "Content-Type: application/json" \
-d '{"url": "https://example.com/hooks/transmute"}'
# → {"id": "...", "secret": "whsec_..."} secret shown ONCE
GET /v1/webhooks lists endpoints; DELETE /v1/webhooks/{id} removes one. The whsec_ secret is displayed once at creation, like API keys.
Verify every delivery
Each delivery is signed:
X-Transmute-Signature: t=<unix seconds>,v1=<hex HMAC-SHA256>
X-Transmute-Event: job.completed
X-Transmute-Delivery: <id> # stable across retries — dedupe on it
Verification:
- Compute
HMAC-SHA256(key = the full secret string including the "whsec_" prefix, message = t + "." + raw request body bytes), lowercase hex. - Compare against
v1constant-time. - Reject timestamps more than 5 minutes from your clock (replay guard).
Verify over the raw received bytes — parse the JSON only after the signature checks out. The SDKs ship a verifier (Go, TypeScript, Python).
Retries and auto-disable
| Behavior | Value |
|---|---|
| Success criterion | Any 2xx from your endpoint |
| Retry ladder | 0s, 1m, 5m, 30m, 2h — 5 attempts max |
| Dedupe | X-Transmute-Delivery is stable across retries |
| Auto-disable | 10 consecutively exhausted deliveries disable the endpoint |
| Re-enable | Delete and re-create the endpoint |
Event contents
The body carries job metadata — id, status, item counts, timing — never message content. Fetch results via GET /v1/jobs/{id} with your API key; the webhook is a doorbell, not a data channel.