Skip to main content

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.

caution

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

ParameterTypeRequiredDefaultDescription
namestringYesThe name of the flow. This will be visible in your WhatsApp Business Manager.
flow_jsonobject or stringYesThe flow definition as a JSON object or stringified JSON. Must conform to WhatsApp's Flow JSON specification v7.2+.
categoriesarray of stringsNo["OTHER"]The categories to classify your flow. Valid options: SIGN_UP, SIGN_IN, APPOINTMENT_BOOKING, LEAD_GENERATION, CONTACT_US, CUSTOMER_SUPPORT, SURVEY, OTHER.
publishbooleanNofalseWhether 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": []
}
ParameterTypeDescription
metaobjectStandard metadata object containing API version and status information.
idstringThe unique identifier for the newly created flow, provided by Meta.
validation_errorsarrayArray of validation errors returned by Meta's API, if any.

Using the Flow ID

info

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 screen
  • flow_action_payload.screen: The screen ID from your flow_json to open
  • mode: 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.

ParameterTypeDescription
namestringThe new name for the flow.
categoriesarray of stringsNew categories for your flow. Valid options: SIGN_UP, SIGN_IN, APPOINTMENT_BOOKING, LEAD_GENERATION, CONTACT_US, CUSTOMER_SUPPORT, SURVEY, OTHER.
endpoint_uristringURL of the WA Flow Endpoint (for Flow JSON version 3.0+ with data exchange).
application_idstringID 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:

ParameterTypeRequiredDescription
filefileYesThe flow JSON file. Maximum size: 10 MB.
info

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
caution

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

StatusDescription
DRAFTFlow is in draft mode and can be edited or deleted
PUBLISHEDFlow is published and can be used to send messages
DEPRECATEDFlow has been deprecated and can no longer be used
THROTTLEDFlow is throttled due to endpoint health issues (limited to 10 messages/hour)
BLOCKEDFlow 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.2 or 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
info

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

info

Turn does not currently support WhatsApp Flows with endpoints (i.e. no data exchange while the user is navigating through the form).

note

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
  1. Test in Draft Mode: Create flows with publish: false initially to test them before publishing.
  2. Validate Flow JSON: Ensure your flow JSON is valid before making the API call to avoid errors.
  3. Use Appropriate Categories: Select the category that best matches your flow's purpose for better organization.
  4. Keep It Simple: Start with simple flows and gradually add complexity as needed.
  5. Error Handling: The flow JSON may contain validation errors returned from Meta's API. Review error messages carefully to fix issues.

Additional Resources