Skip to content

Send an interactive message

Interactive messages add tappable actions to a body of text. They need an open 24-hour window, same as text and media. Every kind shares the outer shape:

{
"to": "+919999999999",
"type": "interactive",
"interactive": {
"type": "<button | list | cta_url | location_request_message | address_message | flow>",
"header": { "...": "optional" },
"body": { "text": "..." },
"footer": { "...": "optional" },
"action": { "...": "required, shape depends on interactive.type" }
}
}

Up to three buttons the customer taps to reply. A tap comes back as a message from the customer carrying the button’s id and title, which opens the 24-hour window.

Terminal window
curl -X POST "$HELLO_API_URL/v1/<your-phone-number-id>/messages" \
-H "Authorization: Bearer $HELLO_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"to": "+919999999999",
"type": "interactive",
"interactive": {
"type": "button",
"header": { "type": "text", "text": "Booking" },
"body": { "text": "Confirm your booking for tomorrow 10:00?" },
"footer": { "text": "Reply anytime" },
"action": {
"buttons": [
{ "type": "reply", "reply": { "id": "yes", "title": "Yes" } },
{ "type": "reply", "reply": { "id": "no", "title": "No" } }
]
}
}
}'

header can be text, or image/video/document in the same shape as media messages. action.buttons allows up to 3 entries; reply.id is returned to you verbatim when the customer taps it, reply.title up to 20 characters.

A single button that opens a scrollable list of options, grouped into sections.

{
"to": "+919999999999",
"type": "interactive",
"interactive": {
"type": "list",
"header": { "type": "text", "text": "Appointments" },
"body": { "text": "Pick a slot" },
"footer": { "text": "Times are IST" },
"action": {
"button": "View slots",
"sections": [
{
"title": "Monday",
"rows": [
{ "id": "mon-9", "title": "09:00", "description": "Morning" },
{ "id": "mon-14", "title": "14:00", "description": "Afternoon" }
]
},
{ "title": "Tuesday", "rows": [{ "id": "tue-11", "title": "11:00" }] }
]
}
}
}

Up to 10 rows total across all sections. action.button is the label of the button that opens the list, up to 20 characters.

A single button that opens a URL, with its own display text (unlike a template’s URL button, this needs no pre-approval).

{
"to": "+919999999999",
"type": "interactive",
"interactive": {
"type": "cta_url",
"header": { "type": "text", "text": "Your order" },
"body": { "text": "Track your order in real time" },
"footer": { "text": "Thanks for shopping" },
"action": {
"name": "cta_url",
"parameters": { "display_text": "Track order", "url": "https://example.com/track/10432" }
}
}
}

Asks the customer to share their current location. The reply arrives as an inbound location message.

{
"to": "+919999999999",
"type": "interactive",
"interactive": {
"type": "location_request_message",
"body": { "text": "Share your location so we can find the nearest store" },
"action": { "name": "send_location" }
}
}

Asks the customer to fill in a structured delivery address. Supported for a limited set of countries on WhatsApp’s side (for example India).

{
"to": "+919999999999",
"type": "interactive",
"interactive": {
"type": "address_message",
"body": { "text": "Where should we deliver?" },
"action": { "name": "address_message", "parameters": { "country": "IN" } }
}
}

Opens a WhatsApp Flow — a structured, multi-screen form inside WhatsApp. flow_id must be a flow published on the sending number’s WABA.

{
"to": "+919999999999",
"type": "interactive",
"interactive": {
"type": "flow",
"body": { "text": "Book an appointment" },
"action": {
"name": "flow",
"parameters": {
"flow_message_version": "3",
"flow_id": "1234567890",
"flow_cta": "Book",
"flow_action": "navigate",
"flow_action_payload": { "screen": "WELCOME" }
}
}
}
}

202 Accepted (queued), or 200 with ?sync=true once WhatsApp accepts it. See Send a message. interactive is forwarded to WhatsApp as sent, so every field WhatsApp documents for a given interactive.type — including kinds not listed above, such as carousel, product, product_list and catalog_message — is accepted; Hello does not validate the shape beyond the outer interactive object being present.

Status code Cause
403 OUTSIDE_24H_WINDOW The recipient’s 24-hour window is closed
400 VALIDATION_ERROR interactive is missing or the wrong shape
422 SEND_FAILED (?sync=true only) WhatsApp rejected the message, for example an unpublished flow_id or too many rows in a list