Skip to main content

Interactive messages

Interactive messages give users structured ways to respond: picking from a list, tapping a button or completing a form. They can only be sent within the customer service window. To send interactive content outside the window, use an interactive template.

Typeinteractive.typeUse it to…
List messagelistLet the user choose from a menu of up to 10 options.
Reply button messagebuttonOffer up to 3 quick replies.
CTA URL button messagebuttonShow a single button that opens a URL, instead of a long raw link.
Location request messagelocation_request_messageAsk the user to share their location.
Flows messageflowOpen a WhatsApp Flow: forms and multi-screen journeys.
Call permission requestcall_permission_requestAsk the user for permission to call them on WhatsApp.
Media carousel messagecarouselShow 2–10 horizontally scrollable cards with media and buttons.

To ask a user for their phone number, see Request phone number from users. For product-related interactive messages, see Catalogue & Product messages.

The user's response is delivered to your MO webhook. See Interactive responses.


Message structure​

Add an interactive item to richContent.conversation. Most interactive types share the following structure:

FieldDescription
typeThe interactive type. See the table above.
headerOptional header. Supported header types depend on the interactive type.
body.textMessage text.
footer.textOptional footer text.
actionThe interactive element: list sections, buttons or other parameters, depending on the type.

Header types​

Interactive typeSupported header types
List messagetext (max. 60 characters)
Reply buttonstext, image, video, document
CTA URL buttontext, image, video, document
Flows messagetext

For a media header, set header.type to the media type and add a media object (mediaName, mediaUri, mimeType). Audio headers are not supported.

Complete request​

The examples on this page show the interactive item only. Place it in a request as follows:

Complete request
{
"messages": {
"authentication": {
"productToken": "YOUR_PRODUCT_TOKEN"
},
"msg": [
{
"from": "00316098765432",
"to": [
{ "number": "00316012345678" }
],
"body": {
"type": "auto",
"content": "Fallback text"
},
"allowedChannels": ["WhatsApp"],
"richContent": {
"conversation": [
{
"interactive": {
"type": "button",
"body": {
"text": "Would you like to receive order updates on WhatsApp?"
},
"action": {
"buttons": [
{ "type": "reply", "reply": { "id": "updates-yes", "title": "Yes, please" } },
{ "type": "reply", "reply": { "id": "updates-no", "title": "No, thanks" } }
]
}
}
}
]
}
}
]
}
}

List message​

A list message shows a button that opens a menu. The user selects one row.

Interactive list message

FieldRequiredLimitDescription
header.textNo60 charactersHeader text. Only text headers are supported.
body.textYesMessage text.
footer.textNoFooter text.
action.buttonYesLabel of the button that opens the list.
action.sections[].titleYes24 charactersSection title.
action.sections[].rows[].idYes200 charactersUnique row ID. Returned in the user's reply.
action.sections[].rows[].titleYes24 charactersRow title.
action.sections[].rows[].descriptionNo72 charactersRow description.

A list can contain up to 10 rows in total.

List message
{
"interactive": {
"type": "list",
"header": {
"type": "text",
"text": "Our opening hours"
},
"body": {
"text": "Which store would you like to visit?"
},
"footer": {
"text": "CM.com"
},
"action": {
"button": "Choose a store",
"sections": [
{
"title": "North Brabant",
"rows": [
{ "id": "store-breda", "title": "Breda", "description": "Konijnenberg 30" }
]
},
{
"title": "North Holland",
"rows": [
{ "id": "store-amsterdam", "title": "Amsterdam", "description": "City centre" }
]
}
]
}
}
}

Reply button message​

A reply button message shows up to 3 buttons. When the user taps a button, its id is returned in the reply.

Interactive reply button message

