Webhook-Id header) and progresses through the following statuses:
| Status | Description |
|---|---|
pending | The delivery has been created and is waiting to be dispatched. |
in_progress | The delivery is actively being attempted. |
succeeded | Your endpoint returned a 2xx response. |
failed | All retry attempts have been exhausted without a successful response. |
Retry schedule
We use at-least-once delivery, which means we guarantee that every event reaches your endpoint at least once — but it may arrive more than once in some cases (see Handling duplicates). If your endpoint doesn’t return a2xx response, we’ll retry the delivery with exponential backoff and jitter, up to 10 attempts:
| Attempt | Average delay | Maximum delay |
|---|---|---|
| 1 | Immediate | — |
| 2 | ~0.5s | 1s |
| 3 | ~3s | 6s |
| 4 | ~18s | 36s |
| 5 | ~1m 48s | 3m 36s |
| 6 | ~10m 48s | 21m 36s |
| 7 | ~1h 4m | 2h 9m |
| 8 | ~6h 28m | 12h 57m |
| 9 | ~12h | 24h |
| 10 | ~12h | 24h |
failed and no further retries are made.
Disabling a webhook
If a webhook is disabled while a delivery is in progress, any future retry attempts will be cancelled and the delivery will be marked asfailed. However, if a
delivery attempt is already in flight (i.e. we’re actively waiting for your endpoint to
respond), that attempt will complete normally before the cancellation takes effect.
Delivery attempt errors
Each failed delivery attempt records the type of error encountered:| Error type | Description |
|---|---|
http | Your endpoint returned a non-2xx HTTP status code. |
timeout | The connection or read timed out. |
dns | DNS resolution for your endpoint failed. |
tls | TLS certificate verification failed. |
connection | The connection was refused, reset, or a network error occurred. |
validation | The webhook URL failed validation (e.g. it resolves to a private IP address). |
webhook_disabled | The webhook was disabled while this delivery was still in progress. |
unknown | An unhandled exception occurred during delivery. |
Handling duplicates
Because delivery is at-least-once, your webhook endpoints may occasionally receive the same event more than once. We recommend making your event processing idempotent to handle this gracefully. A straightforward approach is to use theWebhook-Id header to deduplicate:
- When you receive a delivery, check whether you’ve already processed a delivery with that
Webhook-Id. - If you have, return
200immediately without reprocessing. - If you haven’t, process the event and record the ID.
Ordering
The order of your received webhook events may not match the order they were created. Network latency and retries can cause events to arrive out of sequence. If you need to determine the correct order, use thecreated_at timestamp on each event rather than relying on delivery order.