Skip to main content
Version: Latest

Interactive Messages

Interactive messages let customers choose buttons or list items. Send the complete request bodies below to the corresponding channel send endpoint with x-api-key and Content-Type: application/json. Replace channel IDs, recipient IDs and example media URLs with your own values. Ordinary WhatsApp interactive sends require an active 24-hour customer-service window.

WhatsApp session limits​

These limits apply to ordinary WhatsApp interactive messages, without a template. Each message uses one interactive type; template button limits do not apply to session messages.

Interactive typeQuantity per messageLabel limits
button1–3 reply buttonsReply title: 20 characters; reply ID: 256 characters
cta_url1 URL buttonaction.parameters.display_text: 20 characters
list1 button opening 1–10 options in total, across 1–10 sectionsOpening button: 20 characters; section/row title: 24; row description: 72; row ID: 200

The list's ten-option limit counts all rows across all sections, not ten rows per section. A button message accepts only reply buttons; it cannot combine replies with a URL CTA. Send separate session messages or use an approved template with a supported button combination.

These are WhatsApp provider limits, not a guarantee that Hub rejects every oversized payload before forwarding it. Hub's shared nested-array validation ceiling of 100 entries does not increase WhatsApp's supported quantities, and other channels have their own limits.

The current Hub API accepts button, list, cta_url and location_request_message as content.interactive.type. Meta's voice_call and interactive carousel formats are not accepted by this field. Template Flow buttons use the separate template contract.

See Meta's references for reply buttons, CTA URL messages and lists.

Availability by type and channel​

Interactive typeWhatsAppInstagramMessengerTelegramWeb Chatt
Quick Reply (buttons)YesYesYesInline keyboardYes
Option listYesCardsCardsPollYes
CTA URLYesURL buttonURL buttonNoYes
Request locationYesNoNoNoNo

Web Chatt widget v1.3.1 implements buttons, lists and CTA URL navigation. It also renders text/image/video headers and footers for buttons and CTA messages. This is the verified local widget version; older widget versions may differ. The document header is described separately below. These are implementation capabilities; provider acceptance and client presentation can vary.

Instagram and Messenger discard interactive headers and footers. Telegram supports image/video headers on buttons and appends the footer to the message caption. WhatsApp passes supported headers and footers to the provider.

Quick Reply (response buttons)​

The three-button limit applies to WhatsApp, as do the 20-character reply titles below. Instagram and Messenger use the quick-reply transformation for 1–13 buttons without an image/video header; media headers select a different button-template transformation and are discarded. Telegram and Web Chatt do not share WhatsApp's three-button limit. Hub nested arrays accept at most 100 entries; that validation ceiling does not replace provider limits.

{
"from": "9e85226d-a104-4c85-a21a-5c3cbf7daa8f",
"to": "5511993986082",
"content": {
"interactive": {
"type": "button",
"header": {
"type": "text",
"text": "Customer support"
},
"body": {
"text": "How can I help you?"
},
"footer": {
"text": "Reply with an option"
},
"action": {
"buttons": [
{
"type": "reply",
"reply": {
"id": "SUPPORT",
"title": "Support"
}
},
{
"type": "reply",
"reply": {
"id": "SALES",
"title": "Sales"
}
},
{
"type": "reply",
"reply": {
"id": "OTHER",
"title": "Other"
}
}
]
}
}
}
}
FieldUse
action.buttons[].typereply
reply.idYour callback identifier
reply.titleDisplay label; use at most 20 characters for WhatsApp

Image header on Telegram buttons​

Use POST /v1/communication/telegram/message with a Telegram bot channel UUID and chat ID. The image becomes a photo with an inline keyboard; the body and footer form its caption.

{
"from": "9e85226d-a104-4c85-a21a-5c3cbf7daa8f",
"to": "123456789",
"content": {
"interactive": {
"type": "button",
"header": {
"type": "image",
"image": {
"link": "https://example.com/support-banner.jpg"
}
},
"body": {
"text": "How can I help you?"
},
"footer": {
"text": "Reply with an option"
},
"action": {
"buttons": [
{
"type": "reply",
"reply": {
"id": "SUPPORT",
"title": "Support"
}
},
{
"type": "reply",
"reply": {
"id": "SALES",
"title": "Sales"
}
},
{
"type": "reply",
"reply": {
"id": "OTHER",
"title": "Other"
}
}
]
}
}
}
}

