Flows is an in-app, multi-screen experience available in WhatsApp. Flows can be sent as part of an approved content template. A business's end users can initiate a flow experience using a Flow button. Initiating a flow opens an in-app, multi-screen experience where businesses can add text, images, and solicit user input in multiple ways. Businesses can capture end user input via single-choice, multi-choice, toggles, short-text answers, long-text answers, and date pickers. You can organize these options in up to 10 screens.
Flows isn't designed to transmit HIPAA Eligible Service or PCI data and should not be used to transmit data in workflows that are subject to HIPAA or PCI compliance.
If you are transmitting sensitive information, use Message Redaction. Message Redaction isn't yet compatible with Studio, Proxy Service, and Functions. Don't send Flows containing sensitive information using these products and services because Message Redaction doesn't work with them.
![]() | ![]() |
---|
To create a flow, follow these steps:
twilio/flows
content template.UTILITY
or MARKETING
) depending on the content of the flow and the message.twilio/flows
content template publishes the flow to WhatsApp. You can find the publishing status in the content template approvals. Currently, using flows without an approved content template isn't supported.Parameter | Type | Required | Variable support | Description |
---|---|---|---|---|
body | string | Yes | Yes | Text of the templated message delivering the flow. Maximum length: 1,024 characters |
subtitle | string | No | No | Footer of the message. Maximum length: 1,024 characters |
media_url | string | No | No | Controls media on the initial flow message. |
type | enum | Yes | No | Possible flow category values:
|
button_text | string | Yes | No | Controls the text of the button that initiates the flow. |
pages | array | Yes | No | Contains the definitions of each page's components. Up to 10 pages. |
Property | Type | Required | Variable support | Description |
---|---|---|---|---|
id | string | No | No | Identifier returned in the webhook. Maximum length: 20 characters |
title | string | No | No | Title text appearing above the flow page. |
subtitle | string | No | No | Subtitle text appearing within the flow page at the top of the page. |
layout | array | Yes | No | Questions asked within the flow page. Contains one of the following components:
|
SHORT_TEXT
object
Property | Required | Type | Variable support | Description |
---|---|---|---|---|
type | Yes | enum | No | Set to SHORT_TEXT . Maximum length: 80 characters |
text | Yes | string | Yes | Helper text. |
label | Yes | string | Yes | Question being asked. |
required | No | Boolean | No | Set to false by default. Whether the end user needs to answer the question |
input_type | No | enum | No | Set to text by default. Must be one of the following:
|
LONG_TEXT
object
Property | Required | Type | Variable support | Description |
---|---|---|---|---|
type | Yes | enum | No | Set to LONG_TEXT . Maximum length: 600 characters |
text | Yes | string | Yes | Helper text. |
label | Yes | string | Yes | Question being asked. |
required | No | Boolean | No | Set to false by default. Whether the end user needs to answer the question |
SINGLE_SELECT
object
Property | Required | Type | Variable support | Description |
---|---|---|---|---|
type | Yes | enum | No | Set to SINGLE_SELECT . |
text | Yes | string | Yes | Helper text. |
label | Yes | string | Yes | Question being asked. |
options | Yes | string | Yes | Stringified array of title and id. If variable is used must replace whole string with variable. Example: "options": "[{\"id\":\"ff\",\"title\":\"Friends and family\"},{\"id\":\"oo\",\"title\":\"Online\"},{\"id\":\"ip\",\"title\":\"In person\"}]" |
options.title | Yes | string | Yes | Can be variable if options is variable. Display title of option. |
options.id | Yes | string | Yes | Can be variable if options is variable. Id of option returned in webhook. |
MULTI_SELECT
object
Property | Required | Type | Variable support | Description |
---|---|---|---|---|
type | Yes | enum | No | Set to MULTI_SELECT . |
text | Yes | string | Yes | Helper text |
label | Yes | string | Yes | Question being asked |
options | Yes | string | Yes | Stringified array of title and id. If variable is used must replace whole string with variable. Example: "options": "[{\"id\":\"ff\",\"title\":\"Friends and family\"},{\"id\":\"oo\",\"title\":\"Online\"},{\"id\":\"ip\",\"title\":\"In person\"}]" |
options.title | Yes | string | Yes | Can be variable if options is variable. Display title of option. |
options.id | Yes | string | Yes | Can be variable if options is variable. Id of option returned in webhook. |
DATE_PICKER
object
Property | Required | Type | Variable support | Description |
---|---|---|---|---|
type | Yes | enum | No | Set to DATE_PICKER |
label | Yes | string | Yes | Question being asked. |
min_date | Yes | string | Yes | Start date. Format: YYYY-MM-DD |
max_date | Yes | string | Yes | End date. Format: YYYY-MM-DD |
unavailable_dates | Yes | string | Yes | Stringified array of unavailable dates. Format of dates: YYYY-MM-DD . Example: "unavailable_dates": "['\''2024-12-12'\'','\''2024-11-30'\'']" |
name | No | string | Yes | Name of date picker object. |
LIST
object
Property | Required | Type | Variable support | Description |
---|---|---|---|---|
type | Yes | enum | No | Set to LIST . |
label | Yes | string | Yes | Question being asked |
options | Yes | string | Yes | Stringified array of title and id. If variable is used must replace whole string with variable. Example: "options": "[{\"id\":\"ff\",\"title\":\"Friends and family\"},{\"id\":\"oo\",\"title\":\"Online\"},{\"id\":\"ip\",\"title\":\"In person\"}]" |
options.title | Yes | string | Yes | Can be variable if options is variable. Display title of option. |
options.id | Yes | string | Yes | Can be variable if options is variable. Id of option returned in webhook. |
TEXT_HEADING
object
Property | Required | Type | Variable support | Description |
---|---|---|---|---|
type | Yes | enum | No | Set to TEXT_HEADING . |
text | Yes | string | Yes | Markdown formatted text. Can enable text formatting, including hyperlinks, and all other functions described in the WhatsApp Components syntax cheat sheet. |
TEXT_SUBHEADING
object
Property | Required | Type | Variable support | Description |
---|---|---|---|---|
type | Yes | enum | No | Set to TEXT_SUBHEADING . |
text | Yes | string | Yes | Markdown formatted text. Can enable text formatting, including hyperlinks, and all other functions described in the WhatsApp Components syntax cheat sheet. |
TEXT_BODY
object
Property | Required | Type | Variable support | Description |
---|---|---|---|---|
type | Yes | enum | No | Set to TEXT_BODY . |
text | Yes | string | Yes | Markdown formatted text. Can enable text formatting, including hyperlinks, and all other functions described in the WhatsApp Components syntax cheat sheet. |
TEXT_CAPTION
object
Property | Required | Type | Variable support | Description |
---|---|---|---|---|
type | Yes | enum | No | Set to TEXT_CAPTION . |
text | Yes | string | Yes | Markdown formatted text. Can enable text formatting, including hyperlinks, and all other functions described in the WhatsApp Components syntax cheat sheet. |
RICH_TEXT
object
Property | Required | Type | Variable support | Description |
---|---|---|---|---|
type | Yes | enum | No | Set to TEXT_CAPTION . |
text_list | Yes | array | Yes | Array of strings. Markdown formatted text. Can enable text formatting, including hyperlinks, and all other functions described in the WhatsApp Components syntax cheat sheet. |
MEDIA
object
Property | Required | Type | Variable support | Description |
---|---|---|---|---|
type | Yes | enum | No | Set to MEDIA . |
url | Yes | string | Yes | Image within layout |
FOOTER
object
Property | Required | Type | Variable support | Description |
---|---|---|---|---|
type | Yes | enum | No | Set to FOOTER . |
label | Yes | string | Yes | What is displayed in the button to continue the flow. |
1curl -X POST 'https://content.twilio.com/v1/Content' \2-H 'Content-Type: application/json' \3-u $TWILIO_ACCOUNT_SID:$TWILIO_AUTH_TOKEN \4-d '{5"friendly_name": "info_flow",6"language": "en",7"types": {8"twilio/flows": {9"body": "Wow do we have something super cool for you! Thanks for your interest. we have a helpful link there too.",10"button_text": "See flow",11"subtitle": "Finish flow",12"pages": [13{14"id": "id_one",15"next_page_id": "id_two",16"title": "Page 1",17"layout": [18{19"label": "Name",20"type": "SHORT_TEXT",21"text": "Question 1",22"required": true23},24{25"label": "Email",26"type": "SHORT_TEXT",27"text": "Question 2",28"input_type": "EMAIL"29},30{31"label": "Address",32"type": "LONG_TEXT",33"text": "Question 3"34}35]36},37{38"id": "id_two",39"next_page_id": null,40"title": "Page 2",41"subtitle": "Subtitle of Page 2",42"layout": [43{44"label": "How did you find us?",45"type": "SINGLE_SELECT",46"options": "[{\"id\":\"ff\",\"title\":\"Friends and family\"},{\"id\":\"oo\",\"title\":\"Online\"},{\"id\":\"ip\",\"title\":\"In person\"}]"47},48{49"label": "What is your favorite number?",50"type": "MULTIPLE_SELECT",51"options": "[{\"id\":\"one\",\"title\":\"one one\"},{\"id\":\"two\",\"title\":\"two two\"},{\"id\":\"three\",\"title\":\"three three\"}]"52},53{54"type": "TEXT_BODY",55"text": "Go to [Google](https://www.google.com/) if you have any questions"56},57{58"type": "TEXT_CAPTION",59"text": "No seriously, go to [Google](https://www.google.com/) if you have any questions"60},61{62"label": "If other, tell us where",63"type": "SHORT_TEXT",64"text": "Question 6"65}66]67}68],69"type": "OTHER"70}71}72}'
1{2"account_sid": "ACXXXXXXXXXXXXX",3"date_created": "2025-01-22T22:35:25Z",4"date_updated": "2025-01-22T22:35:25Z",5"friendly_name": "info_flow",6"language": "en",7"links": {8"approval_create": "https://content.twilio.com/v1/Content/HXXXXXXXXXXXX/ApprovalRequests/whatsapp",9"approval_fetch": "https://content.twilio.com/v1/Content/HXXXXXXXXXXXX/ApprovalRequests"10},11"sid": "HXXXXXXXXXXXX",12"types": {13"twilio/flows": {14"body": "Wow do we have something super cool for you! Thanks for your interest. we have a helpful link there too.",15"button_text": "See flow",16"media_url": null,17"pages": [18{19"id": "id_one",20"layout": [21{22"input_type": "TEXT",23"label": "Name",24"name": null,25"required": true,26"text": "Question 1",27"type": "SHORT_TEXT"28},29{30"input_type": "EMAIL",31"label": "Email",32"name": null,33"required": null,34"text": "Question 2",35"type": "SHORT_TEXT"36},37{38"input_type": null,39"label": "Address",40"name": null,41"required": null,42"text": "Question 3",43"type": "LONG_TEXT"44}45],46"next_page_id": "id_two",47"subtitle": null,48"title": "Page 1"49},50{51"id": "id_two",52"layout": [53{54"label": "How did you find us?",55"name": null,56"options": "[{\"id\":\"ff\",\"title\":\"Friends and family\"},{\"id\":\"oo\",\"title\":\"Online\"},{\"id\":\"ip\",\"title\":\"In person\"}]",57"required": null,58"type": "SINGLE_SELECT"59},60{61"label": "What's your favorite number?",62"name": null,63"options": "[{\"id\":\"one\",\"title\":\"one one\"},{\"id\":\"two\",\"title\":\"two two\"},{\"id\":\"three\",\"title\":\"three three\"}]",64"required": null,65"type": "MULTIPLE_SELECT"66},67{68"text": "Go to [Google](https://www.google.com/) if you have any questions",69"type": "TEXT_BODY"70},71{72"text": "No seriously, go to [Google](https://www.google.com/) if you have any questions",73"type": "TEXT_CAPTION"74},75{76"input_type": "TEXT",77"label": "If other, tell us where",78"name": null,79"required": null,80"text": "Question 6",81"type": "SHORT_TEXT"82}83],84"next_page_id": null,85"subtitle": "Subtitle of Page 2",86"title": "Page 2"87}88],89"subtitle": "Finish flow",90"type": "OTHER"91}92},93"url": "https://content.twilio.com/v1/Content/HXXXXXXXXXXXX",94"variables": {}95}
Sending a flow template using content templates is the same as sending other types of content templates. For detailed instructions, see send templates created with the Content Template Builder.
Component | Description |
---|---|
FlowData | Raw data string from the channel provider. |
InteractiveData | All information from the end user in a JSON-formatted field. |