×

You can now send the Template message with the Flow button using the Exotel APIs. To start sending the Template message with the Flow button, you need to follow the below steps:

  • Log in to the Meta dashboard and select your WhatsApp Business Manager account where you intend to create the template.
  • In the left-side menu, go to the Templates section under Account Tools.
  • Click on the Create Template button. Choose the Marketing category and select Form as the sub-category.
  • Click on the Create button under the Buttons section. This action opens the Meta Flow Form Builder UI. Design the required form and submit the template for approval.

To send messages to a single number with configured Template message 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 on 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 the terminal state, Exotel will do a POST callback to your endpoint 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 the 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.

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

Parameter Name

Parameter Type

Mandatory/ Optional

Value

template

Template Object

Mandatory/
Optional

Mandatory when type is template

Template Object

Parameter

Type

Mandatory/ Optional

Value

namespace

String

Mandatory

The namespace of the template

name

String

Mandatory

Name of the template

language

Language Object

Mandatory

Specifies the language the template may be rendered in.

components

[]Component Object

Mandatory

Components of the template, containing the parameters of the message.

Language Object

Parameter

Type

Mandatory/ Optional

Value

policy

String

Mandatory

The language policy the message should follow. The only supported option is deterministic. 

code

String

Mandatory

The code of the language or locale to use. Accepts both language and language_locale formats (e.g., en and en_US).

Component Object

Parameter

Type

Mandatory/ Optional

Value

type

String

Mandatory

Type of the component. Supported types are - 

Header

Body

Button

text

String

Optional

Text for the component 

sub_type

String

Mandatory

Required when type=button. Not used for the other types.

Type of button to create - 

form: Set this to 'form' for sending the template message with the flow button.  

quick_reply & url.

index

String

Mandatory/ Optional

Required when type=button. Not used for the other types. Position the index of the button. You can have up to 3 buttons using index values of 0 to 2.

footer

String

Optional

The footer of the component

parameters

[]Parameter Object

Mandatory/ Optional

Required when type=button.

An array of parameter objects with the content of the message.


Parameter Object

Parameter

Type

Mandatory/ Optional

Value

type

String

Mandatory

Type of the parameter. Describes the parameter type. Supported values:

action: Set this to 'action' for sending the template message with the flow button.

action (object)

String

Mandatory

Required when type is 'action'

flow_token

String

Optional

flow_token: 0000, default is "unused".
You do not generate a flow token on the Meta dashboard for a Flow created via  Template, so you can pass 0000 for a template with a flow message.

flow_action_data

String

Optional

