Skip to main content

Conversational Flows

Flows are deterministic conversation paths that guide users through structured interactions. While the AI agent handles free-form questions, flows ensure consistent data collection and multi-step processes.

What are Flows?

A Flow is a series of steps that execute in sequence when triggered. Each step can:
  • Send a message
  • Collect and validate user input
  • Branch based on conditions
  • Call webhook tools
  • Generate AI responses
  • Transfer to a human agent

When to Use Flows

Use flows when you need guaranteed outcomes. Use the LLM when you need flexibility.

Flow Triggers

Two trigger types run today: always restarts once the flow completes, so the contact’s next message begins it again. It is not once per conversation.
intent and manual are accepted by the API and stored on the flow, and the matcher has no branch for either: a flow created with one is never triggered by anything and never says so. Use keyword or always.

Step Types

Every step has the same envelope. config is required, and its fields depend on type:
That is the envelope, not a runnable step: config is empty because what goes in it depends on type. Each section below gives the real shape. Steps run in array order unless a step names nextStepId, or a condition sends the run elsewhere. A step with no nextStepId that is last in the array completes the flow.

Message Step

Send a fixed message. {{variables}} are replaced with what earlier steps collected.

Collect Step

Ask for something and wait for the customer’s next message.
errorMessage sits beside validation, not inside it. Validation types date currently accepts whatever the contact typed, including tomorrow and asdf, and minDate / maxDate are not read. Validate a date in your own handler, or constrain it with choice. choice is the reason to reach for a flow at all: the answer is constrained to your list, so what reaches your systems is one of a known set rather than whatever the customer typed.

Condition Step

Branch. if is interpolated first, then compared, so "{{budget}} > 10000" becomes "25000 > 10000".
Supported operators are ==, !=, > and <. There is no AND, no OR and no parentheses. For anything more, chain several condition steps or move the decision into a tool. defaultGoto runs when no condition matches. Without it, and with nothing matching, the flow completes.

Tool Step

Call one of the agent’s tools.
Use config.toolName. config.toolId is the original spelling and still works: either field is accepted, and either one may hold the tool’s name or its id.A step pointing at a tool the agent does not have used to reply Tool "tool_9f2a..." not found to the customer as an ordinary message. It now ends the session and logs the misconfiguration instead, so the plain agent takes the conversation from the next message.The session ends as abandoned, not completed: the flow never reached the end you designed. Check that status if your completion numbers look better than the conversations do.
params values wrapped in {{ }} are replaced with collected data; anything else is passed through literally. (action appears in older examples and is accepted, but nothing reads it, so it is left out here.) params may be omitted for a tool that takes none. The tool must already exist on the agent before the flow runs.

LLM Step

Let the model answer, inside the flow.

Transfer Step

End the flow and hand off to a human.
This sends message, marks the session transferred, and silences the agent for that contact. Their next messages are stored and appear in your inbox, and the agent does not answer them: a contact who asked for a person is not talked over by the bot while they wait. The agent takes the thread back as soon as someone answers. Any outbound message you send to that contact, from the inbox or the API, ends the handoff. There is no button to press and no state to clean up.
Nobody is notified for you. There is no queue and no assignment: the conversation waits in the inbox until a person opens it. If your team does not watch the inbox, put a tool step before the transfer and notify yourself from your own systems.notifyWebhook and reason are accepted on the config and never read.

Variables

{{name}} in any string is replaced with what an earlier step collected. A variable that was never collected renders as the literal {{name}} in the message the customer receives, so check that every one is populated before it is used. Variables come from three places:

Via Dashboard

1

Navigate to Flows

Go to Senders > select your sender > Agent tab > Flows section.
2

Create New Flow

Click Create Flow and enter:
  • Name: A descriptive name (e.g., “Lead Capture Flow”)
  • Description: What this flow does
  • Trigger: How the flow is activated
3

Add Steps

Use the visual flow builder to add steps:
  1. Click Add Step
  2. Select the step type
  3. Configure the step parameters
  4. Connect steps by dragging between nodes
4

Configure Triggers

Set up how the flow is triggered:
  • For keyword triggers, enter the words that activate the flow
  • For intent triggers, describe the intent in natural language
  • For always, the flow runs on every new conversation
5

Test the Flow

Use the Test button to simulate a conversation and verify each step works correctly.
6

Activate Flow

Toggle the flow to Active to enable it for incoming messages.

Via API

Create Flow

List Flows

Update Flow

Example Flows

Lead Capture Flow

Qualify an inbound lead into three known fields before anyone reads the thread.
The choice step is what makes this worth a flow: size reaching your CRM is always one of four values, not whatever the customer typed.

Appointment Booking Flow

Both toolName values above must match tools that already exist: create_lead, get_available_slots and create_appointment must already exist on the agent.

Flow Sessions

When a user enters a flow, a session is created to track their progress. Sessions store:
  • Current step
  • Collected variables
  • Timestamps
  • Channel information
Sessions do not expire. A contact who stops answering halfway keeps an open session, and their next message resumes that flow at the step they left, weeks later, with the variables they had. It is not restarted, and there is no timeout.Plan for it: give a long flow a way out, and do not assume a collect step is answered by the message that follows it in the same hour. A flow that ends in a transfer or completes cleanly closes its session, which is the reliable way to stop one.There is also no API for reading sessions. The status is visible in the dashboard.

Best Practices

Keep Flows Short

Aim for 5-7 steps maximum. Long flows have higher abandonment rates.

Validate Early

Validate critical inputs (email, phone) immediately after collection.

Provide Exit Points

Let users say “stop” or “cancel” to exit the flow at any time.

Use Variables

Reference collected data in messages to personalize the experience.

Next Steps

Add Tools

Enable your flows to execute actions via webhooks

Knowledge Base

Let your agent answer questions from documents