twilio/flows
Flows is an in-app, multi-screen experience available on WhatsApp. A business can send a Flow as part of an approved content template. End users start the Flow by selecting a Flow button, which opens the multi-screen experience. Within the Flow, you can add text, images, and several input components. End users can provide input through single-choice, multi-choice, toggles, short-text answers, long-text answers, and date pickers. You can organize these components across as many as 10 screens.
Flows limitations
Flows isn't designed to transmit HIPAA Eligible Service or PCI data and shouldn't be used in workflows that require HIPAA or PCI compliance.
If you need to transmit sensitive information, use Message Redaction. Message Redaction isn't yet compatible with Studio, Proxy Service, or Functions. Don't send Flows that contain sensitive information through these products or services.
- Send a multi-screen form that includes several questions.
- Collect text input, selections, and picker answers.
- Include images, links, and clarifying text on each screen.
![]() | ![]() |
---|
To create a Flow:
- Create a
twilio/flows
content template. - Submit the content template for approval. Choose the appropriate category (
UTILITY
orMARKETING
). - When you submit the
twilio/flows
content template, WhatsApp publishes the Flow. You can view the publishing status in the content template approvals list. Currently, you can't use Flows without an approved content template. - Send the Flow. For instructions, see Send templates created with the Content Template Builder.
- Prepare the follow-up experience for the end user.
- Review the incoming webhook that contains the user's answers.
Parameter | Type | Required | Variable support | Description |
---|---|---|---|---|
body | string | Yes | Yes | Text of the templated message that delivers the Flow. Maximum length: 1,024 characters |
subtitle | string | No | No | Footer of the message. Maximum length: 1,024 characters |
media_url | string | No | Yes | Media on the initial Flow message. Supports .png , .jpeg , .mp4 , and .pdf . The domain must be static; the path can be variable. |
type | enum | Yes | No | Flow category. Valid values:
|
button_text | string | Yes | No | Text displayed on the button that starts the Flow. |
pages | array | Yes | No | Definitions of each page's components. Maximum: 10 pages. |
Property | Type | Required | Variable support | Description |
---|---|---|---|---|
id | string | Yes | No | Identifier returned in the webhook. Maximum length: 20 characters |
title | string | No | No | Title text that appears above the Flow page. |
subtitle | string | No | No | Subtitle text that appears at the top of the Flow page. |
layout | array | Yes | No | Components shown on the page. Each component must be one of the following:
|
SHORT_TEXT
object
Property | Required | Type | Variable support | Description |
---|---|---|---|---|
type | Yes | enum | No | Must be SHORT_TEXT . |
text | Yes | string | Yes (entire string must be variable or static) | Helper text. |
label | Yes | string | Yes (entire string must be variable or static) | Question displayed to the user. |
required | No | Boolean | No | Defaults to false . Whether the user must answer the question. |
input_type | No | enum | No | Defaults to TEXT . Valid values: TEXT , NUMBER , EMAIL , PASSWORD , PASSCODE , PHONE . |
LONG_TEXT
object
Property | Required | Type | Variable support | Description |
---|---|---|---|---|
type | Yes | enum | No | Must be LONG_TEXT . |
text | Yes | string | Yes (entire string must be variable or static) | Helper text. |
label | Yes | string | Yes (entire string must be variable or static) | Question displayed to the user. |
required | No | Boolean | No | Defaults to false . Whether the user must answer the question. |
SINGLE_SELECT
object
Property | Required | Type | Variable support | Description |
---|---|---|---|---|
type | Yes | enum | No | Must be SINGLE_SELECT . |
text | Yes | string | Yes (entire string must be variable or static) | Helper text. |
label | Yes | string | Yes (entire string must be variable or static) | Question displayed to the user. |
options | Yes | string | Yes (entire string must be variable or static) | Stringified array that contains title and id pairs. If you use a variable, the variable must replace the entire string.Example: "[{\"id\":\"ff\",\"title\":\"Friends and family\"}]" |
options.title | Yes | string | Yes | Display title for the option. Can be a variable. |
options.id | Yes | string | Yes | Option identifier returned in the webhook. Can be a variable. |
MULTI_SELECT
object
Property | Required | Type | Variable support | Description |
---|---|---|---|---|
type | Yes | enum | No | Must be MULTI_SELECT . |
text | Yes | string | Yes (entire string must be variable or static) | Helper text. |
label | Yes | string | Yes (entire string must be variable or static) | Question displayed to the user. |
options | Yes | string | Yes (entire string must be variable or static) | Stringified array that contains title and id pairs. If you use a variable, the variable must replace the entire string.Example: "[{\"id\":\"ff\",\"title\":\"Friends and family\"}]" |
options.title | Yes | string | Yes | Display title for the option. Can be a variable. |
options.id | Yes | string | Yes | Option identifier returned in the webhook. Can be a variable. |
DATE_PICKER
object
Property | Required | Type | Variable support | Description |
---|---|---|---|---|
type | Yes | enum | No | Must be DATE_PICKER . |
label | Yes | string | Yes (entire string must be variable or static) | Question displayed to the user. |
min_date | Yes | string | Yes (entire string must be variable or static) | Start date in YYYY-MM-DD format. |
max_date | Yes | string | Yes (entire string must be variable or static) | End date in YYYY-MM-DD format. |
unavailable_dates | Yes | string | Yes (entire string must be variable or static) | Stringified array of unavailable dates in YYYY-MM-DD format. |
name | No | string | Yes (entire string must be variable or static) | Name of the date picker object. |
LIST
object
Property | Required | Type | Variable support | Description |
---|---|---|---|---|
type | Yes | enum | No | Must be LIST . |
label | Yes | string | Yes (entire string must be variable or static) | Question displayed to the user. |
options | Yes | string | Yes (entire string must be variable or static) | Stringified array that contains title and id pairs. If you use a variable, the variable must replace the entire string.Example: "[{\"id\":\"ff\",\"title\":\"Friends and family\"}]" |
options.title | Yes | string | Yes | Display title for the option. Can be a variable. |
options.id | Yes | string | Yes | Option identifier returned in the webhook. Can be a variable. |
TEXT_HEADING
object
Property | Required | Type | Variable support | Description |
---|---|---|---|---|
type | Yes | enum | No | Must be TEXT_HEADING . |
text | Yes | string | Yes (entire string must be variable or static) | Markdown-formatted text. Supports the syntax described in the WhatsApp Components syntax cheat sheet. |
TEXT_SUBHEADING
object
Property | Required | Type | Variable support | Description |
---|---|---|---|---|
type | Yes | enum | No | Must be TEXT_SUBHEADING . |
text | Yes | string | Yes (entire string must be variable or static) | Markdown-formatted text. Supports the syntax described in the WhatsApp Components syntax cheat sheet. |
TEXT_BODY
object
Property | Required | Type | Variable support | Description |
---|---|---|---|---|
type | Yes | enum | No | Must be TEXT_BODY . |
text | Yes | string | Yes (entire string must be variable or static) | Markdown-formatted text. Supports the syntax described in the WhatsApp Components syntax cheat sheet. |
TEXT_CAPTION
object
Property | Required | Type | Variable support | Description |
---|---|---|---|---|
type | Yes | enum | No | Must be TEXT_CAPTION . |
text | Yes | string | Yes (entire string must be variable or static) | Markdown-formatted text. Supports the syntax described in the WhatsApp Components syntax cheat sheet. |
RICH_TEXT
object
Property | Required | Type | Variable support | Description |
---|---|---|---|---|
type | Yes | enum | No | Must be RICH_TEXT . |
text_list | Yes | array | Yes (entire string must be variable or static) | Array of Markdown-formatted strings. Supports the syntax described in the WhatsApp Components syntax cheat sheet. |
MEDIA
object
Property | Required | Type | Variable support | Description |
---|---|---|---|---|
type | Yes | enum | No | Must be MEDIA . |
url | Yes | string | Yes | Image URL. Supports .jpeg and .png formats. |
FOOTER
object
Property | Required | Type | Variable support | Description |
---|---|---|---|---|
type | Yes | enum | No | Must be FOOTER . |
label | Yes | string | Yes | Text displayed in the button used 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}'
Output
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 works the same way as sending any other content template. For step-by-step instructions, see Send templates created with the Content Template Builder.
Field | Description |
---|---|
FlowData | Raw data string from the channel provider. |
InteractiveData | User-provided information in JSON format. |