flow_action_data optional, JSON object with the data payload for the first screen

 

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://{{AuthKey}}:{{AuthToken}}@{{SubDomain}}/v2/accounts/{{AccountSid}}/messages' \
--header 'Content-Type: application/json' \
--data '{
  "custom_data": "ORXXXXXXX",
  "status_callback": "https://webhook.site",
  "whatsapp": {
    "messages": [
      {
        "from": "+911XXXXXXXX",
        "to": "+9199XXXXXXXX",
        "content": {
          "type": "template",
          "template": {
            "name": "flow_template",
            "language": {
              "code": "en_US"
            },
            "components": [
              {
                "type": "button",
                "sub_type": "flow",
                "index": "0",
                "parameters": [
                  {
                    "type": "action",
                    "action": {
                      "flow_token": "0000",
                      "flow_action_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": "ORXXXXXXX",
"status_callback": "https://webhook.site",
"whatsapp": {
"messages": [
{
"from": "+911XXXXXXXX",
"to": "+9199XXXXXXXX",
"content": {
"type": "template",
"template": {
"name": "flow_template",
"language": {
"code": "en_US"
},
"components": [
{
"type": "button",
"sub_type": "flow",
"index": "0",
"parameters": [
{
"type": "action",
"action": {
"flow_token": "0000",
"flow_action_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)
curl --location --globoff 'https://{{AuthKey}}:{{AuthToken}}@{{SubDomain}}/v2/accounts/{{AccountSid}}/messages' \
--header 'Content-Type: application/json' \
--data '{
    "custom_data": "ORDXXXXX",
    "status_callback": "https://webhook.site",
    "whatsapp": {
        "messages": [
            {
                "from": "{{FromNumber}}",
                "to": "{{ToNumber}}",
                "content": {
                    "type": "template",
                    "template": {
                        "name": "template_flow_text_header",
                        "language": {
                            "code": "en"
                        },
                        "components": [
                            {
                                "type": "header",
                                "parameters": [
                                    {
                                        "type": "text",
                                        "text": "Exotel"
                                    }
                                ]
                            },
                            {
                                "type": "body",
                                "parameters": [
                                    {
                                        "type": "text",
                                        "text": "John"
                                    }
                                ]
                            },
                            {
                                "type": "button",
                                "sub_type": "flow",
                                "index": "0",
                                "parameters": [
                                    {
                                        "type": "action",
                                        "action": {
                                            "flow_token": "0000",
                                            "flow_action_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": "ORDER123456",
"status_callback": "https://webhook.site",
"whatsapp": {
"messages": [
{
"from": "{{FromNumber}}",
"to": "{{ToNumber}}",
"content": {
"type": "template",
"template": {
"name": "template_flow_text_header",
"language": {
"code": "en",
"policy": "deterministic"  //Only for On-Premise APIs
},
"components": [
{
"type": "header",
"parameters": [
{
"type": "text",
"text": "Exotel"
}
]
},
{
"type": "body",
"parameters": [
{
"type": "text",
"text": "Javed"
}
]
},
{
"type": "button",
"sub_type": "flow",
"index": "0",
"parameters": [
{
"type": "action",
"action": {
"flow_token": "0000",
"flow_action_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)
curl --location --globoff 'https://{{AuthKey}}:{{AuthToken}}@{{SubDomain}}/v2/accounts/{{AccountSid}}/messages' \
--header 'Content-Type: application/json' \
--data '{
    "custom_data": "ORDXXXXX",
    "status_callback": "https://webhook.site",
    "whatsapp": {
        "messages": [
            {
                "from": "{{FromNumber}}",
                "to": "{{ToNumber}}",
                "content": {
                    "type": "template",
                    "template": {
                        "name": "flow_template_header_image",
                        "language": {
                            "code": "en"
                        },
                        "components": [
                            {
                                "type": "header",
                                "parameters": [
                                    {
                                        "type": "image",
                                        "image": {
                                            "link": "https://image.shutterstock.com/image-photo/happy-XXXXXXXXX.jpg"
                                        }
                                    }
                                ]
                            },
                            {
                                "type": "body",
                                "parameters": [
                                    {
                                        "type": "text",
                                        "text": "John"
                                    }
                                ]
                            },
                            {
                                "type": "button",
                                "sub_type": "flow",
                                "index": "0",
                                "parameters": [
                                    {
                                        "type": "action",
                                        "action": {
                                            "flow_token": "0000",
                                            "flow_action_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": "ORDXXXXX",
"status_callback": "https://webhook.site",
"whatsapp": {
"messages": [
{
"from": "{{FromNumber}}",
"to": "{{ToNumber}}",
"content": {
"type": "template",
"template": {
"name": "flow_template_header_image",
"language": {
"policy": "deterministic",  //Only for On-Premise APIs
"code": "en"
},
"components": [
{
"type": "header",
"parameters": [
{
"type": "image",
"image": {
"link": "https://image.shutterstock.com/image-photo/happy-puppy-dog-smiling-on-260nw-1799966587.jpg"
}
}
]
},
{
"type": "body",
"parameters": [
{
"type": "text",
"text": "Javed"
}
]
},
{
"type": "button",
"sub_type": "flow",
"index": "0",
"parameters": [
{
"type": "action",
"action": {
"flow_token": "0000",
"flow_action_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": "210bd1cda8004a2e913eac7a580eb159",
"method": "POST",
"http_code": 202,
"metadata": {
"failed": 0,
"total": 1,
"success": 1
},
"response": {
"whatsapp": {
"messages": [
{
"code": 202,
"error_data": null,
"status": "success",
"data": {
"sid": "f65047444e5c782a56f76f40e06717b9"
}
}
]
}
}
}

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

ErrorResponseObject

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/template 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 Template message with the Flow button will have the same delivery callbacks as another type of Template message.
  • But the incoming message callback is different than the other types of WhatsApp messages after the end-user fills and submits the Form on WhatsApp, please check the Receive Whatsapp Messages section to find the callback sample for the Flow messages.
 "whatsapp": {
     "messages": [
       {
   "callback_type": "dlr",
         "sid": "1234XXXXX",
         "to": "2365XXXXXX",
         "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"
       }
     ]
   }
 }