FieldRequiredLimitDescription
headerNotext, image, video or document header.
body.textYesMessage text.
footer.textNoFooter text.
action.buttons[].typeYesreply
action.buttons[].reply.idYes256 charactersUnique button ID. Returned in the user's reply.
action.buttons[].reply.titleYes20 charactersButton label. Must be unique within the message. No emoji or Markdown.
Text header
{
"interactive": {
"type": "button",
"header": {
"type": "text",
"text": "Delivery update"
},
"body": {
"text": "Your parcel is ready for delivery. When would you like to receive it?"
},
"footer": {
"text": "Reply within 24 hours"
},
"action": {
"buttons": [
{ "type": "reply", "reply": { "id": "delivery-today", "title": "Today" } },
{ "type": "reply", "reply": { "id": "delivery-tomorrow", "title": "Tomorrow" } }
]
}
}
}
Image header
{
"interactive": {
"type": "button",
"header": {
"type": "image",
"media": {
"mediaName": "CM.com - Be part of it.",
"mediaUri": "https://www.cm.com/cdn/web/blog/content/logo-cmcom.png",
"mimeType": "image/png"
}
},
"body": {
"text": "Your parcel is ready for delivery. When would you like to receive it?"
},
"action": {
"buttons": [
{ "type": "reply", "reply": { "id": "delivery-today", "title": "Today" } },
{ "type": "reply", "reply": { "id": "delivery-tomorrow", "title": "Tomorrow" } }
]
}
}
}

Interactive reply button message with image


CTA URL button message​

A call-to-action (CTA) URL button message shows a single button that opens a URL. Use it instead of a raw link, which users may be hesitant to tap.

Interactive CTA button message

FieldRequiredDescription
headerNotext, image, video or document header.
body.textYesMessage text.
footer.textNoFooter text.
action.buttons[].typeYesopenurl
action.buttons[].idYesUnique button ID.
action.buttons[].titleYesButton label.
action.buttons[].urlYesURL opened when the user taps the button.
One button only

WhatsApp supports one URL button per message. If you supply more than one, only the first is sent.

Text header
{
"interactive": {
"type": "button",
"header": {
"type": "text",
"text": "Your invoice"
},
"body": {
"text": "Your invoice for October is ready."
},
"footer": {
"text": "CM.com"
},
"action": {
"buttons": [
{
"type": "openurl",
"id": "view-invoice",
"title": "View invoice",
"url": "https://www.example.com/invoices/2026-10"
}
]
}
}
}
Image header
{
"interactive": {
"type": "button",
"header": {
"type": "image",
"media": {
"mediaName": "Invoice",
"mediaUri": "https://www.example.com/images/invoice.png",
"mimeType": "image/png"
}
},
"body": {
"text": "Your invoice for October is ready."
},
"action": {
"buttons": [
{
"type": "openurl",
"id": "view-invoice",
"title": "View invoice",
"url": "https://www.example.com/invoices/2026-10"
}
]
}
}
}

Interactive CTA button with image header


Location request message​

A location request message contains a Send location button. When the user taps it, WhatsApp opens a screen where they can share their location. The location is delivered to your MO webhook as a location message.

Location request message

FieldRequiredDescription
body.textYesMessage text.
action.nameYessend_location
Location request message
{
"interactive": {
"type": "location_request_message",
"body": {
"text": "Hello! Please share your pickup location so we can send you a cab."
},
"action": {
"name": "send_location"
}
}
}

Flows message​

A Flows message opens a WhatsApp Flow: a form or multi-screen journey you have built in WhatsApp Manager. The data the user submits is delivered to your MO webhook as a Flows reply.

FieldRequiredDescription
headerNotext header.
body.textYesMessage text.
footer.textNoFooter text.
action.nameYesflow
action.parameters.flow_message_versionYesMust be 3.
action.parameters.flow_idYes*ID of the Flow. *Provide either flow_id or flow_name, not both.
action.parameters.flow_nameYes*Name of the Flow. *Provide either flow_id or flow_name, not both.
action.parameters.flow_tokenNoYour own token. It is returned in the Flows reply so you can correlate the response.
action.parameters.flow_ctaYesLabel of the button that opens the Flow.
action.parameters.flow_actionNonavigate or data_exchange.
action.parameters.flow_action_payloadNoFor navigate: the first screen to show and optional initial data.
Flows message
{
"interactive": {
"type": "flow",
"header": {
"type": "text",
"text": "Book an appointment"
},
"body": {
"text": "Choose a date and time that suits you."
},
"footer": {
"text": "CM.com"
},
"action": {
"name": "flow",
"parameters": {
"flow_message_version": "3",
"flow_id": "your-flow-id",
"flow_token": "your-flow-token",
"flow_cta": "Book now",
"flow_action": "navigate",
"flow_action_payload": {
"screen": "YOUR_FIRST_SCREEN_ID",
"data": {
"optional-field": "optional-value"
}
}
}
}
}
}

