Skip to contentSkip to navigationSkip to topbar
Rate this page:
On this page

Send Rich Content Messages with Conversations



Overview

overview page anchor

In this tutorial, you will learn how to send rich messages to WhatsApp using Conversations and the Content Template Builder. The Content Template Builder lets users build rich content templates programmatically through an API or with no code in a graphical user interface in the console. "Rich content" or "Rich messaging" refers to messages with additional visual or interactive elements such as buttons or selectable lists.

The Content Template Builder

the-content-template-builder page anchor

With Twilio's Content Template Builder, you can create message templates to send over any Twilio-supported messaging channel. It supports text and media as well as richer content types like location, quick-replies, and list-pickers. The templates also support variables, so you can leverage the same content across multiple conversations while personalizing each message.

Below is an overview of the content types currently supported by Conversations. See the individual content type documentation for additional details about each type's parameters and input requirements.

Content TypeData parameterTypeDescription
twilio/textbody [required]stringThe text of the message you want to send. Maximum 1,600 characters.
twilio/mediabody [required]stringThe text of the message you want to send. Maximum 1,600 characters.
media [optional]string[]The URL of the media you want to send. - The URL must resolve to a publicly accessible media file. - The media URL must contain a valid file type.
twilio/locationlongitude [required]numbersThe longitude value of the location pin you want to send.
latitude [required]numbersThe latitude value of the location pin you want to send.
label [optional]stringLabel to be displayed alongside the location pin.
twilio/quick-replybody [required]stringThe text of the message you want to send. Maximum 1,024 characters.
actions [required]array[actions]Predefined buttons that a customer could use as the response. It needs the "type", "title", and "id" fields.
twilio/call-to-actionbody [required]stringThe text of the message you want to send. Maximum 640 characters.
actions [required]array[actions]Buttons that recipients can tap to act on the message. It requires the "type" and "title" actions.
twilio/list-pickerbody [required]stringThe text of the message you want to send. Maximum 1,024 characters.
button [required]stringDisplay value for the primary button.
items [required]array[list items]Array of list item objects.
twilio/cardtitle [required]stringTitle of the card. Maximum 1,024 characters.
subtitle [optional]stringSubtitle of the card. Maximum 60 characters.
media [optional]string[]The URL of the media to send with the message.
actions [optional]array[actions]Buttons that recipients can tap on to act on the message.

Step 1: Create Content Template via Content API

step-1-create-content-template-via-content-api page anchor
(information)

Info

The Content Template Builder supports an unlimited number of templates, however, WhatsApp limits users to 6000 approved templates across all languages.

To send a rich message, you'll first need to create a content template using the Content Template Builder.

In the following example, we'll use the "quick-reply" template, which allows the recipient to respond by simply clicking on one of the options that you pre-define in the template. To see how the template layout looks, please navigate to Step 4.

After creating your template, please note down the ContentSid (HXXXXXX) found in the response as we'll be using that SID throughout this tutorial.

POST API

Request:


_30
curl -X POST 'https://content.twilio.com/v1/Content' \
_30
-H 'Content-Type: application/json' \
_30
-u $TWILIO_ACCOUNT_SID:$TWILIO_AUTH_TOKEN \
_30
-d '{
_30
"friendly_name": "flight_replies",
_30
"language": "en",
_30
"variables": {"1":"name"},
_30
"types": {
_30
"twilio/quick-reply": {
_30
"body": "Hi, {{ 1 }}. \n Thanks for contacting Owl Air Support. How can I help?",
_30
"actions": [
_30
{
_30
"title": "Check flight status",
_30
"id": "flightid1"
_30
},
_30
{
_30
"title": "Check gate number",
_30
"id": "gateid1"
_30
},
_30
{
_30
"title": "Speak with an agent",
_30
"id": "agentid1"
_30
}
_30
]
_30
},
_30
"twilio/text": {
_30
"body": "Hi, {{ 1 }}. \n Thanks for contacting Owl Air Support. How can I help?."
_30
}
_30
}
_30
}'

Response:


_38
{
_38
"language": "en",
_38
"date_updated": "2022-08-29T10:43:20Z",
_38
"variables": {
_38
"1": "name"
_38
},
_38
"friendly_name": "flight_replies",
_38
"account_sid": "ACXXXXXXXXXXXXXXXXXXX",
_38
"url": "https://content.twilio.com/v1/Content/HXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
_38
"sid": "HXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
_38
"date_created": "2022-08-29T10:43:20Z",
_38
"types": {
_38
"twilio/text": {
_38
"body": "Hi, {{ 1 }}. \n Thanks for contacting Owl Air Support. How can I help?."
_38
},
_38
"twilio/quick-reply": {
_38
"body": "Hi, {{ 1 }}. \n Thanks for contacting Owl Air Support. How can I help?",
_38
"actions": [
_38
{
_38
"id": "flightid1",
_38
"title": "Check flight status"
_38
},
_38
{
_38
"id": "gateid1",
_38
"title": "Check gate number"
_38
},
_38
{
_38
"id": "agentid1",
_38
"title": "Speak with an agent"
_38
}
_38
]
_38
}
_38
},
_38
"links": {
_38
"approval_fetch": "https://content.twilio.com/v1/Content/HXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX/ApprovalRequests",
_38
"approval_create": "https://content.twilio.com/v1/Content/HXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX/ApprovalRequests/whatsapp"
_38
}
_38
}

Optional: Retrieve a Content Template SID from the Content Template Builder

optional-retrieve-a-content-template-sid-from-the-content-template-builder page anchor

You can make a GET request to the Content API to fetch a list of all the content templates that you have created.

GET API

Request:


_10
curl -X GET "https://content.twilio.com/v1/Content?PageSize=2" \
_10
-u $TWILIO_ACCOUNT_SID:$TWILIO_AUTH_TOKEN

Response:


_88
{
_88
"meta": {
_88
"page": 0,
_88
"page_size": 2,
_88
"first_page_url": "https://content.twilio.com/v1/Content?PageSize=2&Page=0",
_88
"previous_page_url": null,
_88
"url": "https://content.twilio.com/v1/Content?PageSize=2&Page=0",
_88
"next_page_url": "https://content.twilio.com/v1/Content?PageSize=2&Page=1&PageToken=PAHXXXXXXXXXXXX",
_88
"key": "contents"
_88
},
_88
"contents": [
_88
{
_88
"language": "en",
_88
"date_updated": "2023-03-07T14:46:13Z",
_88
"variables": {
_88
"1": "flight_number",
_88
"3": "departure_time",
_88
"2": "arrival_city",
_88
"5": "url_suffix",
_88
"4": "gate_number"
_88
},
_88
"friendly_name": "flight_departure_update",
_88
"account_sid": "ACXXXXXXXXXX",
_88
"url": "https://content.twilio.com/v1/Content/HXXXXXXXXXXXXX",
_88
"sid": "HXXXXXXXXXXXX",
_88
"date_created": "2023-03-07T14:46:13Z",
_88
"types": {
_88
"twilio/call-to-action": {
_88
"body": "Owl Air: We will see you soon! Flight {{ 1 }} to {{ 2 }} departs at {{ 3 }} from Gate {{ 4 }}.",
_88
"actions": [
_88
{
_88
"url": "https://owlair.com/{{ 5 }}",
_88
"type": "URL",
_88
"title": "Check Flight Status"
_88
},
_88
{
_88
"phone": "+18005551234",
_88
"type": "PHONE_NUMBER",
_88
"title": "Call Support"
_88
}
_88
]
_88
}
_88
},
_88
"links": {
_88
"approval_fetch": "https://content.twilio.com/v1/Content/HXXXXXXXXXXXX/ApprovalRequests",
_88
"approval_create": "https://content.twilio.com/v1/Content/HXXXXXXXXXXX/ApprovalRequests/whatsapp"
_88
}
_88
},
_88
{
_88
"language": "en",
_88
"date_updated": "2023-02-24T14:25:37Z",
_88
"variables": {
_88
"1": "name"
_88
},
_88
"friendly_name": "flight_replies",
_88
"account_sid": "ACXXXXXXXXXX",
_88
"url": "https://content.twilio.com/v1/Content/HXXXXXXXXXX",
_88
"sid": "HXXXXXXXXXXX",
_88
"date_created": "2023-02-24T14:25:37Z",
_88
"types": {
_88
"twilio/text": {
_88
"body": "Hi, {{ 1 }}. \n Thanks for contacting Owl Air Support. How can I help?."
_88
},
_88
"twilio/quick-reply": {
_88
"body": "Hi, {{ 1 }}. \n Thanks for contacting Owl Air Support. How can I help?",
_88
"actions": [
_88
{
_88
"id": "flightid1",
_88
"title": "Check flight status"
_88
},
_88
{
_88
"id": "gateid1",
_88
"title": "Check gate number"
_88
},
_88
{
_88
"id": "agentid1",
_88
"title": "Speak with an agent"
_88
}
_88
]
_88
}
_88
},
_88
"links": {
_88
"approval_fetch": "https://content.twilio.com/v1/Content/HXXXXXXXXXXX/ApprovalRequests",
_88
"approval_create": "https://content.twilio.com/v1/Content/HXXXXXXXXXXX/ApprovalRequests/whatsapp"
_88
}
_88
}
_88
]
_88
}


