Documentation
Sign inGet started

WhatsApp events

Every WhatsApp message emits events as it moves through its lifecycle. Each event is a stamped fact about the message: when Bird accepted it, when it reached WhatsApp, when it was delivered, when the recipient read it, or that it failed. Events are how you follow what happened to a message after the send returns 202.

The event envelope

Events reach you in two shapes that carry the same lifecycle facts. A webhook delivery is the standard envelope described in the Webhooks guide: a type, a timestamp, and a type-specific data object.
Ejemplo de código
{
  "data": {
    "direction": "outbound",
    "from": { "phone_number": "+13124495569" },
    "metadata": { "session_id": "sess_4821" },
    "tags": [{ "name": "flow", "value": "login-otp" }],
    "to": { "phone_number": "+14155550100" },
    "whatsapp_id": "wam_01ky7qbvswf3fvyaw3az90391c",
    "workspace_id": "ws_01ky7m235keycbnwyajabe1a6b"
  },
  "timestamp": "2026-07-23T14:51:39.913Z",
  "type": "whatsapp.delivered"
}
Every whatsapp.* payload's data carries the identity base: whatsapp_id, workspace_id, the message direction (outbound for messages you send), the from and to addresses (each a phone_number in E.164 and/or a Meta business-scoped user ID bsuid), and the tags and metadata from the send request (both null when the message carried none).
The events API returns the same lifecycle as leaner records: each event is an id, a type, and the occurred_at timestamp, since the message identity is already fixed by the request URL.

Lifecycle events

A message emits events in order as it progresses. Not every message emits every type: a failed send stops at whatsapp.failed, and whatsapp.read only appears if the recipient opens the message.
EventMeaning
whatsapp.acceptedBird accepted the send request. This is what the 202 reported.
whatsapp.sentHanded to the WhatsApp network.
whatsapp.deliveredDelivery confirmed to the recipient's device.
whatsapp.readThe recipient opened the message.
One thing about whatsapp.read: it does not change the message status. A delivered message stays delivered, and the read is recorded as a read_at timestamp on the message alongside the event.
The event type list is open: new types may be added over time, so treat an unrecognized value as a future event rather than an error.

Failure events

whatsapp.failed is terminal: the message will not be delivered, and no further events follow. It is the one event type that carries an error object with the failure detail: a Bird-stable code (for example undeliverable or insufficient_balance), a human-readable description, an optional raw meta_error_code from the WhatsApp Cloud API, and the failure's occurred_at. The same object appears on the API record and in the webhook payload, and is absent on every other event type.

Reading events from the API

GET /v1/whatsapp/messages/{message_id}/events returns a message's events in chronological order. The timeline is bounded and returned in full, so the list is not paginated. Reading events needs an API key with the whatsapp_messages scope:
Ejemplo de código
curl https://us1.platform.bird.com/v1/whatsapp/messages/wam_.../events \
  -H "Authorization: Bearer $BIRD_API_KEY"
A message that was accepted, sent, delivered, and read returns four events:
Ejemplo de código
{
  "data": [
    {
      "id": "ev_01ky7q6a1fejfbvs0myn41hj41",
      "occurred_at": "2026-07-23T14:48:34.71Z",
      "type": "whatsapp.accepted"
    },
    {
      "id": "ev_01ky7q6a2denvtd6jg1vqwmg13",
      "occurred_at": "2026-07-23T14:48:35.671Z",
      "type": "whatsapp.sent"
    },
    {
      "id": "ev_01ky7q6a2zff9r2qm74mmg1g6z",
      "occurred_at": "2026-07-23T14:48:36.642Z",
      "type": "whatsapp.delivered"
    },
    {
      "id": "ev_01ky7q6c21frssf0vj8h50qysw",
      "occurred_at": "2026-07-23T14:48:38.65Z",
      "type": "whatsapp.read"
    }
  ]
}
To keep only one type, pass the type query parameter (for example ?type=whatsapp.failed); omit it for the full timeline.
The same timeline is what the WhatsApp log page renders when you open a message.
The WhatsApp message detail sheet in the Bird dashboard, opened for a delivered bird_order_confirmation message: the Events tab showing the per-message lifecycle timeline of Accepted, Sent, Delivered, and Read, each with its timestamp, over the dimmed message list

Webhooks

The same five lifecycle events are delivered to your endpoints as webhooks, so you can react to a message the moment it moves instead of polling the events API. Subscribe an endpoint to any whatsapp.* type from the Webhooks page in the dashboard or through the webhooks API; each delivery uses the event envelope with the identity base and, on whatsapp.failed, the error object. The Webhooks guide covers creating endpoints, verifying signatures, and retries.

Next steps