Webhook-Id header) and progresses through the following statuses:
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:
The total delivery window spans approximately 43 hours on average and up to 3.6 days in the worst case. After 10 failed attempts, the delivery is marked as
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: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.