Step 2: Create a Conversation

step-2-create-a-conversation page anchor

Now, let's create a Conversation that we'll use in the next step to send a rich content message. In the sample code below, replace the Account SID and Auth Token with the values from your Twilio Console. Copy down the Conversation SID (It starts with CHXXXXX). We'll be using this value in the next step when we add a WhatsApp participant to the Conversation you just created.

POST API

Request:


_10
curl -X POST "https://conversations.twilio.com/v1/Conversations" \
_10
--data-urlencode "FriendlyName=Send Rich content messages with Conversations" \
_10
-u $TWILIO_ACCOUNT_SID:$TWILIO_AUTH_TOKEN

Response:


_20
{
_20
"unique_name": null,
_20
"date_updated": "2023-02-13T12:31:50Z",
_20
"friendly_name": "Send rich content messages with Conversations",
_20
"timers": {},
_20
"account_sid": "ACXXXXXXXXXXXXX",
_20
"url": "https://conversations.twilio.com/v1/Conversations/CHXXXXXXXXXXXX",
_20
"state": "active",
_20
"date_created": "2023-02-13T12:31:50Z",
_20
"messaging_service_sid": "MGXXXXXXXXXXXX",
_20
"sid": "CHXXXXXXXXXXXXX",
_20
"attributes": "{}",
_20
"bindings": null,
_20
"chat_service_sid": "ISXXXXXXXXXX",
_20
"links": {
_20
"participants": "https://conversations.twilio.com/v1/Conversations/CHXXXXXXXXX/Participants",
_20
"messages": "https://conversations.twilio.com/v1/Conversations/CHXXXXXXXXX/Messages",
_20
"webhooks": "https://conversations.twilio.com/v1/Conversations/CHXXXXXXXXXX/Webhooks"
_20
}
_20
}


Step 3: Add a WhatsApp Participant to the Conversation

step-3-add-a-whatsapp-participant-to-the-conversation page anchor

Let's add a WhatsApp Participant to the Conversation. For the code sample below, replace the placeholder values for:

  • CHXXXXXXX : use the Conversation SID you just copied
  • YOUR_WHATSAPP_NUMBER : your WhatsApp phone number, in E.164 format
  • TWI_WA_NUMBER : Your Twilio enabled WhatsApp phone number, in E.164 format
  • TWILIO_ACCOUNT_SID : Your Twilio Account SID
  • TWILIO_AUTH_TOKEN : Your Twilio Auth Token

POST API

Request:


_10
curl -X POST "https://conversations.twilio.com/v1/Conversations/CHxxxx/Participants" \
_10
--data-urlencode "MessagingBinding.Address=whatsapp:YOUR_WHATSAPP_NUMBER" \
_10
--data-urlencode "MessagingBinding.ProxyAddress=whatsapp:TWI_WA_NUMBER" \
_10
-u $TWILIO_ACCOUNT_SID:$TWILIO_AUTH_TOKEN

