Receiving WhatsApp interactive replies
A tap on a reply button, a list row, or a template's quick-reply button arrives as its own inbound message carrying interactive_reply. The arm gives you back the handle you set on the send, so a flow branches on your own identifier rather than on the label the contact saw.
What an inbound interactive reply carries
type names the kind of tap, and the field of the same name carries it:
Przykład kodu
{
"id": "wam_01kyb2m4xq7whs0d8n3prv6tez",
"direction": "inbound",
"from": { "phone_number": "+14155550100" },
"to": { "phone_number": "+13124495569" },
"status": "received",
"in_reply_to_message_id": "wam_01kya19eknftrs2s6p82asmvnh",
"interactive_reply": {
"type": "button",
"button": { "slug": "cancel-booking", "text": "Cancel" }
},
"created_at": "2026-08-25T09:04:11Z"
}| type | Field | What it carries |
|---|---|---|
| button | button | The slug and text of a reply button, or of a template's quick-reply button |
| list | list | The slug and text of the row the contact chose, plus its description when it had one |
A list row replaces button with list and adds the second line the row showed:
Przykład kodu
{
"interactive_reply": {
"type": "list",
"list": {
"slug": "priority_express",
"text": "Priority Mail Express",
"description": "Next day to 2 days"
}
}
}slug is the handle you declared and the contact never saw; text is the label they read. Branch on slug. Labels get reworded and translated, and on a tap on a template's quick-reply button the slug is the payload that template declared, which WhatsApp sets to the button's own label.
The kind list is open: WhatsApp adds interactive kinds over time, so treat a type you do not recognize as a future kind rather than an error, and fall back to logging the message instead of failing the read.
Tying a tap to what you sent
in_reply_to_message_id names the message that carried the button or the menu, which is how you know which question this answer belongs to. WhatsApp does not report it on every tap, and resolution can also miss, in which case the field is omitted rather than reported empty. The hub's quoted replies covers what a miss means and how long a quoted message stays resolvable.
Where correlation has to be reliable, put your own reference in the slug itself, or in metadata on the send, rather than depending on the field. See quoting a message for the send side.
The two taps that arrive elsewhere
Two interactive types answer without an interactive_reply at all:
- A location request comes back as an ordinary inbound location.
- A contact info request comes back as contact cards, with origin set to contact_request.
A link button sends nothing back: the contact leaves for the URL, and no inbound message records the tap. An integration watching only interactive_reply misses all three.
The webhook payload
whatsapp.received carries the interactive_reply arm on the event envelope, so a bot can answer a tap without reading the message back:
Przykład kodu
{
"type": "whatsapp.received",
"timestamp": "2026-08-25T09:04:11.118Z",
"data": {
"whatsapp_id": "wam_01kyb2m4xq7whs0d8n3prv6tez",
"workspace_id": "ws_01ky7m235keycbnwyajabe1a6b",
"direction": "inbound",
"from": { "phone_number": "+14155550100", "display_name": "Alex Rivera" },
"to": { "phone_number": "+13124495569" },
"in_reply_to_message_id": "wam_01kya19eknftrs2s6p82asmvnh",
"interactive_reply": {
"type": "button",
"button": { "slug": "cancel-booking", "text": "Cancel" }
},
"tags": null,
"metadata": null
}
}Things to watch
- interactive and interactive_reply are opposite directions. interactive is what you sent and never arrives inbound; interactive_reply is what the contact tapped and never appears on an outbound message.
- A tap resets the service window. It is an inbound message, so it reopens 24 hours of free-form replies the same way a text does.
- A contact can tap the same button twice. Nothing deduplicates taps, so each one is its own message with its own ID. Make the action you take on a slug idempotent.
- A tap on an old menu still arrives. A contact scrolling back can tap a button from days ago, so validate that the flow is still open rather than assuming the tap answers your latest message.
Next steps
- How receiving works: the inbound envelope, media fetching, and the whatsapp.received webhook
- WhatsApp interactive messages: the six types a recipient can tap
- WhatsApp reply buttons: the send side of a button tap
- WhatsApp list menus: the send side of a row choice