Interactive messages
Interactive messages
Interactive messages put tappable UI — reply buttons, scrollable lists, or a call-to-action link button — into a WhatsApp thread. You send them through the same POST /send endpoint using the interactive content field, and the customer's tap comes back to you on the received webhook.
All three shapes below are Meta Cloud API interactive objects passed through verbatim — Telenow does not reshape them. interactive.type must be one of button, list, or cta_url; other Meta interactive types (flow, product, product_list, catalog_message, address_message, location_request_message) are rejected with 400 interactive type must be button, list or cta_url. Interactive messages are free-form content, so they only send inside the 24-hour customer service window; outside it, start with a template.
Reply buttons
A button interactive shows up to three tappable quick-reply buttons under a body text. Each button has your own id (echoed back on the tap) and a title (what the customer sees, ≤20 chars).
curl -X POST https://api.telenow.ai/api/app-whatsapp/send \
-H "Authorization: Bearer vai_app_…" \
-H "Content-Type: application/json" \
-d '{
"channelId": "b1e2c3d4-…",
"to": "+919876543210",
"interactive": {
"type": "button",
"body": { "text": "Did this resolve your issue?" },
"action": {
"buttons": [
{ "type": "reply", "reply": { "id": "resolved_yes", "title": "Yes, thanks" } },
{ "type": "reply", "reply": { "id": "resolved_no", "title": "Still stuck" } },
{ "type": "reply", "reply": { "id": "talk_human", "title": "Talk to an agent" } }
]
}
}
}'
{ "success": true, "data": { "wamid": "wamid.HBgLMTQxNTU1MDEwMBUCABIYFj…" } }
Rules that mirror Meta's:
| Field | Notes |
|---|---|
action.buttons | 1–3 buttons. More than 3 → 400 |
reply.id | Your identifier, ≤256 chars. Comes back verbatim on the tap — make it stable and meaningful |
reply.title | ≤20 chars, must be unique within the message |
header | Optional — { "type": "text", "text": "…" }. An image / video / document header must reference a public https link, e.g. { "type": "image", "image": { "link": "https://…" } } — not a mediaId |
footer | Optional — { "text": "…" }, ≤60 chars |
Staged mediaIds from POST /channels/{id}/media are only translated for plain media sends and template headers — never inside interactive, where the object is forwarded to Meta verbatim, so a media header must carry a public https link.
List messages
A list interactive opens a menu the customer scrolls through. It has one action.button label (the text that opens the sheet) and one or more sections, each holding up to 10 rows. Every row has an id, a title, and an optional description.
curl -X POST https://api.telenow.ai/api/app-whatsapp/send \
-H "Authorization: Bearer vai_app_…" \
-H "Content-Type: application/json" \
-d '{
"channelId": "b1e2c3d4-…",
"to": "+919876543210",
"interactive": {
"type": "list",
"header": { "type": "text", "text": "Book an appointment" },
"body": { "text": "Pick a slot that works for you." },
"footer": { "text": "Times shown in IST" },
"action": {
"button": "View slots",
"sections": [
{
"title": "Today",
"rows": [
{ "id": "slot_1500", "title": "3:00 PM", "description": "Dr. Rao — 30 min" },
{ "id": "slot_1630", "title": "4:30 PM", "description": "Dr. Rao — 30 min" }
]
},
{
"title": "Tomorrow",
"rows": [
{ "id": "slot_1000", "title": "10:00 AM", "description": "Dr. Mehta — 30 min" }
]
}
]
}
}
}'
{ "success": true, "data": { "wamid": "wamid.HBgLMTQxNTU1MDEwMBUCABIYFj…" } }
| Field | Notes |
|---|---|
action.button | ≤20 chars. The label that opens the list |
sections | ≥1 section; ≤10 rows total across all sections |
sections[].title | Optional section heading, ≤24 chars |
rows[].id | Your identifier, ≤200 chars. Echoed back on selection |
rows[].title | ≤24 chars, unique across the whole list |
rows[].description | Optional, ≤72 chars |
Call-to-action URL
A cta_url interactive renders a body plus a single button that opens a URL — cleaner than pasting a raw link, and it survives Meta's link-formatting. This one has no tap webhook: the customer just leaves for your URL, so there is nothing to receive back.
curl -X POST https://api.telenow.ai/api/app-whatsapp/send \
-H "Authorization: Bearer vai_app_…" \
-H "Content-Type: application/json" \
-d '{
"channelId": "b1e2c3d4-…",
"to": "+919876543210",
"interactive": {
"type": "cta_url",
"body": { "text": "Your order #1234 is ready. Track it live below." },
"action": {
"name": "cta_url",
"parameters": {
"display_text": "Track order",
"url": "https://shop.example.com/track/1234"
}
}
}
}'
{ "success": true, "data": { "wamid": "wamid.HBgLMTQxNTU1MDEwMBUCABIYFj…" } }
action.name must be the literal string "cta_url". parameters.display_text is the button label; parameters.url must be a fully-qualified https:// link. An optional header / footer can wrap the body just like the other types — a media header must reference a public https link (e.g. { "type": "image", "image": { "link": "https://…" } }), not a staged mediaId.
Handling the tap
When the customer taps a reply button or picks a list row, Telenow delivers a whatsapp.message.received webhook whose content.reply carries the choice — see Webhooks & events for the full payload and signature verification.
{
"event": "whatsapp.message.received",
"channelId": "b1e2c3d4-…",
"from": "+919876543210",
"wamid": "wamid.HBgLM…",
"type": "interactive",
"content": {
"reply": { "kind": "button_reply", "id": "resolved_no", "title": "Still stuck" }
},
"timestamp": "2026-07-18T09:31:00Z"
}
content.reply.kindis"button_reply"for a reply-button tap and"list_reply"for a list-row selection.content.reply.idis the exactidyou set on the button or row — key your routing off this, not the human-readabletitle.content.reply.titleis the label the customer saw.
Because the id round-trips unchanged, you can encode routing hints into it (e.g. slot_1500, talk_human) and branch on it directly when the webhook arrives.
Related
- Webhooks & events — receive and verify the tap (
content.reply). - Sending template messages — start conversations outside the 24-hour window.
- Location, contacts & reactions — the other rich
/sendcontent fields. - Media messages — images, documents, audio and video.
- WhatsApp overview — connect a number and find your
channelId.