For WhatsApp and Web Chatt, the same interactive object can use an image header or a video header with type: "video" and video.link. Use the appropriate channel UUID and recipient ID at that channel's send endpoint. Web Chatt recipients are visitor UUIDs, for example 74f7d0c4-a11d-4c1d-9569-17757aac1832.

Video header on Web Chatt buttons​

Use POST /v1/communication/web-chatt2me/message with a widget channel and visitor UUID. Widget v1.3.1 renders the video header, body, footer and reply buttons:

{
"from": "9e85226d-a104-4c85-a21a-5c3cbf7daa8f",
"to": "74f7d0c4-a11d-4c1d-9569-17757aac1832",
"content": {
"interactive": {
"type": "button",
"header": {
"type": "video",
"video": {
"link": "https://example.com/support-introduction.mp4"
}
},
"body": {
"text": "How can I help you?"
},
"footer": {
"text": "Reply with an option"
},
"action": {
"buttons": [
{
"type": "reply",
"reply": {
"id": "SUPPORT",
"title": "Support"
}
},
{
"type": "reply",
"reply": {
"id": "SALES",
"title": "Sales"
}
},
{
"type": "reply",
"reply": {
"id": "OTHER",
"title": "Other"
}
}
]
}
}
}
}

Option list​

WhatsApp and Web Chatt preserve the section/row structure. Instagram and Messenger flatten the rows into cards with postback buttons, losing section grouping. Telegram converts the row titles into a poll and requires at least two nonempty option titles. Sections, descriptions and row IDs are not represented in that poll.

{
"from": "9e85226d-a104-4c85-a21a-5c3cbf7daa8f",
"to": "5511993986082",
"content": {
"interactive": {
"type": "list",
"header": {
"type": "text",
"text": "Our menu"
},
"body": {
"text": "Choose a dish"
},
"footer": {
"text": "Available until 10 PM"
},
"action": {
"button": "View options",
"sections": [
{
"title": "Main courses",
"rows": [
{
"id": "dish_1",
"title": "Grilled steak",
"description": "With fries and salad"
},
{
"id": "dish_2",
"title": "Shrimp risotto",
"description": "Serving for 2 people"
}
]
},
{
"title": "Desserts",
"rows": [
{
"id": "dessert_1",
"title": "Chocolate lava cake",
"description": "With vanilla ice cream"
}
]
}
]
}
}
}
}
FieldUse
action.buttonLabel that opens the WhatsApp list
action.sectionsSections containing rows
sections[].titleOptional section heading
rows[].idCallback identifier for channels that preserve row IDs
rows[].titleItem label; use at most 24 characters for WhatsApp
rows[].descriptionOptional description; use at most 72 characters for WhatsApp

On Telegram, use action.name: "multiple" or "multiple_answers" for multiple selections; the default poll mode is regular. A provider may impose additional poll limits. Use unique titles if your integration needs to recognize selections from their text.

A CTA opens a browser URL. It is supported by WhatsApp, Instagram, Messenger and the Web Chatt widget described above. Telegram has no CTA transformation. Opening a CTA does not provide the button/list selection webhook shown below.

Text header​

{
"from": "9e85226d-a104-4c85-a21a-5c3cbf7daa8f",
"to": "5511993986082",
"content": {
"interactive": {
"type": "cta_url",
"header": {
"type": "text",
"text": "Visit our website"
},
"body": {
"text": "Open your order details."
},
"footer": {
"text": "Available 24/7"
},
"action": {
"parameters": {
"display_text": "View order",
"url": "https://example.com/orders/order-123"
}
}
}
}
}

Image header​

{
"from": "9e85226d-a104-4c85-a21a-5c3cbf7daa8f",
"to": "5511993986082",
"content": {
"interactive": {
"type": "cta_url",
"header": {
"type": "image",
"image": {
"link": "https://example.com/order-banner.jpg"
}
},
"body": {
"text": "Open your order details."
},
"footer": {
"text": "Available 24/7"
},
"action": {
"parameters": {
"display_text": "View order",
"url": "https://example.com/orders/order-123"
}
}
}
}
}

Video header​

{
"from": "9e85226d-a104-4c85-a21a-5c3cbf7daa8f",
"to": "5511993986082",
"content": {
"interactive": {
"type": "cta_url",
"header": {
"type": "video",
"video": {
"link": "https://example.com/order-demo.mp4"
}
},
"body": {
"text": "Open your order details."
},
"footer": {
"text": "Available 24/7"
},
"action": {
"parameters": {
"display_text": "View order",
"url": "https://example.com/orders/order-123"
}
}
}
}
}

