| Key | Value |
|---|---|
BASE-URL | Base URL for Facebook Graph API Example: https://graph.facebook.com/v18.0 |
ACCESS-TOKEN | User access token for authentication. This can be retrieved by copying the Temporary access token from your app which expires in 24 hours. Alternatively, you can generate a System User Access Token. |
WABA-ID | This can be retrieved by copying the WhatsApp Business Account ID from your app. |
FLOW-ID | ID of a Flow returned after calling Create a Flow. |
DRAFT status and you can make changes to the Flow by uploading an JSON file.flow_json and publish parameters.curl -X POST '{BASE-URL}/{WABA-ID}/flows' \ --header 'Authorization: Bearer {ACCESS-TOKEN}' \ --header "Content-Type: application/json" \ --data '{ "name": "My first flow", "categories": [ "OTHER" ], "flow_json" : "{\"version\":\"5.0\",\"screens\":[{\"id\":\"WELCOME_SCREEN\",\"layout\":{\"type\":\"SingleColumnLayout\",\"children\":[{\"type\":\"TextHeading\",\"text\":\"Hello World\"},{\"type\":\"Footer\",\"label\":\"Complete\",\"on-click-action\":{\"name\":\"complete\",\"payload\":{}}}]},\"title\":\"Welcome\",\"terminal\":true,\"success\":true,\"data\":{}}]}", "publish" : true }'
| Parameter | Description | Optional |
|---|---|---|
namestring | Flow name | |
categoriesarray | A list of Flow categories. Multiple values are possible, but at least one is required. Choose the values which represent your business use case. The list of values:
| |
flow_jsonstring | Flow’s JSON encoded as string. | ✓ |
publishboolean | Indicates whether Flow should also get published. Only works if flow_json is also provided with valid Flow JSON. | ✓ |
clone_flow_idstring | ID of source Flow to clone. You must have permission to access the specified Flow. | ✓ |
endpoint_uristring | The URL of the WA Flow Endpoint. Starting from Flow JSON version 3.0 this property should be specified only via API. Do not provide this field if you are cloning a Flow with Flow JSON version below 3.0. | ✓ |
{ "id": "<Flow-ID>" "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" } ] } ] }
curl -X POST '{BASE-URL}/{FLOW-ID}' \ --header 'Authorization: Bearer {ACCESS-TOKEN}' \ --header "Content-Type: application/json" \ --data '{ "name": "New flow name" }'
| Parameter | Description | Optional |
|---|---|---|
namestring | Flow name | ✓ |
categoriesarray | A list of Flow categories. Missing value will keep existing categories. If provided, at least one values is required. | ✓ |
endpoint_uristring | The URL of the WA Flow Endpoint. Starting from Flow JSON version 3.0 this property should be specified via API or via the Builder UI. Do not provide this field if you are updating a Flow with Flow JSON version below 3.0. | ✓ |
application_idstring | The ID of the Meta application which will be connected to the Flow. All the flows with endpoints need to have an Application connected to them. | ✓ |
{ "success": true, }
curl -X POST '{BASE-URL}/{FLOW_ID}/assets' \ --header 'Authorization: Bearer {ACCESS-TOKEN}' \ --form 'file=@"/path/to/file";type=application/json' \ --form 'name="flow.json"' \ --form 'asset_type="FLOW_JSON"' # file must be attached as form-data
| Parameter | Description | Optional |
|---|---|---|
namestring | Flow asset name. The value must be flow.json | |
asset_typestring | Asset type. The value must be FLOW_JSON | |
filejson | File with the JSON content. The size is limited to 10 MB |
{ "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" } ] } ] }
curl '{BASE-URL}/{FLOW-ID}?fields=preview.invalidate(false)' \ --header 'Authorization: Bearer {ACCESS-TOKEN}'
{ "preview": { "preview_url": "https://business.facebook.com/wa/manage/flows/550.../preview/?token=b9d6....", "expires_at": "2023-05-21T11:18:09+0000" }, "id": "flow-1" }
preview_url can also be embedded as an iframe into an existing website using the following code (replace url with the one returned by the API):<iframe src="https://business.facebook.com/wa/manage/flows/550.../preview/?token=b9d6...." width="430" height="800" ></iframe>
| Field | Description |
|---|---|
preview_url | Link for the preview page. This link does not require login and can be shared with stakeholders, but the link will expire in 30 days, or if you call the API with invalidate=true which will generate a new link. |
expires_at | Time when the link will expire and the developer needs to call the API again to get a new link (30 days from link creation). |
| URL Parameter | Description |
|---|---|
interactive
boolean | If true, the preview will run in interactive mode.
Defaults to false. |
flow_token
string | It will be sent as part of each request.
You should always verify that token on your server to block any other unexpected requests.
Required for Flows with endpoint.
See Sending a Flow. |
flow_action
navigate | data_exchange | First action when Flow starts. data_exchange if it will make a request to the endpoint, or navigate if it won’t (this will also require flow_action_payload to be provided).See Sending a Flow. |
flow_action_payload
string | Initial screen data in JSON format, escaped using encodeURIComponent.
Required if flow_action is navigate. Should be omitted otherwise.See Sending a Flow. |
phone_number
string | Phone number that will be used to send the Flow, from which the public key will be used to encrypt the request payload.
Required for Flows with endpoint. See Sending a Flow. |
debug
string | Show actions in a separate panel while interacting with the preview. It will be ignored if interactive is not true. |
https://business.facebook.com/wa/manage/flows/550.../preview/?token=b9d6...&interactive=true&flow_action=navigate&flow_action_payload=%7B%22screen%22%3A%22FIRST_SCREEN%22%2C%22data%22%3A%7B%22screen_heading%22%3A%22hello%20world%22%7D%7D&debug=true
DRAFT status, it can be deleted. Use this request for that purpose.curl -X DELETE '{BASE-URL}/{FLOW-ID}' \ --header 'Authorization: Bearer {ACCESS-TOKEN}'
{ "success": true, }
curl '{BASE-URL}/{WABA-ID}/flows' \ --header 'Authorization: Bearer {ACCESS-TOKEN}'
{ "data": [ { "id": "flow-1", "name": "flow 1", "status": "DRAFT", "categories": [ "CONTACT_US" ], "validation_errors": [] }, { "id": "flow-2", "name": "flow 2", "status": "PUBLISHED", "categories": [ "SURVEY" ], "validation_errors": [] }, { "id": "flow-3", "name": "flow 3", "status": "DRAFT", "categories": [ "LEAD_GENERATION" ], "validation_errors": [] } ], "paging": { "cursors": { "before": "QVFI...", "after": "QVFI..." } } }
id,name, status, categories, validation_errors. You can request other fields by using the fields param in the request. The request example below includes all possible fields.curl '{BASE-URL}/{FLOW-ID}?fields=id,name,categories,preview,status,validation_errors,json_version,data_api_version,endpoint_uri,whatsapp_business_account,application,health_status' \ --header 'Authorization: Bearer {ACCESS-TOKEN}'
health_status.phone_number(PHONE_NUMBER_ID) parameter.{ "id": "<Flow-ID>", "name": "<Flow-Name>", "status": "DRAFT", "categories": [ "LEAD_GENERATION" ], "validation_errors": [], "json_version": "3.0", "data_api_version": "3.0", "endpoint_uri": "https://example.com", "preview": { "preview_url": "https://business.facebook.com/wa/manage/flows/55000..../preview/?token=b9d6.....", "expires_at": "2023-05-21T11:18:09+0000" }, "whatsapp_business_account": { ... }, "application": { ... }, "health_status": { "can_send_message": "BLOCKED", "entities": [ { "entity_type": "FLOW", "id": "<Flow-ID>", "can_send_message": "BLOCKED", "errors": [ { "error_code": 131000, "error_description": "endpoint_uri: You need to set the endpoint URI before you can send or publish a flow.", "possible_solution": "/documentation/business-messaging/whatsapp/flows/guides/flowjson#top-level-flow-json-properties" }, { "error_code": 131000, "error_description": "app_check: You need to connect a Meta app to the flow before you can send or publish it.", "possible_solution": "/docs/development/create-an-app" } ] }, { "entity_type": "WABA", "id": "<WABA-ID>", "can_send_message": "AVAILABLE" }, { "entity_type": "BUSINESS", "id": "<Business-ID>", "can_send_message": "AVAILABLE" }, { "entity_type": "APP", "id": "<App-ID>", "can_send_message": "LIMITED", "additional_info": [ "Your app is not subscribed to the message webhook. This means you will not receive any messages sent to your phone number." ] } ] } }
| Field | Description | Returned by default |
|---|---|---|
idstring | The unique ID of the Flow. | ✓ |
namestring | The user-defined name of the Flow which is not visible to users. | ✓ |
statusstring | DRAFT: This is the initial status. The Flow is still under development. The Flow can only be sent with "mode": "draft" for testing.PUBLISHED: The Flow has been marked as published by the developer so now it can be sent to customers. This Flow cannot be deleted or updated afterwards.DEPRECATED: The developer has marked the Flow as deprecated (since it cannot be deleted after publishing). This prevents sending and opening the Flow, to allow the developer to retire their endpoint. Deprecated Flows cannot be deleted or undeprecated.BLOCKED: Monitoring detected that the endpoint is unhealthy and set the status to Blocked. The Flow cannot be sent or opened in this state; the developer needs to fix the endpoint to get it back to Published state (more details in Flows Health and Monitoring).THROTTLED: Monitoring detected that the endpoint is unhealthy and set the status to Throttled. Flows with throttled status can be opened, however only 10 messages of the Flow could be sent per hour. The developer needs to fix the endpoint to get it back to the PUBLISHED state (more details in Flows Health and Monitoring). | ✓ |
categoriesarray | A list of flow categories. | ✓ |
validation_errorsarray | A list of errors in the Flow. All errors must be fixed before the Flow can be published. | ✓ |
json_versionstring | The version specified by the developer in the Flow JSON asset uploaded. | |
data_api_versionstring | The version of the Data API specified by the developer in the Flow JSON asset uploaded. Only for Flows with an Endpoint. | |
data_channel_uristring | [DEPRECATED in API v19.0 ] Use endpoint_uri field instead.The URL of the WA Flow Endpoint specified by the developer via API or in the Builder UI. | |
endpoint_uristring | The URL of the WA Flow Endpoint specified by the developer via API or in the Builder UI. | |
previewobject | The URL to the web preview page to visualize the flow and its expiry time. | |
whatsapp_business_accountobject | The WhatsApp Business Account which owns the Flow. | |
applicationobject | The Facebook developer application used to create the Flow initially. | |
health_statusobject | A summary of the Flows health status. When you attempt to send a Flow, multiple nodes are involved, including the app, the business portfolio that owns or has claimed it, a WABA and Flow. Each of these nodes can have one of the following health statuses assigned to the can_send_message property:
Flow node The Flow node will have the can_send_message property set to:
For more details about other nodes and rest of the properties see Messaging Health Status page. |
curl '{BASE-URL}/{FLOW-ID}/assets' \ --header 'Authorization: Bearer {ACCESS-TOKEN}'
{ "data": [ { "name": "flow.json", "asset_type": "FLOW_JSON", "download_url": "https://scontent.xx.fbcdn.net/m1/v/t0.57323-24/An_Hq0jnfJ..." } ], "paging": { "cursors": { "before": "QVFIU...", "after": "QVFIU..." } } }
clone_flow_id parameter. For more details, visit the Lifecycle of a Flow page.curl -X POST '{BASE-URL}/{FLOW-ID}/publish' \ --header 'Authorization: Bearer {ACCESS-TOKEN}'
{ "success": true }
curl -X POST '{BASE-URL}/{FLOW-ID}/deprecate' \ --header 'Authorization: Bearer {ACCESS-TOKEN}'
{ "success": true, }
curl -X POST '{BASE-URL}/<DESTINATION_WABA_ID>/migrate_flows?source_waba_id=<SOURCE_WABA_ID> &source_flow_names=<SOURCE_FLOW_NAMES>' \ --header 'Authorization: Bearer {ACCESS-TOKEN}'
| Placeholder | Description | Example Value |
|---|---|---|
<DESTINATION_WABA_ID>WhatsApp Business Account ID | Required. Destination WhatsApp Business Account ID. | 104996122399160 |
<SOURCE_WABA_ID>WhatsApp Business Account ID | Required. Source WhatsApp Business Account ID. | 102290129340398 |
<SOURCE_FLOW_NAMES>Array | Optional. List of specific Flow names to migrate. If not specified, it will migrate all flows in source WABA. Only 100 Flows can be migrated in a request. | [ “appointment-booking”, “lead-gen” ] |
{ "migrated_flows": [ { "source_name": "appointment-booking", "source_id": "1234", "migrated_id": "5678" } ], "failed_flows": [ { "source_name": "lead-gen", "error_code": "4233041", "error_message": "Flows Migration Error: Flow with the same name exists in destination WABA." } ] }
| Issue | Potential cause | Steps to resolve |
|---|---|---|
Received a permission error while calling the API | Insufficient Permissions | You can check your permissions with the following link (replace WA Business Account ID and Business ID with your values)
https://business.facebook.com/settings/whatsapp-business-accounts/{waba-id}?business_id={business-id} To use Flows API you need Message templates (view and manage) and Phone Numbers (view and manage) permissions. |
Incorrect Access Token | Use the Access Token Debugger tool to verify your token permissions
https://developers.facebook.com/tools/debug/accesstoken In Scopes field, you should have whatsapp_business_management, whatsapp_business_messaging. And under Granular Scopes section you should see your WABA Id under both whatsapp_business_management and whatsapp_business_messaging After you verify access token, please try to make basic request with the token, like GET /waba-id or GET /flow-id. | |
Invalid request syntax | Use the Postman Collection to make the same request. |