# Receiving WhatsApp reactions

Subscribe to reaction changes to learn when a contact adds an emoji to one of your messages, changes it, or takes it back. Reactions annotate an existing message and arrive through `whatsapp.reacted`.

## Prerequisites

Set up a [webhook endpoint](/docs/guides/webhooks) for your workspace. To retrieve the current reactions or their history, use an API key with WhatsApp read permission.

## 1. Subscribe to reaction changes

Add `whatsapp.reacted` to your webhook subscription. A subscription to `whatsapp.received` does not include reactions. Follow the [webhooks guide](/docs/guides/webhooks) for signature verification, delivery retries, and endpoint configuration.

Reactions do not create a new message in the message list or open a customer service window. If you need to reply, check the [service window rules](/docs/guides/whatsapp/sending-whatsapp) before sending a free-form message.

## 2. Identify the message and the change

Read the event's `data.whatsapp_id` to find the message the contact reacted to. This is the original Bird message ID (`wam_…`), rather than a separate reaction ID.

Use `data.from` to identify the contact and `data.to` to identify your WhatsApp sender. These are WhatsApp address objects; handle [business-scoped user IDs](/docs/guides/whatsapp/business-scoped-user-ids) when the contact's address has no phone number.

A contact adding a thumbs-up reaction produces this webhook:

```json
{
  "data": {
    "emoji": "👍",
    "from": { "phone_number": "+14155550100" },
    "to": { "phone_number": "+13124495569" },
    "whatsapp_id": "wam_01ky8b3xq4gd7pmzn2ka51f7te",
    "workspace_id": "ws_01ky7m235keycbnwyajabe1a6b"
  },
  "timestamp": "2026-08-28T19:01:10.000Z",
  "type": "whatsapp.reacted"
}
```

Interpret `data.emoji` as follows:

- A non-null emoji adds or replaces that contact's reaction on the referenced message.
- A `null` emoji removes that contact's reaction. The field is present on a removal event.

A replacement arrives as one event carrying the new emoji; there is no separate removal event for the old emoji. Preserve the exact string: `❤` and `❤️` are distinct values in the payload.

## 3. Retrieve the current reactions

If your application displays the reaction currently attached to a message, [retrieve the message](/docs/api/reference/get-whatsapp-message) and read its `reactions`. The list contains one standing reaction per sender and is omitted when no reactions stand.

For `GET /v1/whatsapp/messages/wam_01ky8b3xq4gd7pmzn2ka51f7te`, the reaction-related fields have this shape (other message fields omitted):

```json
{
  "id": "wam_01ky8b3xq4gd7pmzn2ka51f7te",
  "reactions": [
    {
      "emoji": "👍",
      "from": { "phone_number": "+14155550100" }
    }
  ]
}
```

The message retains its original content, direction, and delivery status. `reactions[].from` identifies the person who reacted.

Do not treat the last webhook you receive as the current state. WhatsApp reports reaction times to the second, so changes can share a timestamp, and webhook retries can change arrival order. Use webhooks to trigger a refresh of the message's current reactions.

## 4. Inspect reaction history

[List reaction events](/docs/api/reference/list-whatsapp-message-reaction-events) to inspect changes to the referenced message. Incoming contact changes have status `received`; a removal carries `emoji: null`. The list also includes outcomes of [reactions your workspace sent](/docs/guides/whatsapp/reactions).

The reaction-events API returns a paginated response. This example shows a rejected business reaction and an earlier received contact reaction:

```json
{
  "data": [
    {
      "id": "war_01krdgeqcxet5s7t44vh8rt9mh",
      "emoji": "🎉",
      "status": "rejected",
      "from": {
        "phone_number": "+13124495569"
      },
      "error": {
        "code": "internal_error",
        "description": "the receiving number is no longer connected",
        "occurred_at": "2026-08-28T19:04:22Z"
      },
      "occurred_at": "2026-08-28T19:04:22Z"
    },
    {
      "id": "war_01krdgeqcxet5s7t44vh8rt9mg",
      "emoji": "👍",
      "status": "received",
      "from": {
        "phone_number": "+14155550100",
        "bsuid": "US.13491208655302741918"
      },
      "occurred_at": "2026-08-28T19:01:10Z"
    }
  ],
  "next_cursor": null,
  "prev_cursor": null,
  "refresh_cursor": "eyJ2IjoxLCJzIjoiMjAyNi0wOC0yOFQxOTowNDoyMloiLCJpIjoiMDE5ZTFiMDctNWQ5ZC03NjhiLTkzZTgtODRkYzUxOGQyNjkxIn0"
}
```

Reaction history is separate from the message's delivery events. The message-events endpoint does not contain `whatsapp.reacted` changes. For retention and pagination, follow the [reaction log reference](/docs/api/reference/list-whatsapp-message-reaction-events).

## Troubleshooting

- **No reaction webhook**: Check that the subscription includes `whatsapp.reacted`. A reaction to an older message whose provider reference can no longer be resolved produces no matched reaction, log entry, or webhook.
- **Reaction missing from the message list**: Look up the original message. A reaction is attached to it and has no separate message row.
- **Reaction state changes unexpectedly**: Refresh the original message's `reactions` instead of ordering webhook events by arrival time or timestamp.

## Next steps

- [Send or remove a reaction](/docs/guides/whatsapp/reactions)
- [Read WhatsApp event payloads](/docs/guides/whatsapp/events)
- [Receive WhatsApp messages](/docs/guides/whatsapp/receiving-whatsapp)

## 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](/products/whatsapp) (product)

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