# WhatsApp webhooks

Bird pushes WhatsApp activity to your endpoint as it happens, so you do not have to poll for it. Subscribe from the [**Webhooks**](https://bird.com/dashboard/w/webhooks) page or with [`POST /v1/webhooks`](/docs/api/reference/create-webhook). The [Webhooks guide](/docs/guides/webhooks) covers endpoints, signature verification, and retries.

## Events you can subscribe to

Each event links to its payload.

| Event                                                                                               | Fires when                                           |
| --------------------------------------------------------------------------------------------------- | ---------------------------------------------------- |
| [`whatsapp.accepted`](/docs/guides/whatsapp/webhooks/lifecycle#delivery-events)                     | Bird accepts an outbound send request                |
| [`whatsapp.sent`](/docs/guides/whatsapp/webhooks/lifecycle#delivery-events)                         | Bird hands the message to the WhatsApp network       |
| [`whatsapp.delivered`](/docs/guides/whatsapp/webhooks/lifecycle#delivery-events)                    | WhatsApp confirms delivery to the recipient's device |
| [`whatsapp.read`](/docs/guides/whatsapp/webhooks/lifecycle#delivery-events)                         | The recipient opens the message                      |
| [`whatsapp.failed`](/docs/guides/whatsapp/webhooks/lifecycle#delivery-events)                       | The message fails to deliver                         |
| [`whatsapp.rejected`](/docs/guides/whatsapp/webhooks/lifecycle#delivery-events)                     | Bird refuses the message before sending it           |
| [`whatsapp.received`](/docs/guides/whatsapp/webhooks/lifecycle#incoming-messages)                   | A contact sends you a message                        |
| [`whatsapp.reacted`](/docs/guides/whatsapp/webhooks/reactions)                                      | A contact adds, changes, or removes a reaction       |
| [`whatsapp_suppression.created`](/docs/guides/whatsapp/webhooks/suppressions)                       | A suppression opens on your workspace                |
| [`whatsapp.group.join_request_created`](/docs/guides/whatsapp/webhooks/groups#join-request-created) | Someone asks to join a group                         |
| [`whatsapp.group.join_request_revoked`](/docs/guides/whatsapp/webhooks/groups#join-request-revoked) | Someone cancels their request to join a group        |

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.

## The event envelope

Every WhatsApp event uses the standard [webhook envelope](/docs/guides/webhooks): a `type`, a `timestamp`, and a type-specific `data` object.

```json
{
  "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"
}
```

## Fields every message event carries

Each WhatsApp webhook payload for a message carries `whatsapp_id`, `workspace_id`, `direction`, `from`, `to`, `tags`, and `metadata`. The reaction, suppression, and group events are not about a message, so each has its own shape, given on its page.

- **Addresses**: `from` and `to` can include an E.164 `phone_number`, a Meta [business-scoped user ID](/docs/guides/whatsapp/business-scoped-user-ids) in `bsuid`, or both. A message received from a WhatsApp user also carries the profile they publish, in `username` and `display_name`.
- **`tags` and `metadata`** are `null` when the send carried none.
- **`in_reply_to_message_id`** appears on every outbound event of a message sent in reply, from `whatsapp.accepted` through `whatsapp.read`, `whatsapp.failed`, or `whatsapp.rejected`, naming the message it answers.

Event payloads carry no cost. Read the message back with [`GET /v1/whatsapp/messages/{message_id}`](/docs/api/reference/get-whatsapp-message) to see what it cost.

## Next steps

- [Message lifecycle webhooks](/docs/guides/whatsapp/webhooks/lifecycle): delivery and incoming-message payloads
- [Lifecycle events](/docs/guides/whatsapp/events/lifecycle): read the same timeline back through the API
- [Webhooks guide](/docs/guides/webhooks): endpoints, signatures, retries, and the full event catalog

## Related resources

- [Connecting WhatsApp to Bird: from buying a number to a live channel](/learn/whatsapp/connecting-whatsapp-to-bird) (video)
- [What is the 24-hour customer service window on WhatsApp?](/explained/whatsapp/what-is-the-24-hour-customer-service-window) (answer)
- [WhatsApp message builder](/tools/whatsapp-message-builder) (tool)
- [WhatsApp](/whatsapp-api) (product)

[Get an implementation brief](/learn/workspace?topic=whatsapp)
