Sending
A flow can be sent once it is published on the WhatsApp Business Account of the sending number. There are three ways:
- API:
POST /whatsapp-flows/{id}/send - Inbox: agents pick a flow in a WhatsApp conversation.
- Automation: the Send WhatsApp Flow node sends it and waits for the answers.
Every send creates a session: a unique token that ties the contact's answers back to the flow, the version and the sender.
Interactive or template
WhatsApp only allows free-form messages within 24 hours after the contact's last message. That decides the mode:
mode | When | What the contact gets |
|---|---|---|
interactive (default) | The 24-hour service window is open. | A flow message with your header, body, footer and button text. |
template | Any time, including outside the window. | An approved WhatsApp template with a Flow button that opens this flow. |
For template mode, create a WhatsApp template with a Flow button that points to this flow and get it approved first (see WhatsApp templates).
Send via API
Scopes: messages:create and whatsapp_flows:read.
curl -X POST https://api.sendseven.com/api/v1/whatsapp-flows/0f9e8d7c-…/send \
-H "Authorization: Bearer s7_api_a1b2c3d4e5f6789012345678abcdef00" \
-H "Content-Type: application/json" \
-d '{
"conversation_id": "9a8b7c6d-…",
"header_text": "Rückruf vereinbaren",
"body_text": "Wann dürfen wir Sie anrufen? Das Formular dauert keine Minute.",
"cta": "Formular öffnen"
}'
Response 200:
{
"session_id": "5b0e2c1a-…",
"message_id": "msg_7e6d…",
"conversation_id": "9a8b7c6d-…",
"status": "sent",
"error": null
}
Request fields
| Field | Notes |
|---|---|
contact_id / conversation_id | Exactly one. A conversation also supplies the contact and its reply channel. |
channel_id | The WhatsApp channel to send from. Optional when it comes from the conversation or the template. |
mode | interactive (default) or template. |
header_text | Interactive only. Up to 60 characters. |
body_text | Interactive only. Up to 1024 characters. Defaults to the flow name. |
footer_text | Interactive only. Up to 60 characters. |
cta | Interactive only. The button text, up to 30 characters, for example "Formular öffnen". Defaults to "Open". |
template_id | Template mode: the approved template with a Flow button. |
template_variables | Template mode: values for the template placeholders, as an object ({"1": "Anna"} or named parameters) or a list (["Anna"] becomes {"1": "Anna"}). |
screen | Optional entry screen (navigate only). Defaults to the first screen. |
initial_data | Optional data for the entry screen. Replaces the data from send-time bindings. |
flow_action | navigate or data_exchange. Leave it empty to let SendSeven choose (see below). |
Entry screen data
For a static flow, SendSeven fills the entry screen's data when the message is sent: from your initial_data if you pass it, otherwise from the entry screen's bindings (for example the contact's name and e-mail), otherwise from the declared example values.
For a dynamic flow, SendSeven by default sends the flow with flow_action: "data_exchange". The entry screen is then loaded live from the managed endpoint when the contact opens the flow, so the data is fresh even days later. Passing screen or initial_data switches to navigate. data_exchange on a flow without an endpoint returns 409 flow_action_requires_endpoint.
Session lifetime
An API send is valid for 72 hours. After that, a dynamic flow can no longer load data, and WhatsApp shows the contact an error instead of the next screen. A static flow that the contact already filled in on the phone is still accepted when it arrives late.
Session status | Meaning |
|---|---|
created | Session created, message not yet accepted by WhatsApp. |
sent | WhatsApp accepted the message. |
in_progress | The contact opened the flow (dynamic flows). |
completed | The contact submitted the flow. |
expired | expires_at passed without a submission. SendSeven moves open sessions to expired within a few minutes of expires_at. A static flow that arrives late still moves the session to completed. |
cancelled | Reserved. Not used at the moment. |
failed | WhatsApp rejected the send. error contains the reason. |
A send that WhatsApp rejects does not return an HTTP error: the response has status: "failed" and an error. HTTP errors are only returned when the send cannot start.
Errors
| Status | Code | Cause |
|---|---|---|
400 | channel_not_whatsapp | The channel is not a WhatsApp channel. |
400 | no_whatsapp_recipient | The contact has no WhatsApp number. |
400 | conversation_contact_mismatch | The conversation belongs to another contact. |
403 | feature_not_available | WhatsApp Flows are not included in the plan. |
404 | conversation_not_found, template_not_found | Unknown conversation or template. |
409 | CHANNEL_DISCONNECTED | The channel is disconnected. |
409 | flow_archived | The flow is archived. |
409 | flow_not_published | The flow is not published on the channel's WhatsApp Business Account. |
409 | flow_action_requires_endpoint | data_exchange on a flow without a managed endpoint. |
409 | dynamic_not_supported_on_coexistence | A dynamic flow on a number that also uses the WhatsApp Business app (Coexistence). These numbers can only send static flows. |
422 | outside_service_window | Interactive send outside the 24-hour window. details.last_customer_message_at tells you when the contact last wrote. Use template mode. |
422 | template_required | mode: "template" without template_id. |
422 | template_has_no_flow_button | The template has no Flow button. |
422 | template_flow_mismatch | The template's Flow button opens a different flow. |
422 | channel_required | No channel given and none could be derived. |
422 | recipient_required | Neither or both of contact_id and conversation_id. |
422 | invalid_mode, invalid_flow_action | Unknown value. |
422 | draft_send_not_supported | Drafts cannot be sent. Use the preview link. |
Template send example
curl -X POST https://api.sendseven.com/api/v1/whatsapp-flows/0f9e8d7c-…/send \
-H "Authorization: Bearer s7_api_a1b2c3d4e5f6789012345678abcdef00" \
-H "Content-Type: application/json" \
-d '{
"contact_id": "c0ffee00-…",
"mode": "template",
"template_id": "tpl_41b2…",
"template_variables": ["Anna"]
}'
From the inbox
In a WhatsApp conversation, agents can pick any published flow and send it. Inside the 24-hour window it goes out as an interactive message; outside it, they choose a template with a Flow button. The answers appear in the conversation once the contact submits. Inbox sends are recorded with sender_type: "inbox", API sends with sender_type: "api".
Dynamic flows cannot be sent from a number that also uses the WhatsApp Business app (Coexistence). The send is refused with dynamic_not_supported_on_coexistence. Static flows work on these numbers.
From an automation
The Send WhatsApp Flow node in Flows sends a WhatsApp Flow to the contact of the run, waits for the submission, and continues on a branch:
- completed: the answers are available as
{{vars.waflow.<output_key>.<field>}}. - timeout: the contact did not submit in time (default 24 hours, up to 72 hours).
- fallback: the flow could not be sent, for example outside the 24-hour window without a fallback template, or a dynamic flow on a WhatsApp Business app (Coexistence) number.
See Send WhatsApp Flow node for the full configuration.
To react to submissions of flows sent anywhere (inbox, API, campaigns), use the whatsapp_flow.completed trigger.
Billing
WhatsApp Flows is in beta. During the beta, completed flows and AI-builder generations are free. Every flow you send counts as one message from your plan's message pool, like any other WhatsApp message. Additional charges per completed flow will apply once WhatsApp Flows becomes generally available; we will announce them in advance.
- Interactive flow message (inside the 24-hour window): one outbound WhatsApp message.
- Template with a Flow button (
mode: "template", or outside the window): one outbound template message. - Campaigns with a Flow-button template: one campaign message per recipient, from the same message pool.
- Send WhatsApp Flow node in an automation: one message, the same as an inbox or API send.
A flow counts once it is sent, delivered or read. Failed sends are not billed. The contact's submission arrives as an incoming message and is free. During the beta, the completion itself costs nothing.