×

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:

  • Log in to the Meta dashboard and select your WhatsApp Business Manager account where you intend to create the Flow JSON.
  • In the left-side menu, go to the Flows section under Account Tools.
  • Click on the Create Flow button or Start Building Flows. Follow the steps mentioned here to create your JSON Flow under Option 2: Using Flows Builder under the Account Tools section in the Create Flow section  - WhatsApp Flows Integration Guide.

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:

POST

https://<your_api_key>:<your_api_token><subdomain>/v2/accounts/<your_sid>/messages

  • Replace <your_api_key> and <your_api_token> with the API key and token created by you.
  • Replace <your_sid> with your “Account sid".
  • Replace <subdomain> with the region of your account
    1. <subdomain> of Singapore cluster is @api.exotel.com
    2. <subdomain> of Mumbai cluster is @api.in.exotel.com

<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.

whatsapp

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.

Channel Object

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 

Message Object

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

Whatsapp Message Object

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.
For Cloud API, Static third-party outbound stickers are supported in addition to all types of inbound stickers. A static sticker needs to be 512x512 pixels and cannot exceed 100 KB. An animated sticker must be 512x512 pixels and cannot exceed 500 KB.

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.

Text Object

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

Image Object

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.

Audio Object

Parameter Name

Parameter Type

Mandatory/Optional

Value

link

String

Mandatory

Link of the audio to be sent. Use only with HTTP/HTTPS URLs.

Video Object

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.

Document Object

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.

Interactive Object

Parameter Name

Parameter Type

Mandatory/Optional

Value

type

String

Optional

The type of interactive message you want to send. Set this to:

  • flow: Use it for Flow Messages.

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.

Header Object

Parameter Name

Parameter Type

Mandatory/Optional

Value

type

String

Mandatory

The header type you would like to use. Supported values:


  • text: Used for List Messages, Reply Buttons
  • video: Used for Reply Buttons.
  • image: Used for Reply Buttons.
  • document: Used for Reply Buttons.

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.

Body Object

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.

Footer Object

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.

Action Object

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:

  • On success, the HTTP response status code will be 202
  • The Sid is the unique identifier of the message and it will be useful to log this for future debugging
  • the HTTP body will contain a JSON similar to the one below
{
   "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

Metadata Object

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)

Response Object

Parameter

Type

Mandatory/Optional

Notes

whatsapp

Channel Response Object

Mandatory

Response for Whatsapp messages specified in the request

Channel Response Object

Parameter

Type

Mandatory/Optional

Notes

messages

[]Create Message Response Object

Mandatory

Array of messages response for each message

Create Message Response Object

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

Error Response Object

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

Message Response Object

Parameter

Type

Mandatory/Optional

Notes

sid

String

Mandatory

SID (Unique identifier) of the single message

HTTP Error codes : 

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 Callbacks 

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.

  • If you pass the status callback URL in send message/template message APIs, status callbacks will be triggered to the respective URL 
  • If you do not pass any status callback URL in send message/template message APIs, status callbacks will be triggered to the default URL, if any.

*NOTE: Any callback can be received only in one status callback URL at any time.

What is different for Flow Template?

  • The sent message with the Flow button will have the same delivery callbacks as another type of message.
  • But the incoming message callback is different than the other types of WhatsApp messages, please check the Receive Whatsapp Messages section to find the callback sample for the Flow messages.
 
 "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"
       }
     ]
   }
 }