Skip to main content
Every time your bot sends a message, Meta fires status events back to your webhook tracking that message’s journey. These arrive in value.statuses, not value.messages.

The four statuses in order

You send a message

sent       — Meta accepted it and queued it for delivery

delivered  — reached the customer's phone (grey double tick ✓✓)

read       — customer opened it (blue double tick ✓✓)

If something goes wrong:
failed     — could not be delivered

What Meta sends to your webhook

{
  "object": "whatsapp_business_account",
  "entry": [{ "changes": [{ "value": {
    "statuses": [{
      "id": "wamid.HBgM...",
      "status": "delivered",
      "timestamp": "1717000000",
      "recipient_id": "919959623255"
    }]
  }}]}]
}
For failed, an errors array is included:
{
  "status": "failed",
  "errors": [{ "code": 131026, "title": "Message Undeliverable" }]
}

How to parse statuses

if (changes?.statuses) {
  const s  = changes.statuses[0];
  const to = s.recipient_id;

  if (s.status === 'sent')      console.log(`[STATUS] sent      → ${to}`);
  if (s.status === 'delivered') console.log(`[STATUS] delivered → ${to}`);
  if (s.status === 'read')      console.log(`[STATUS] read      → ${to}`);
  if (s.status === 'failed')    console.log(`[STATUS] FAILED    → ${to} | ${s.errors?.[0]?.code}`);
  return;
}
This block must come before the messages check, since a payload has either statuses or messages — never both.

Frequently asked

Meta sends a "status": "delivered" event to your webhook. Parse changes.statuses[0] and check the status field.
Meta sends "status": "read" when the customer opens the message. Note: customers can turn off read receipts — if they do, you never receive the read event.
Read statuses[0].errors[0].code. Common codes: 131026 = number has no WhatsApp; 131047 = 24-hour window closed; 131049 = marketing message blocked. See Error handling & codes.

Gotchas & common mistakes

  • Statuses arrive at the same /webhook endpoint as messages — your code must check changes.statuses vs changes.messages and handle each separately.
  • read is not guaranteed — customers can disable read receipts. Design your logic to work without it.
  • Order is not guaranteed — you may receive delivered before sent in rare cases. Don’t rely on sequence.