WhatsApp Flows API
https://whatsapp.turn.io/v1/flows
WhatsApp Flows are interactive, data-collection tools that can be used to gather information from customers directly within WhatsApp. This endpoint allows you to programmatically create WhatsApp Flows for your WhatsApp Business Account.
WhatsApp Flows are a feature provided by Meta. For detailed information about flow specifications, screen types, and components, please refer to the official WhatsApp Flows documentation.
Prerequisites
Feature Flag
All WhatsApp Flows endpoints require the whatsapp_flows_api feature flag to be enabled for your number. Please contact your account manager to enable this feature.
Authentication
All endpoints use Bearer token authentication. Include your Turn.io token in the HTTP Authorization header:
-H "Authorization: Bearer <token>"
The WhatsApp number is determined from the authentication token.
Creating a Flow
To create a WhatsApp Flow, provide a JSON object with the flow definition. The flow will be created under your WhatsApp Business Account (WABA).
POST https://whatsapp.turn.io/v1/flows
Request Body
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
name | string | Yes | The name of the flow. This will be visible in your WhatsApp Business Manager. | |
flow_json | object or string | Yes | The flow definition as a JSON object or stringified JSON. Must conform to WhatsApp's Flow JSON specification v7.2+. | |
categories | array of strings | No | ["OTHER"] | The categories to classify your flow. Valid options: SIGN_UP, SIGN_IN, APPOINTMENT_BOOKING, LEAD_GENERATION, CONTACT_US, CUSTOMER_SUPPORT, SURVEY, OTHER. |
publish | boolean | No | false | Whether to publish the flow immediately after creation. If false, the flow will be created in draft mode. |
Example Request
$ curl -X POST https://whatsapp.turn.io/v1/flows \
-H "Authorization: Bearer <token>" \
-H "Content-Type: application/json" \
-d '{
"name": "Customer Survey",
"flow_json": {
"version": "7.2",
"screens": [
{
"id": "SURVEY_START",
"title": "Customer Satisfaction",
"terminal": true,
"layout": {
"type": "SingleColumnLayout",
"children": [
{
"type": "TextHeading",
"text": "How satisfied are you with our service?"
},
{
"type": "RadioButtonsGroup",
"name": "satisfaction",
"label": "Please select your satisfaction level",
"data-source": [
{ "id": "very_satisfied", "title": "Very Satisfied" },
{ "id": "satisfied", "title": "Satisfied" },
{ "id": "neutral", "title": "Neutral" },
{ "id": "dissatisfied", "title": "Dissatisfied" }
],
"required": true
},
{
"type": "Footer",
"label": "Submit",
"on-click-action": {
"name": "complete",
"payload": {}
}
}
]
}
}
]
},
"categories": ["SURVEY"],
"publish": false
}'
Response
201 Created
{
"meta": {
"version": "v1",
"api_status": "stable",
"http_code": 201
},
"id": "1234567890123456",
"validation_errors": []
}
| Parameter | Type | Description |
|---|---|---|
meta | object | Standard metadata object containing API version and status information. |
id | string | The unique identifier for the newly created flow, provided by Meta. |
validation_errors | array | Array of validation errors returned by Meta's API, if any. |
Using the Flow ID
The ID of your flow and the available screens are supplied by Facebook Business Manager.
Once you have the flow id, you can use it to send interactive messages with flows to your customers:
$ curl -X POST https://whatsapp.turn.io/v1/messages \
-H "Authorization: Bearer <token>" \
-H "Content-Type: application/json" \
-d '{
"to": "27123456789",
"type": "interactive",
"interactive": {
"type": "flow",
"header": {
"type": "text",
"text": "Customer Survey"
},
"body": {
"text": "We would love to hear your feedback! Please take a moment to complete our survey."
},
"footer": {
"text": "Your feedback helps us improve"
},
"action": {
"name": "flow",
"parameters": {
"flow_id": "1234567890123456",
"flow_cta": "Start Survey",
"flow_action": "navigate",
"flow_action_payload": {
"screen": "SURVEY_START"
},
"flow_message_version": "3",
"mode": "published"
}
}
}
}'
Key Parameters:
flow_id: The ID returned from creating your flow (the flow_json is already stored in Meta's system)flow_cta: The call-to-action button text (e.g., "Start Survey")flow_action: Usually "navigate" to open the flow at a specific screenflow_action_payload.screen: The screen ID from your flow_json to openmode: Either "published" (for live flows) or "draft" (for testing)
For more details, see the Messages API documentation.
Updating Flow Metadata
Update a flow's metadata such as name, categories, endpoint URI, and application ID without changing the flow JSON itself.
POST https://whatsapp.turn.io/v1/flows/:flow_id
Request Body
All parameters are optional. Only include the fields you want to update.
| Parameter | Type | Description |
|---|---|---|
name | string | The new name for the flow. |
categories | array of strings | New categories for your flow. Valid options: SIGN_UP, SIGN_IN, APPOINTMENT_BOOKING, LEAD_GENERATION, CONTACT_US, CUSTOMER_SUPPORT, SURVEY, OTHER. |
endpoint_uri | string | URL of the WA Flow Endpoint (for Flow JSON version 3.0+ with data exchange). |
application_id | string | ID of the Meta application to connect to the Flow (required for flows with endpoints). |
Example Request
$ curl -X POST https://whatsapp.turn.io/v1/flows/1234567890123456 \
-H "Authorization: Bearer <token>" \
-H "Content-Type: application/json" \
-d '{
"name": "Customer Feedback Form",
"categories": ["CUSTOMER_SUPPORT", "SURVEY"]
}'
Response
200 OK
{
"meta": {
"version": "v1",
"api_status": "stable",
"http_code": 200
},
"success": true
}
Updating Flow JSON
Update a flow's JSON by uploading a new flow.json file. Meta will validate the JSON and return any validation errors.
POST https://whatsapp.turn.io/v1/flows/:flow_id/assets
Request
The request must be sent as multipart/form-data:
| Parameter | Type | Required | Description |
|---|---|---|---|
file | file | Yes | The flow JSON file. Maximum size: 10 MB. |
The name and asset_type parameters are automatically set to flow.json and FLOW_JSON respectively.
Example Request
$ curl -X POST https://whatsapp.turn.io/v1/flows/1234567890123456/assets \
-H "Authorization: Bearer <token>" \
-F "file=@flow.json"
Response
200 OK
{
"meta": {
"version": "v1",
"api_status": "stable",
"http_code": 200
},
"success": true,
"validation_errors": []
}
If the flow JSON contains validation errors, Meta will still accept the upload but return detailed error information:
{
"meta": {
"version": "v1",
"api_status": "stable",
"http_code": 200
},
"success": true,
"validation_errors": [
{
"error": "INVALID_PROPERTY_VALUE",
"error_type": "FLOW_JSON_ERROR",
"message": "Invalid value found for property 'type'.",
"line_start": 10,
"line_end": 10,
"column_start": 21,
"column_end": 34,
"pointers": [
{
"line_start": 10,
"line_end": 10,
"column_start": 21,
"column_end": 34,
"path": "screens[0].layout.children[0].type"
}
]
}
]
}
Publishing a Flow
Publish a draft flow to make it available for production messages.
POST https://whatsapp.turn.io/v1/flows/:flow_id/publish
Example Request
$ curl -X POST https://whatsapp.turn.io/v1/flows/1234567890123456/publish \
-H "Authorization: Bearer <token>"
Response
200 OK
{
"meta": {
"version": "v1",
"api_status": "stable",
"http_code": 200
},
"success": true
}
Important Notes
- Only flows in DRAFT status can be published
- Once published, flows cannot be edited or deleted (only deprecated)
- Published flows can be used immediately in production messages
- Ensure you've thoroughly tested your flow in draft mode before publishing
Deleting a Flow
Delete a flow that is in DRAFT status.
DELETE https://whatsapp.turn.io/v1/flows/:flow_id
Only flows in DRAFT status can be deleted. To remove a published flow, use the deprecate endpoint instead.
Example Request
$ curl -X DELETE https://whatsapp.turn.io/v1/flows/1234567890123456 \
-H "Authorization: Bearer <token>"
Response
200 OK
{
"meta": {
"version": "v1",
"api_status": "stable",
"http_code": 200
},
"success": true
}
Deprecating a Flow
Deprecate a published flow. Deprecated flows remain visible in your flow history but can no longer be used to send messages to customers.
POST https://whatsapp.turn.io/v1/flows/:flow_id/deprecate
Example Request
$ curl -X POST https://whatsapp.turn.io/v1/flows/1234567890123456/deprecate \
-H "Authorization: Bearer <token>"
Response
200 OK
{
"meta": {
"version": "v1",
"api_status": "stable",
"http_code": 200
},
"success": true
}
Listing Flows
Retrieve a list of all WhatsApp Flows for your WhatsApp Business Account.
GET https://whatsapp.turn.io/v1/flows
Example Request
$ curl -X GET https://whatsapp.turn.io/v1/flows \
-H "Authorization: Bearer <token>"
Response
200 OK
{
"meta": {
"version": "v1",
"api_status": "stable",
"http_code": 200
},
"data": [
{
"id": "1234567890123456",
"name": "Customer Survey",
"status": "PUBLISHED",
"categories": ["SURVEY"],
"validation_errors": []
},
{
"id": "6543210987654321",
"name": "Sign Up Flow",
"status": "DRAFT",
"categories": ["SIGN_UP"],
"validation_errors": []
}
]
}
Flow Status Values
| Status | Description |
|---|---|
DRAFT | Flow is in draft mode and can be edited or deleted |
PUBLISHED | Flow is published and can be used to send messages |
DEPRECATED | Flow has been deprecated and can no longer be used |
THROTTLED | Flow is throttled due to endpoint health issues (limited to 10 messages/hour) |
BLOCKED | Flow has been blocked due to continued endpoint health issues |
Listing Flow Assets
Retrieve a flow's assets, including the FLOW_JSON asset containing the flow definition.
GET https://whatsapp.turn.io/v1/flows/:flow_id/assets
Example Request
$ curl -X GET https://whatsapp.turn.io/v1/flows/1234567890123456/assets \
-H "Authorization: Bearer <token>"
Response
200 OK
{
"meta": {
"version": "v1",
"api_status": "stable",
"http_code": 200
},
"data": [
{
"name": "flow.json",
"asset_type": "FLOW_JSON",
"download_url": "https://scontent.xx.fbcdn.net/m1/v/..."
}
]
}
The download_url is a temporary URL to download the asset content:
$ curl -X GET "https://scontent.xx.fbcdn.net/m1/v/..." -o flow.json
Error Responses
All endpoints may return the following common errors:
403 Forbidden - Feature Not Enabled
{
"meta": {
"version": "v1",
"api_status": "stable",
"http_code": 403
},
"error": {
"code": "feature_not_enabled",
"message": "The whatsapp_flows_api feature is not enabled for this number",
"type": "FeatureNotEnabled"
}
}
403 Forbidden - Not Supported for Number Type
{
"meta": {
"version": "v1",
"api_status": "stable",
"http_code": 403
},
"error": {
"code": "not_supported",
"message": "This operation is not supported for the given number type",
"type": "NotSupported"
}
}
400 Bad Request - Missing Flow ID
{
"meta": {
"version": "v1",
"api_status": "stable",
"http_code": 400
},
"error": {
"code": "missing_parameters",
"message": "Missing required parameter: flow_id",
"type": "BadRequest"
}
}
400 Bad Request - Flow Not Found
{
"meta": {
"version": "v1",
"api_status": "stable",
"http_code": 400
},
"errors": [
{
"title": "Flow not found",
"details": "The specified flow ID does not exist or is not accessible"
}
]
}
400 Bad Request - WABA Not Found
{
"meta": {
"version": "v1",
"api_status": "stable",
"http_code": 400
},
"errors": [
{
"title": "WABA not found",
"details": "This number is not associated with a WhatsApp Business Account"
}
]
}
400 Bad Request - Invalid Flow Status
Returned when attempting to publish, delete, or deprecate a flow in an invalid status:
{
"meta": {
"version": "v1",
"api_status": "stable",
"http_code": 400
},
"error": {
"code": 100,
"message": "Flow is not in DRAFT status",
"error_user_title": "Invalid Flow Status",
"error_user_msg": "Only flows in DRAFT status can be published",
"type": "OAuthException"
}
}
400 Bad Request - Validation Errors
{
"meta": {
"version": "v1",
"api_status": "stable",
"http_code": 400
},
"error": {
"code": 100,
"message": "Flow has validation errors",
"error_user_title": "Validation Failed",
"error_user_msg": "Please fix all validation errors before publishing",
"type": "OAuthException"
}
}
Flow JSON Specification
The flow_json parameter must conform to WhatsApp's Flow JSON specification:
- Version: Must be
7.2or higher - Screens: An array of screen objects that define the flow's user interface
- Data Model: Optional data model for managing flow state
- Routing: Navigation logic between screens
To accept a payload on WhatsApp you need to define data in the WhatsApp flow definition, as well as init-value for each input field.
For complete details on the Flow JSON specification, including available screen layouts, component types, action types, and validation rules, refer to the WhatsApp Flows JSON Reference.
Best Practices
Turn does not currently support WhatsApp Flows with endpoints (i.e. no data exchange while the user is navigating through the form).
Turn only guarantees the working of WhatsApp Flows for the following devices as per Meta's policies:
- Android running OS 6.0 and newer
- iPhone running iOS 12 and newer
- Test in Draft Mode: Create flows with
publish: falseinitially to test them before publishing. - Validate Flow JSON: Ensure your flow JSON is valid before making the API call to avoid errors.
- Use Appropriate Categories: Select the category that best matches your flow's purpose for better organization.
- Keep It Simple: Start with simple flows and gradually add complexity as needed.
- Error Handling: The flow JSON may contain validation errors returned from Meta's API. Review error messages carefully to fix issues.