- Webhooks & events
- Practitioner
- Developers
Webhook Retry Policy
Also called: Webhook redelivery · Webhook retries · 7-day webhook retry
How Meta re-sends a WhatsApp webhook that does not get an HTTP 200: again and again, less often each time, for up to seven days before dropping it.
Reviewed
What is the webhook retry policy?
The webhook retry policy (Meta's rules for redelivering a webhook) is what happens when your webhook endpoint does not acknowledge an event. Meta's WhatsApp documentation counts any HTTP status other than 200 as a failed delivery — a 500, a 401 from a failing signature check, a redirect — as well as a delivery that fails for another reason, such as a timeout, a TLS error or a refused connection. Meta keeps retrying with decreasing frequency until the request succeeds, for up to seven days; notifications still unacknowledged after that are dropped.
Meta does not publish the exact schedule, only its shape — it resembles exponential backoff, with early retries coming quickly and later ones spread further apart. That is why a five-minute outage usually shows up as a short delay, while a weekend outage becomes a backlog that drains for hours once you recover, mixed in with live traffic. In practice this is at-least-once delivery: Meta warns that retries can produce duplicate notifications, so the same event may arrive more than once.
This is Meta's policy as the sender of webhooks. It differs from a client-side retry policy, which governs how your own code retries outbound calls such as sending a message, and from webhook deduplication, which is how your receiver copes with the repeats this policy creates. The generic Graph API webhooks guide describes a shorter, 36-hour retry period; for WhatsApp, rely on the seven days in Meta's WhatsApp webhook documentation.
Key takeaways
- Meta retries a WhatsApp webhook that gets no HTTP 200 with decreasing frequency until it succeeds, for up to seven days.
- Any status other than 200, a timeout, a TLS error or a refused connection counts as a failed delivery.
- Retries create duplicates, so handlers must be idempotent and keep deduplication keys for at least seven days.
- Notifications unacknowledged after seven days are dropped, and Meta offers no API to fetch historical webhook data.
- After an outage the retried backlog arrives together with live traffic, and not in its original order.
Interactive stop
Watch Meta retry a webhook nobody answers
Retries exhausted
t = 162 h 40 min
- Attempt 1 at 0 ms: failed.
- Attempt 2 at 1 min, after waiting 1 min: failed.
- Attempt 3 at 4 min, after waiting 3 min: failed.
- Attempt 4 at 13 min, after waiting 9 min: failed.
- Attempt 5 at 40 min, after waiting 27 min: failed.
- Attempt 6 at 2 h 1 min, after waiting 1 h 21 min: failed.
- Attempt 7 at 6 h 4 min, after waiting 4 h 3 min: failed.
- Attempt 8 at 18 h 13 min, after waiting 12 h 9 min: failed.
- Attempt 9 at 54 h 40 min, after waiting 36 h 27 min: failed.
- Attempt 10 at 108 h 40 min, after waiting 54 h: failed.
- Attempt 11 at 162 h 40 min, after waiting 54 h: failed.
- Dropped after about 7 days — rebuild from your own recordsafter 11 attempts · t = 162 h 40 min
The delay formula
delayn = min(cap, base × factorn)
All 10 retries are spent (11 attempts in 162 h 40 min), so the client stops: Dropped after about 7 days — rebuild from your own records.
24 clients, same outage · retry n = 9
Without jitter all 24 retry at exactly 54 h: a thundering herd that can knock the server over again.
Gave up after 11 attempts at 162 h 40 min: Dropped after about 7 days — rebuild from your own records.
How does the webhook retry policy work?
Meta POSTs the event
Each notification expects exactly HTTP 200 — the webhook acknowledgement. Your endpoint should verify the signature, put the event on a queue and answer straight away.
Anything else counts as a failure
Error codes, redirects, timeouts, TLS failures and refused connections all mark the delivery as failed, and Meta schedules another attempt.
Retries spread out over time
Attempts come close together at first and further apart later. Meta documents the decreasing frequency, not the intervals, so never build logic on a specific gap.
Recovery arrives as a burst
When your endpoint comes back, retried events land alongside new ones and out of their original order — webhook event ordering is never guaranteed, and a status for a message sent hours ago can arrive after newer ones.
Seven days is the limit
An event still unacknowledged after seven days is dropped, and Meta offers no API for historical webhook data. State you need after that must come from your own records or from API reads, such as fetching template status.
The webhook retry policy: key facts and limits
- Triggers a retry
- Any response other than HTTP 200, or no response
- Pattern
- Decreasing frequency until success; intervals not published
- Retry window
- Up to 7 days, then the notification is dropped
- Duplicates
- Expected — handlers must be idempotent
- Ordering
- Not guaranteed, especially after an outage
- Dedup key lifetime
- At least 7 days (8 gives a margin)
Example: A weekend without a certificate
A Kochi travel agency's webhook server loses its TLS certificate at 11 pm on a Friday after a failed renewal. Customers keep replying to booking confirmations all weekend, and every delivery fails the TLS handshake. At 9 am on Monday the certificate is fixed, and within minutes the endpoint receives 58 hours of retried messages and statuses at several times its normal rate, many of them more than once. Because the handler acknowledges first, queues the work and skips any event it has already processed, the inbox fills in the right threads instead of falling over — and agents answer the oldest first, many with templates, because those customers' 24-hour windows have closed.
Common mistakes with the webhook retry policy
Using non-200 responses as flow control
Returning 503 during a spike to make Meta back off hands your scheduling to a timetable you cannot see, and every refused event comes back later on top of live traffic. Accept, queue and pace the work yourself; refuse only when you genuinely could not store the event.
Handlers that do the work first
Waiting on a CRM, a database or an LLM before answering makes requests slow; a timed-out delivery is retried while the first copy is still being processed. Acknowledge first, work later.
Dedup windows shorter than the retry window
A seen-ID cache that expires after an hour lets day-old retries through as new events. Keep keys for at least the seven-day retry window.
Declaring victory the moment the endpoint is up
The first hour after an outage carries the backlog plus live traffic. Scale workers and watch queue depth, or the backlog causes a second outage.
Counting on retries for long outages
After seven days events are gone. Rebuild what you can through the API — template status, phone number quality — and accept that inbound message content cannot be fetched later.
The webhook retry policy in code
app.post("/webhooks/whatsapp", async (req, res) => {if (!validSignature(req)) return res.sendStatus(401); // non-200: Meta will retry itawait queue.add("wa-event", req.body); // durable queue, no other I/O hereres.sendStatus(200); // exactly 200 — not 202 or 204});// Worker: skip redeliveries and measure how late events arriveworker.process("wa-event", async (job) => {for (const entry of job.data.entry ?? []) {for (const change of entry.changes ?? []) {for (const s of change.value?.statuses ?? []) {// Keep seen-keys longer than Meta's 7-day retry windowconst first = await redis.set(`seen:${s.id}:${s.status}`, "1", "EX", 8 * 24 * 3600, "NX");if (!first) { metrics.increment("webhook.duplicate"); continue; }metrics.histogram("webhook.lag_seconds", Date.now() / 1000 - Number(s.timestamp));await applyStatus(s);}}}});
Acknowledge with a plain 200, deduplicate for longer than the retry window, and watch lag to see retries happening.
Why does the webhook retry policy matter?
Retries are a safety net, not a queue you can lean on. Knowing the policy tells you how long you can be down before events are lost for good, why duplicates appear after every incident, and why a slow handler is as harmful as a dead one — each timeout schedules another copy. It also shapes your recovery plan: after an outage you must absorb the retried backlog and live traffic at the same time.
Best practices for the webhook retry policy
- Alert on a falling event rate as well as on errors — a silent endpoint is still failing deliveries.
- Track webhook lag (received time minus the event timestamp) to see retries as they happen.
- Rehearse an outage in staging: block the endpoint for an hour, then measure how long the backlog takes to drain.
- Keep the acknowledgement path free of external dependencies so it is the last thing to fail.
Webhook Retry Policy FAQs
How long does Meta retry a failed WhatsApp webhook?+
Does Meta retry when my endpoint returns a 4xx?+
Do retries go to every app subscribed to the WABA?+
Will retried events arrive in their original order?+
Can I ask Meta to resend a webhook?+
Talk to InfiQ
From definition to your first message
InfiQ is an official Meta Business Partner. Start a 7-day free trial — no card needed — and see this running on your own number.