Statuses
| Status | Meaning |
|---|---|
pending | Queued. The next scheduled attempt is in next_attempt_at. |
delivering | An attempt is in progress. |
succeeded | An attempt returned 2xx. Terminal. |
failed | All attempts exhausted without a 2xx. Terminal until you replay. |
Retry schedule
A failed delivery is retried up to seven times after the initial attempt, for eight total attempts. The Workflow-backed retry schedule is:| Attempt | Delay before this attempt |
|---|---|
| 1 | 0 (immediate) |
| 2 | 5 seconds |
| 3 | 5 minutes |
| 4 | 30 minutes |
| 5 | 2 hours |
| 6 | 5 hours |
| 7 | 10 hours |
| 8 | 10 hours |
2xx response is marked failed and stops retrying. The automatic retry window is about 32 hours and 35 minutes after the first attempt.
A delivery is treated as failed if:
- The HTTP request fails to connect or times out.
- The endpoint returns a non-
2xxstatus. - The endpoint returns no response within the request timeout.
2xx first and process asynchronously if your handler is heavy.
Inspecting deliveries
status, endpoint_id, or event_id. The response is the standard cursor-paginated list:
Payload retention
Webhook payloads are JWE-encrypted, but they can still contain personal data once your endpoint decrypts them. Kayle keeps the encrypted body only while it is needed for automatic delivery and manual recovery.succeededdeliveries havepayload_scrubbed_atset and the encrypted payload removed immediately after the first2xxresponse.faileddeliveries keep the encrypted payload for the endpoint’s undelivered payload retention window after the final automatic attempt.- Expired, missing-key, and JWE-creation failures cannot be retried because there is no retained encrypted payload to send.
undelivered_payload_retention_hours controls the manual retry/replay window after final delivery failure. Supported values are 0, 24, 72, and 168; new endpoints default to 72.
Manual retry
Replay a single failed delivery:pending and runs through the automatic retry schedule again. The signature is regenerated, so don’t expect the captured headers from the previous attempts to match.
Manual retry is only available while the delivery still has a retained encrypted payload. Once payload_expires_at passes, or once payload_scrubbed_at is set, the API returns 409 WEBHOOK_PAYLOAD_EXPIRED.
Replaying an event
If multiple deliveries (one per subscribed endpoint) failed because of a downstream outage, replay the whole event rather than each delivery:409 WEBHOOK_PAYLOAD_EXPIRED.
Listing events
/v1/events is an alias for the same resource, kept for older integrations. Use the /v1/webhooks/events path in new code.