Call permission request message​

Before you can call a WhatsApp user, you need their explicit permission. A call permission request asks the user to grant it, either temporarily or permanently. Only the user can grant or revoke permission. The user's response is delivered to your MO webhook as a call permission reply.

To request permission outside the customer service window, use a call permission request template.

Example of interactive call permission request

Limits​

LimitValue
Temporary permissionValid for 7 days (168 hours).
Permanent permissionDoes not expire, but the user can revoke it.
Permission requestsMax. 1 per 24 hours and 2 per 7 days per user. Both limits reset after any connected call.
Connected callsMax. 100 per business phone number per 24 hours.
Unanswered callsAfter 2 consecutive unanswered calls, the user is asked to reconsider the permission. After 4, the permission is revoked automatically.

Fields​

FieldRequiredDescription
headerNoHeader.
body.textNoMessage text. Strongly recommended, so the user understands why you want to call.
footer.textNoFooter text.
action.nameYescall_permission_request
Call permission request
{
"interactive": {
"type": "call_permission_request",
"body": {
"text": "Our support team would like to call you about your recent request. Do you allow us to call you on WhatsApp?"
},
"action": {
"name": "call_permission_request"
}
}
}

You can send this message to a phone number or to a Business-scoped User ID, only to[].number changes.


A media carousel shows 2–10 horizontally scrollable cards. Each card has an image or video header, optional body text and buttons.

Example of interactive media carousel

Rules​

  • The message must contain between 2 and 10 cards.
  • The message-level body.text is required. Message-level headers and footers are not supported.
  • Each card must have an image or video header. Other header types are not supported.
  • Card body text is optional.
  • Each card has either one CTA URL button or one or more quick-reply buttons. The button type and number of buttons must be the same on every card. For example, if one card has 2 quick-reply buttons, every card must have exactly 2.

Fields​

FieldRequiredDescription
body.textYesMessage text, shown above the cards.
action.cards[].card_indexYesPosition of the card, starting at 0.
action.cards[].typeYesCard type, for example cta_url.
action.cards[].header.typeYesimage or video.
action.cards[].header.image.linkYesPublic URL of the image (or header.video.link for video).
action.cards[].body.textNoCard text.
action.cards[].action.nameYescta_url for a URL button.
action.cards[].action.parameters.display_textYesButton label.
action.cards[].action.parameters.urlYesURL opened when the user taps the button.
Carousel with CTA URL buttons
{
"interactive": {
"type": "carousel",
"body": {
"text": "Check out our channels!"
},
"action": {
"cards": [
{
"card_index": 0,
"type": "cta_url",
"header": {
"type": "image",
"image": {
"link": "https://www.cm.com/cdn/web/en/download-whatsapp-business-guide-new.png"
}
},
"body": {
"text": "Use WhatsApp for direct, personalised communication with your audience."
},
"action": {
"name": "cta_url",
"parameters": {
"display_text": "WhatsApp",
"url": "https://www.cm.com/whatsapp/"
}
}
},
{
"card_index": 1,
"type": "cta_url",
"header": {
"type": "image",
"image": {
"link": "https://www.cm.com/cdn/web/en/instagram-newsletters-announcements.jpg"
}
},
"body": {
"text": "Boost customer engagement with Instagram's automated business-initiated messages."
},
"action": {
"name": "cta_url",
"parameters": {
"display_text": "Instagram",
"url": "https://www.cm.com/instagram-messaging/"
}
}
},
{
"card_index": 2,
"type": "cta_url",
"header": {
"type": "image",
"image": {
"link": "https://www.cm.com/cdn/web/en/rcs-features.png"
}
},
"body": {
"text": "Bring text messages to life with rich media."
},
"action": {
"name": "cta_url",
"parameters": {
"display_text": "RCS",
"url": "https://www.cm.com/rcs/"
}
}
}
]
}
}
}