Document header​

Use a document header for a compatible WhatsApp connection. The link must be an HTTP(S) URL; the optional filename is nonempty and limited to 255 characters. Hub validates and prepares the document media before forwarding it; WhatsApp documents have a 100 MiB limit. See Content Types for media requirements.

{
"from": "9e85226d-a104-4c85-a21a-5c3cbf7daa8f",
"to": "5511993986082",
"content": {
"interactive": {
"type": "cta_url",
"header": {
"type": "document",
"document": {
"link": "https://example.com/order-summary.pdf",
"filename": "Order-summary.pdf"
}
},
"body": {
"text": "Open your order details."
},
"footer": {
"text": "Available 24/7"
},
"action": {
"parameters": {
"display_text": "View order",
"url": "https://example.com/orders/order-123"
}
}
}
}
}

This new API header type does not imply document-preview rendering in Web Chatt widget v1.3.1 or other clients. Instagram/Messenger discard the header, and Telegram has no CTA transformation. Verify presentation in your target WhatsApp client.

Request user location (WhatsApp)​

{
"from": "9e85226d-a104-4c85-a21a-5c3cbf7daa8f",
"to": "5511993986082",
"content": {
"interactive": {
"type": "location_request_message",
"body": {
"text": "To calculate shipping, please share your location."
},
"action": {
"name": "send_location"
}
}
}
}

The reply arrives as a location message in the normalized webhook payload.

User responses via webhook​

Hub sends its normalized message envelope. Read the selected identifier from payload.message.content.buttons[].id, the displayed title from label, and the incoming Hub message ID from payload.message.id.

WhatsApp button selection​

{
"eventType": "message",
"timestamp": "2026-10-06T15:00:00.000Z",
"payload": {
"provider": "whatsapp",
"direction": "IN",
"timestamp": 1791298800000,
"message": {
"id": "9b509e32-bfec-4fe6-8a63-2c22017a3a17",
"sessionId": "d387b2bf-b36e-40f4-90f8-0a4db8a49f75",
"type": "Button",
"content": {
"buttons": [
{
"id": "SUPPORT",
"label": "Support",
"type": "reply"
}
]
}
},
"sender": {
"id": "5511993986082"
},
"recipient": {
"id": "551130001234",
"applicationChannelId": "9e85226d-a104-4c85-a21a-5c3cbf7daa8f"
}
}
}

WhatsApp list selection​

{
"eventType": "message",
"timestamp": "2026-10-06T15:00:00.000Z",
"payload": {
"provider": "whatsapp",
"direction": "IN",
"timestamp": 1791298800000,
"message": {
"id": "9b509e32-bfec-4fe6-8a63-2c22017a3a17",
"sessionId": "d387b2bf-b36e-40f4-90f8-0a4db8a49f75",
"type": "Button",
"content": {
"buttons": [
{
"id": "dish_1",
"label": "Grilled steak",
"type": "list"
}
]
}
},
"sender": {
"id": "5511993986082"
},
"recipient": {
"id": "551130001234",
"applicationChannelId": "9e85226d-a104-4c85-a21a-5c3cbf7daa8f"
}
}
}

Instagram/Messenger postbacks use buttons[].type: "postback". Handle the normalized fields rather than assuming the provider's raw interactive structure.

Telegram poll selection​

The following is a normalized poll-answer envelope when a selected title has been resolved. content.poll.id is the provider poll identifier. Poll aggregate updates may also include question/options/vote counts. Hub does not export the stored selected option indices or list row IDs in this webhook.

{
"eventType": "message",
"timestamp": "2026-10-06T15:00:00.000Z",
"payload": {
"provider": "telegram",
"direction": "IN",
"timestamp": 1791298800000,
"message": {
"id": "9b509e32-bfec-4fe6-8a63-2c22017a3a17",
"sessionId": "d387b2bf-b36e-40f4-90f8-0a4db8a49f75",
"type": "Poll",
"content": {
"text": "Grilled steak",
"poll": {
"id": "5812298937489215487"
}
}
},
"sender": {
"id": "123456789"
},
"recipient": {
"id": "123456789",
"applicationChannelId": "9e85226d-a104-4c85-a21a-5c3cbf7daa8f"
}
}
}

Correlate with the poll ID and resolved title text when available. A poll update without text does not identify an individual selection.