Browse guides

Webhook Reliability

Three rules for reliable WhatsApp webhook handling — respond 200 immediately, deduplicate deliveries by message ID, and don't assume messages arrive in order.

On this page

Meta's webhook delivery system is designed for reliability — which means it retries failed deliveries. Your server must follow three rules to handle this correctly.

Rule 1 — Send 200 immediately, process after#

Meta expects a 200 response within a few seconds. If it doesn't get one, it retries the same event — which means your bot processes the same message twice.

js
app.post('/webhook', (req, res) => {
  res.sendStatus(200);          // ← FIRST — before any logic

  const message = changes.messages[0];
  // process here, after 200 is sent
});
ResponseWhat Meta does
200 immediatelyNever retries — done
No response / timeoutRetries for up to 24 hours
500 errorRetries

Rule 2 — Deduplicate by message ID#

Because Meta retries, the same message can arrive twice with the same id. Store seen IDs and skip duplicates:

js
const seen = new Set(); // use a database in production

if (seen.has(message.id)) return; // already processed
seen.add(message.id);

// now process safely

Rule 3 — Don't trust order#

If a customer sends "Hi", "How are you?", "Hello?" quickly, Meta does not guarantee they arrive in order. If order matters, sort by the message timestamp:

js
const timestamp = parseInt(message.timestamp); // unix timestamp

Frequently asked#

Why is my bot replying twice to the same message?

Your server is not responding 200 fast enough, or it's doing slow work before sending 200. Meta retries and your handler runs twice. Fix: send 200 first, then process.

Do I need to worry about duplicate messages on a test setup?

Not much — duplicates are rare in testing. But in production with real traffic, always deduplicate by message.id.

Gotchas & common mistakes#

Still stuck? Open a support ticket and our team will help.