Response:


_18
{
_18
"last_read_message_index": null,
_18
"date_updated": "2023-02-17T16:45:32Z",
_18
"last_read_timestamp": null,
_18
"conversation_sid": "CHXXXXXXXXX",
_18
"account_sid": "ACXXXXXXXXXX",
_18
"url": "https://conversations.twilio.com/v1/Conversations/CHXXXXXXXXX/Participants/MBXXXXXXXXX",
_18
"date_created": "2023-02-17T16:45:32Z",
_18
"role_sid": "RLXXXXXXXXXX",
_18
"sid": "MBXXXXXXXXXXX",
_18
"attributes": "{}",
_18
"identity": null,
_18
"messaging_binding": {
_18
"proxy_address": "whatsapp:TWI_WA_NUMBER",
_18
"type": "whatsapp",
_18
"address": "whatsapp:YOUR_WHATSAPP_NUMBER"
_18
}
_18
}


Step 4: Send a Rich Message via the Conversations API

step-4-send-a-rich-message-via-the-conversations-api page anchor
(information)

Info

If the customer representative wants to send rich content messages prior to the end user messaging them on WhatsApp, then this content template will need to be approved before it can be sent out. Some content types (e.g., Cards and CTA buttons) require prior approval regardless of whether the template is sent in the context of a session or not.

So far you've created a content template, and a Conversation with a WhatsApp participant. Now we're ready to send a rich message to the participant. This example uses the Conversations API, but content templates are also available through the Conversations SDKs for JavaScript, Android, and iOS.

In our POST request example, you'll pass the ContentVariables parameter (optional), which allows you to customize the message content with dynamic values. For this example, "name" will be replaced with the value ("Alice").

Replace:

  • CHXXXXXXXXXXXXXXXXXXX with the Conversation SID in the request URL
  • HXXXXXXXXXXXXXXXXXXXX value in the Content SID parameter

Request parameters:

ParameterRequiredDescription
ContentSidYesThe unique ID of the multi-channel Content template, required for template-generated message. Note that if this field is set, the Body and MediaSid parameters are ignored.
ContentVariablesOptionalA structurally valid JSON string that contains values to determine Content template variables.

POST API

Request:


_10
curl -X POST "https://conversations.twilio.com/v1/Conversations/CHXXXXXXXXXXXXXXXXXXX/Messages" \
_10
--data-urlencode 'ContentSid=HXXXXXXXXXXXXXXXXXXXX' \
_10
--data-urlencode 'ContentVariables={ "1": "Alice" }' \
_10
-u $TWILIO_ACCOUNT_SID:$TWILIO_AUTH_TOKEN

Response:


_19
{
_19
"body": "Hi, Alice. \n Thanks for contacting Owl Air Support. How can I help?",
_19
"index": 0,
_19
"author": "system",
_19
"date_updated": "2023-02-09T17:44:30Z",
_19
"media": null,
_19
"participant_sid": null,
_19
"conversation_sid": "CHXXXXXXXXXXXXXXXXXXX",
_19
"account_sid": "ACXXXXXXXXXXXXXXXXXXX",
_19
"delivery": null,
_19
"url": "https://conversations.twilio.com/v1/Conversations/CHXXXXXXXXXXXXXXXXXXX0/Messages/IMXXXXXXXXXXXXXXXXXXX",
_19
"date_created": "2023-02-09T17:44:30Z",
_19
"content_sid": "HXXXXXXXXXXXXXXXXXXXX",
_19
"sid": "IMXXXXXXXXXXXXXXXXXXX",
_19
"attributes": "{}",
_19
"links": {
_19
"delivery_receipts": "https://conversations.twilio.com/v1/Conversations/CHXXXXXXXXXXXXXXXXXXX/Messages/IMXXXXXXXXXXXXXXXXXXX/Receipts"
_19
}
_19
}

WhatsApp Conversation screenshot showing interactive elements in the form of buttons.

Well done! You've successfully sent your first rich content message to your WhatsApp Participant using Twilio Conversations.


As a following step, you can:


Rate this page: