Platform

How are failed webhooks retried, and do events arrive in order?

Bird retries failed webhooks on a fixed schedule without guaranteeing that events arrive in the order they occurred.

Your receiver can store an event even when the sender never receives its acknowledgment. A retry can therefore repeat work your application already accepted.

Retries delay some events. Newer events can arrive before those retries finish. Store event identifiers and occurrence times so those deliveries cannot overwrite newer work.

What counts as a failed delivery?

Bird treats a delivery as failed when it receives a non-success response or the request times out.

Return HTTP 2xx after storing the event to stop retries for that delivery. A redirect, client error or server error remains eligible for retry.

For example, 400 records a rejected request but does not tell Bird to discard it. Use an error response when signature verification or durable storage fails, so the delivery can be recovered.

Store the event before acknowledging it. Returning success first can lose the event if the later storage operation fails.

Keep slow processing in a background worker so your receiver can respond promptly. The receiver's job is to verify and preserve the event before that work begins.

What is the retry schedule?

Bird uses seven retry delays after the initial attempt, for eight attempts in total.

RetryDelay after the previous attemptApproximate elapsed time before timing adjustments
15 seconds5 seconds
25 minutes5 minutes 5 seconds
330 minutes35 minutes 5 seconds
42 hours2 hours 35 minutes 5 seconds
55 hours7 hours 35 minutes 5 seconds
610 hours17 hours 35 minutes 5 seconds
710 hours27 hours 35 minutes 5 seconds

The schedule gives you roughly 27.5 hours to repair a receiver before automatic attempts finish.

Bird randomly adjusts each wait by up to 20 percent in either direction to spread retries after an outage. A five-minute delay therefore ranges from four to six minutes before other adjustments.

A throttling response or timeout can change the next wait. Bird also considers Retry-After, a response header requesting a delay before another attempt. Treat the schedule as a recovery window rather than an exact deadline.

Each retry retains the event's webhook-id, so your receiver can recognize duplicates.

What happens after the last retry?

Automatic retries stop for that delivery. You can request replay of the deliveries that failed.

You request redelivery with createWebhookReplay, or through the endpoint's dashboard page. Replay reads the delivery-attempt log and selects the events that failed there. An event Bird never attempted, such as one that arrived while the endpoint was paused, has no attempt to select, so replay cannot recover it.

The response is 202, meaning replay is queued for background execution. It does not include a count or task identifier. Use listWebhookAttempts to inspect subsequent attempts.

Each redelivery takes one attempt rather than the schedule above. Bird records the attempt and finishes the job whether or not your receiver accepted it. Replaying into a receiver that is still broken therefore costs one request per event instead of eight. Repair the receiver, then replay again. Those failures leave endpoint health alone. An accepted redelivery clears degradation.

Replay skips deliveries already acknowledged successfully. A redelivery keeps its original webhook-id, so your duplicate handling still applies.

Set since and until as date-time strings to bound the recovery window. Both boundaries are inclusive. Both are read against the time of the delivery attempt, not the time the event occurred. Omitting since starts the window 24 hours before the request, so an older outage needs an explicit start time. Omitting until ends the window at the time of the request.

Attempts are retained for three days, which is as far back as replay reaches. An earlier since widens the window without recovering anything older. One replay also covers at most the oldest 10,000 events in the window, so a long outage needs several narrower windows.

An organization can request 20 replays per UTC day. A further request receives 429 with WebhookReplayQuotaExceeded, so combine recovery into a window instead of requesting replay per event.

What if my endpoint keeps failing?

Bird marks a failing endpoint degraded. It pauses delivery after about five days of uninterrupted failures.

You can read its status as active, degraded or paused. A degraded endpoint continues receiving deliveries and retries. A successful delivery clears degradation and resets the continuous-failure clock.

A paused endpoint stops receiving events and does not resume automatically. Re-enable it with updateWebhook, setting status to active. Then replay the window, which recovers the deliveries that failed before the pause. Re-enable first: a replay requested while the endpoint is still paused returns 202 and redelivers nothing. The writable status values are active and paused.

Changing the receiving url or completing a successful test delivery also clears degradation. The replacement URL must be publicly reachable HTTPS, so private addresses cannot repair reachability. URLs longer than 2048 characters fail validation, so shorten a generated URL before submitting it.

Editing the endpoint's description or event subscriptions does not demonstrate that it can receive requests. Those changes leave degradation in place, as does a failed test delivery.

Bird emails the organization's owners when an endpoint becomes degraded. It sends no further degradation email until the endpoint recovers. Repeated failures therefore do not produce an email for every attempt. A failure after recovery starts another period of degradation.

Is there a dead-letter queue?

Bird does not provide a separate queue of failed events for you to read. Inspect delivery attempts and request replay instead.

Recovery taskMechanism
Inspect failuresDelivery attempts record each HTTP request's outcome and latency, newest first.
Stop repeated delivery to a broken receiverPausing takes the endpoint out of delivery.
Recover failed deliveriesReplay requests redelivery within a time window.

Fix the receiver, re-enable it if needed and replay the affected window. There is no separate queue to drain afterward.

Do events arrive in order?

Events can arrive in a different order from the order in which they occurred.

An email.delivered event can arrive before the same message's email.accepted event. Compare event times in timestamp before applying a change that would overwrite newer state.

Track each part of an SMS charge separately. For example, the delivery charge and a carrier fee are separate cost components.

The cost object is null until a component has been priced. Its component values are decimal strings or null. The amount field is a decimal string summing the components present in that payload.

Merge each component using its newest event timestamp. Replacing the whole object can erase a component supplied by another event, or restore an older charge.

A null component means it was not priced in that payload. It does not mean a charge of zero. SMS events describes that merge in context, and webhooks covers delivery semantics.

In short

  1. Retries use a fixed schedule.

    Eight attempts span roughly 27.5 hours before timing adjustments. Random changes to the waits spread retries so receivers do not face a synchronized burst.

  2. Acknowledge after durable storage.

    A 2xx response stops retries and excludes that delivery from missed-event replay. An error response leaves it eligible for retry.

  3. A paused endpoint needs manual recovery.

    Re-enable it, then replay the deliveries that failed before the pause. Events that arrived while it was paused were never attempted, so replay cannot reach them.

  4. Use event time to apply updates.

    Delivery is unordered. Compare occurrence timestamps and merge partial SMS costs per component.

Build on the same network.

A test API key is yours immediately. Production unlocks when you add a payment method and verify a sender.

Your next idea.
Ready to connect.