Overview
kurnl sends HTTP POST requests to yourwebhook_url after significant events. The webhook_url lives on your provider integration settings (tenant-config); the signing secret is the Shared webhook secret from the dashboard Checkout page.
All events share a common envelope structure with event-specific fields merged in at the top level.
Event reference
What is not emitted: there is no
subscription.suspended event, and
subscription.activated does not fire on dashboard-driven activation,
the kurnl-billed Stripe flow, or the home-drop / confirm-install path —
today those emit nothing. Also mind the payload variants:
subscription.activated from a provider switch carries only
subscription_id, started_at, via — don’t key on location_hash
unconditionally.Payload structure
event, provider_document_id, and timestamp. Event-specific fields are merged in alongside them.
Verifying signatures
When you have awebhook_secret configured, kurnl signs every request body with HMAC-SHA256 and sends the signature in the X-Webhook-Signature header as sha256=<hex_digest>.
Always verify this signature before processing any event.
Delivery behaviour
- kurnl first attempts delivery up to 3 times inline, with exponential back-off (2s, then up to 30s between retries) and a 15 second timeout per attempt
- If all inline attempts fail, the event moves to a dead-letter queue: a scheduler (every 10 minutes) redelivers it with growing back-off until 5 total attempts have been made, then the event is dropped and kurnl operations is alerted
- Every delivery carries an
X-Webhook-Eventheader with the event name; DLQ redeliveries additionally carryX-Webhook-Retry: true— use it for dedup awareness - Network errors and 5xx responses are retried; 4xx responses are not retried (a 4xx during DLQ redelivery ends retrying immediately)
- Return any
2xxstatus to acknowledge — kurnl does not inspect the response body
Idempotency
kurnl may deliver the same event more than once after transient failures. Usejob_id or subscription_id as an idempotency key to deduplicate in your handler:
Testing webhooks locally
During development you can use a tunnelling tool to expose your local server to kurnl:Debugging delivery failures
The sandbox has its own webhook event feed — but it is a different pipeline with different event names than the production events on this page. See Sandbox for how to configure, list, and replay sandbox webhook events. For production issues, remember the delivery behaviour above: failed events are redelivered from the dead-letter queue withX-Webhook-Retry: true, and events
that exhaust all attempts alert kurnl operations.