Configure a subscription
Webhooks are configured per project in the dashboard (Project → Webhooks): a URL, the events to subscribe to, and anactive flag. There is no API to register webhooks programmatically yet
(roadmap) — use the dashboard.
Delivered events:
| Event | Fired when |
|---|---|
render.succeeded | a render finished and the PDF is available |
render.failed | a render terminated with an error |
Delivery contract
CraftkitPOSTs a JSON body to your URL with these headers:
| Header | Value |
|---|---|
x-craftkit-event | the event name (render.succeeded / render.failed) |
x-craftkit-signature | HMAC-SHA256 of the raw body, hex-encoded, keyed by the subscription secret |
x-craftkit-timestamp | unix seconds when the delivery was signed |
x-craftkit-delivery-id | unique delivery id (use for your own idempotency) |
user-agent | Craftkit-Webhook/1.0 |
Verify the signature
Compute the HMAC over the raw request body and compare againstx-craftkit-signature (raw hex,
no sha256= prefix). Reject on mismatch.
Retries
Failed deliveries (non-2xx, timeout, or error) retry up to 6 attempts; after that the delivery is markedabandoned. Respond 2xx quickly (within ~15s) and do heavy work asynchronously.
De-duplicate on x-craftkit-delivery-id since a delivery may arrive more than once.
downloadUrl in the payload follows the same durability rules as elsewhere — a permanent public
URL, or null if no public bucket is configured. See
Render lifecycle.