Please understand that this feature is currently in Beta and it’s important to note that certain capabilities, such as Reports and Analytics are not yet available on the dashboard. We will be working on this and is part of our next phase launch.
You can now send a Message with a Flow in a user-initiated conversation as a free-form message with a Call To Action (CTA) using the Exotel APIs.
Before you start sending the Message with a Flow button, you need to create and publish the Flow JSON. Follow the below steps:
Note: Currently, the creation of templates with flows via API or on the Exotel dashboard is not supported. We plan to enable this feature soon. Until then, create the JSON Flows using the WhatsApp Manager on the Meta dashboard.
To send messages to a single number with configured Flow button content via Exotel API, make an HTTP POST request to:
https://<your_api_key>:<your_api_token><subdomain>/v2/accounts/<your_sid>/messages
<your_api_key>
and <your_api_token>
with the API key and token created by you.<your_sid>
with your “Account sid".<subdomain>
with the region of your account
<your_api_key>
, <your_api_token>
and <your_sid>
are available in the API settings page of your Exotel Dashboard
The following are the POST parameters -
Parameter Name |
Parameter Type |
Mandatory/Optional |
Value |
custom_data |
String |
Optional |
This parameter can be used to send any custom data at the API request level. This will be passed back in the callback. |
status_callback |
String (URL) |
Optional |
Once the message reaches terminal state, Exotel will do a POST callback to your end point if the URL is set as a parameter in the API. |
|
Channel Object |
Optional |
Information related to the messages to be sent out on whatsapp. |
* The Whatsapp parameter mentioned here will be used to send messages through the Whatsapp communication channel. In future, the API will be extended further to support other communication channels like SMS. Later, the SMS parameter can also be passed to send SMSes.
Parameter Name |
Parameter Type |
Mandatory/Optional |
Value |
custom_data |
String |
Optional |
This parameter can be used to send any custom data at the API request level. This will be passed back in the callback. |
status_callback |
String (URL) |
Optional |
Once the message reaches the terminal state, Exotel will do a POST callback to your endpoint if the URL is set as a parameter in the API. |
messages |
[]Message Object |
Mandatory |
An array of messages to be sent out |
Parameter Name |
Parameter Type |
Mandatory/Optional |
Value |
custom_data |
String |
Optional |
This parameter can be used to send any custom data at the API request level. This will be passed back in the callback. |
status_callback |
String (URL) |
Optional |
Once the message reaches the terminal state, Exotel will do a POST callback to your endpoint if the URL is set as a parameter in the API. |
from |
String |
Mandatory |
From number from which the message has to be sent |
to |
String |
Mandatory |
Phone number of the user to whom a message needs to be sent. The number must be in e.164 format. Here are some examples of supported phone number formats: "+10000000000" "+919888888888" "+919876543210" |
content |
Whatsapp Message Object |
Mandatory |
Whatsapp message body |
This will be similar to Whatsapp Native API contracts [Refer Here]:
Parameter Name |
Parameter Type |
Mandatory/ Optional |
Value |
recepient_type |
String |
Mandatory |
Recipient type of the user to whom the message is being sent. Currently, you can only send messages to individuals. Set this as an individual. Default: individual |
type |
String |
Mandatory |
Type of the message. Type can be - Text, Image, Audio, Video, Document, Sticker, Location, Contact Interactive - This is for List Messages, Reply Buttons, Flows |
text |
Text Object |
Mandatory/Optional |
Mandatory when type is text. To send a text message attach a WhatsappMessageObject with type = text and then add a text object |
image |
Image Object |
Mandatory/Optional |
Mandatory when the type is an image. To send an image attach a WhatsappMessageObject with type = image and then add an image object |
audio |
Audio Object |
Mandatory/Optional |
Mandatory when the type is audio. To send audio attach a WhatsappMessageObject with type = audio and then add an audio object |
video |
Video Object |
Mandatory/Optional |
Mandatory when type is video. To send a video attach a WhatsappMessageObject with type = video and then add a video object |
document |
Document Object |
Mandatory/Optional |
Mandatory when type is a document. To send a sticker attach a WhatsappMessageObject with type = document and then add a document object |
sticker |
Sticker Object |
Mandatory/Optional |
Mandatory when the type is a sticker. To send a sticker attach a WhatsappMessageObject with type = sticker and then add a sticker object. The type of file should be image/webp. |
location |
Location Object |
Mandatory/Optional |
Mandatory when type is location. To send a location message attach a WhatsappMessageObject with type = location and then add a location object |
contacts |
Contact Object |
Mandatory/Optional |
Mandatory when type is contacts. To send a contact message attach a WhatsappMessageObject with type = contact and then add a contacts object |
interactive |
Interactive Object |
Mandatory/Optional |
Mandatory when type is interactive. To send interactive messages attach a WhatsappMessageObject with type = interactive and then add an interactive object. The components of each interactive object generally follow a consistent pattern: header, body, footer, and action. |
Parameter Name |
Parameter Type |
Mandatory/Optional |
Value |
body |
String |
Mandatory |
The text of the text message can contain URLs that begin with http:// or https:// and formatting. If you include URLs in your text and want to include a preview box in text messages (preview_url: true), make sure the URL starts with http:// or https:// —https:// URLs are preferred. You must include a hostname since IP addresses will not be matched. Maximum length: 4096 characters. |
preview_url |
Boolean |
Optional |
Set preview_url as ‘Yes’ only if the body includes a URL that begins with https:// or http:// and you want to preview the URL Set preview_url as ‘No’ if you do not want to preview the URL |
Parameter Name |
Parameter Type |
Mandatory/Optional |
Value |
link |
String |
Mandatory |
Link of the image to be sent. Use only with HTTP/HTTPS URLs. |
caption |
String |
Optional |
Caption for the image. Describes the specified image. |
Parameter Name |
Parameter Type |
Mandatory/Optional |
Value |
link |
String |
Mandatory |
Link of the audio to be sent. Use only with HTTP/HTTPS URLs. |
Parameter Name |
Parameter Type |
Mandatory/Optional |
Value |
link |
String |
Mandatory |
Link of the video to be sent. Use only with HTTP/HTTPS URLs. |
caption |
String |
Optional |
Caption for the video. Describes the specified video media. |
Parameter Name |
Parameter Type |
Mandatory/Optional |
Value |
link |
String |
Mandatory |
Link of the document to be sent. Use only with HTTP/HTTPS URLs. |
caption |
String |
Optional |
Caption for the document. Describes the specified document media. |
filename |
String |
Optional |
Describes the filename for the specific document. Use only document media. The extension of the filename will specify what format the document is displayed in WhatsApp. |
Parameter Name |
Parameter Type |
Mandatory/Optional |
Value |
type |
String |
Optional |
The type of interactive message you want to send. Set this to:
|
header |
Header Object |
Optional |
Header content displayed on top of a message. |
body |
Body Object |
Mandatory/Optional |
Optional for type product. Required for other message types. |
footer |
Footer Object |
Optional |
Footer of the interactive message |
action |
Action Object |
Optional |
Action you want the user to perform after reading the message. |
Parameter Name |
Parameter Type |
Mandatory/Optional |
Value |
type |
String |
Mandatory |
The header type you would like to use. Supported values:
|
text |
String |
Mandatory/Optional |
Required if header type is set to text. Text for the header. Formatting allows emojis, but not markdown. Maximum length: 60 characters. |
image |
Image Object |
Mandatory/Optional |
Required if header type is set to image. |
video |
Video Object |
Mandatory/Optional |
Required if header type is set to video. |
document |
Document Object |
Mandatory/Optional |
Required if header type is set to document. |
Parameter Name |
Parameter Type |
Mandatory/Optional |
Value |
text |
String |
Mandatory |
Required if body is present. The content of the message. Emojis and markdown are supported. Maximum length: 1024 characters. |
Parameter Name |
Parameter Type |
Mandatory/Optional |
Value |
text |
String |
Mandatory |
Required if the footer is present. The footer content. Emojis, markdowns, and links are supported. Maximum length: 60 characters. |
Parameter Name |
Parameter Type |
Mandatory/Optional |
Value |
name | String | Mandatory | Value must be "flow". |
mode | String | Mandatory | The Flow can be in either draft or published mode. (Default value: published) |
flow_message_version | String | Mandatory | Value must be "3". |
flow_token | String | Mandatory | Flow token that is generated by the business to serve as an identifier. You can get this from the Meta Dashboard for the JSON Flow by clicking on the "Manage" button on the right hand side. |
flow_id | String | Mandatory |
Unique ID of the Flow provided by WhatsApp on the Meta Dashboard under the Flows section.
|
flow_cta | String | Mandatory | Text on the CTA button. For example: "Signup" Character limit - 20 characters (no emoji). |
flow_action | String | Mandatory | navigate or data_exchange (Default value: navigate) |
flow_action_payload | String | Mandatory | Required if flow_action is navigate. Should be omitted otherwise. |
screen | String | Mandatory | The ID of the first Screen. You can get the Screen Name from the Meta Dashboard for the right-hand side preview page. |
data | Object | Optional | Optional input data for the first Screen of the Flow. If provided, this must be a non-empty object. |
Please refer to Exotel's sample Postman collection to try out the APIs, we have also shared some examples here for your reference.
curl --location 'https://0677f84029ded8bae022bc115c1c4e05dc75360595feb7dc:8e0342b396bc14a2881c9abb1e686ad91373b8dd5835fe74@api.exotel.com/v2/accounts/Exotel/messages' \ --header 'Content-Type: application/json' \ --data '{ "custom_data": "ORDXXXXXXX", "status_callback": "https://webhook.site", "whatsapp": { "messages": [ { "from": "91804XXXXXX", "to": "{{ToNumber}}", "content": { "type": "interactive", "interactive": { "type": "flow", "header": { "type": "text", "text": "Flow message header" }, "body": { "text": "Flow message body" }, "footer": { "text": "Flow message footer" }, "action": { "name": "flow", "parameters": { "flow_message_version": "3", "flow_id": "1323XXXXXXXXX", "flow_token": "flows-builder-97XXXXX", "flow_cta": "Click Here", "flow_action": "navigate", "flow_action_payload": { "screen": "screen_name", "data": { "product_name": "test", "product_description": "test", "product_price": 1 } } } } } } } ] } }'
import requests
import json
url = “https://{{AuthKey}}:{{AuthToken}}@{{SubDomain}}/v2/accounts/{{AccountSid}}/messages”
payload = json.dumps({
“custom_data”: “ORDXXXXXXX”,
“status_callback”: “https://webhook.site”,
“whatsapp”: {
“messages”: [
{
“from”: “{{FromNumber}}”,
“to”: “{{ToNumber}}”,
“content”: {
“type”: “interactive”,
“interactive”: {
“type”: “flow”,
“header”: {
“type”: “text”,
“text”: “Flow message header”
},
“body”: {
“text”: “Flow message body”
},
“footer”: {
“text”: “Flow message footer”
},
“action”: {
“name”: “flow”,
“parameters”: {
“flow_message_version”: “3”,
“flow_id”: “1323XXXXXXXXX”,
“flow_token”: “flows-builder-97XXXXX”,
“flow_cta”: “Click Here”,
“flow_action”: “navigate”,
“flow_action_payload”: {
“screen”: “screen_name”,
“data”: {
“product_name”: “test”,
“product_description”: “test”,
“product_price”: 1
}
}
}
}
}
}
}
]
}
})
headers = {
‘Content-Type’: ‘application/json’
}
response = requests.request(“POST”, url, headers=headers, data=payload)
print(response.text)
HTTP Response:
{ "request_id": "b434e927a5844175b23059cd96feea3d", "method": "POST", "http_code": 202, "metadata": { "failed": 0, "total": 1, "success": 1 }, "response": { "whatsapp": { "messages": [ { "code": 202, "error_data": null, "status": "success", "data": { "sid": "2FdiXXXXXXXXXXXXXXXXX", } } ] } } }
The following are the response parameters -
Parameter |
Type |
Mandatory/Optional |
Notes |
request_id |
String |
Mandatory |
This indicates the unique id of the request. Useful for debugging and tracing purposes. |
method |
String |
Mandatory |
This indicates the HTTP method for the request such as POST |
http_code |
Integer |
Mandatory |
This indicates the HTTP code for the request such as 202, 400, 500 etc. |
metadata |
Metadata Object |
Mandatory |
Metadata pertaining to the request. Count of failed, total and success records. |
response |
Response Object |
Mandatory |
Response for the request |
Parameter |
Type |
Mandatory/Optional |
Notes |
total |
Integer |
Mandatory |
Total number of the messages in the request |
success |
Integer |
Mandatory |
Number of messages successfully accepted |
failed |
Integer |
Mandatory |
Number of messages that couldn’t be accepted (failed) |
Parameter |
Type |
Mandatory/Optional |
Notes |
|
Channel Response Object |
Mandatory |
Response for Whatsapp messages specified in the request |
Parameter |
Type |
Mandatory/Optional |
Notes |
messages |
[]Create Message Response Object |
Mandatory |
Array of messages response for each message |
Parameter |
Type |
Mandatory/Optional |
Notes |
code |
Integer |
Mandatory |
Response code for the individual message |
error_data |
Error Response Object |
Optional |
Error related to a single message |
status |
String |
Mandatory |
Status of the single message |
data |
Message Response Object |
Optional |
Data pertaining to a single message |
Parameter |
Type |
Mandatory/Optional |
Notes |
code |
Numeric |
Mandatory |
Numeric HTTP code for a Single message |
message |
String |
Mandatory |
Brief description of the error |
description |
String |
Mandatory |
Detailed explanation of error |
Parameter |
Type |
Mandatory/Optional |
Notes |
sid |
String |
Mandatory |
SID (Unique identifier) of the single message |
HTTP Error Codes |
Error Message |
202 |
Accepted - Request accepted. |
400 |
Bad Request - Something in your header or request body was malformed/missing. More than 100 messages specified in a request |
401 |
Unauthorized - Necessary credentials were either missing or invalid. |
402 |
Payment Required - The action is not available on your plan, or you have exceeded usage limits for your current plan. |
403 |
Your credentials are valid, but you don’t have access to the requested resource. |
404 |
Not Found - The object you’re requesting doesn’t exist. |
5xx |
Server Errors - Something went wrong at our end. Please try again. |
Status callback URL can be passed in the status_callback parameter in send message APIs and it can also be configured as default to receive the responses. The Exotel team will help you configure the default URL while onboarding.
*NOTE: Any callback can be received only in one status callback URL at any time.
What is different for Flow Template?
"whatsapp": { "messages": [ { "callback_type": "dlr", "sid": "1234", "to": "23XXXXXXX", "exo_status_code": 25001, "exo_detailed_status": "EX_MESSAGE_DELIVERED", "description": "Message delivered", "timestamp": "2022-12-07T17:00:00.000+05:30", "custom_data": "custom" } ] } }