
Use Default steps (no-code) when routing can be expressed with labeled branches and entity extraction. Use Function steps instead when you need API calls, strict numeric comparisons, or custom business logic. Use code-driven flows instead when the entire flow requires Python control.
- Ask for information (intent)
- Extract structured data (entities)
- Route based on what was collected (conditions)
- Continue the conversation in the correct branch
- End cleanly with an exit flow
Key concepts
- Step (node): A box in the editor. It represents one moment in the conversation (ask something, confirm something, collect details).
- Edge: A line between steps. It represents a possible next path.
- Condition: A label on an edge that explains when that edge should be taken.
- Entity: A piece of structured information you want to collect (phone number, date, number of passengers).
- Exit flow: A terminal end point (finish, handoff, stop).
Step types
Choosing a step type
| Default step | Function step | Advanced step | |
|---|---|---|---|
| Best for | Most flows — collecting info, routing by intent | API calls, business rules, strict comparisons | Full prompt control with code-based transitions |
| Prompt field | Yes | No (code only) | Yes |
| Routing | LLM evaluates condition labels | Your code calls flow.goto_step() | Transition functions called by the LLM |
| Entity extraction | Built-in | Access via conv.entities in code | Access via code in transition functions |
| Conditions | Labels + descriptions guide the LLM | Labels are decorative (code decides) | Transition functions control routing |
| ASR biasing / DTMF | No | No | Yes |
| Requires Python | No | Yes | Yes |
Default step (no-code)
Use Default steps for most of your flow. They allow you to:- Write natural-language instructions (prompt)
- Extract entities
- Branch to other steps using labeled edges
- Step 1: Collect an entity (e.g. number of passengers)
- Step 2: Route to the correct branch (e.g. Individual Booking vs Group Booking)
- Step 3: Continue collecting relevant details
Function step (low-code, still visual)
Use Function steps only when you need more control, such as:- Calling an API
- Applying strict business rules
- Performing numeric comparisons
- Writing state changes
- They contain code only — there is no prompt field.
- They support conditions for visual routing, but conditions on Function steps do not have required entities — your code handles all validation.
- They do not support ASR biasing, DTMF, or other per-step audio configuration.
Exit flow
Use Exit flows to:- End the conversation cleanly
- Represent a handoff
- Make terminal paths obvious in the editor
How flow logic actually runs
There are two execution models inside flows. Understanding this prevents most confusion.Default steps (LLM-driven) — no code required
In a Default step:- The LLM evaluates conditions.
- Condition labels are meaningful.
- “Required entities” inform the LLM what must be present before a condition can pass.
- Routing is determined by the model.
/entities. This inserts a template tag in the format {{entity:entity_name}} that the system resolves at runtime.
Default step prompts support entity and variant attribute references, but do not support function references. To call transition functions or global functions from a prompt, use an Advanced step.
Function steps (code-driven) — for developers
The following section covers writing Python code to control flow logic. If you are building flows without code, you can skip this section.
- Conditions are evaluated in your Python code.
- The condition label on the edge is decorative.
- You must explicitly move the flow forward.
Accessing collected entities in a function
Entities collected earlier in the flow are available as:Entity values are always strings. Cast to
int() or float() before numeric comparisons.Moving to another step from a function
A Function step does not automatically transition. You must call:flow.goto_step(), the flow will not move.
To leave the current flow entirely and enter a different one, use conv.goto_flow("flow_name") instead.
When should you use a Function step?
Use one only when you need:- API calls
- Strict numeric comparisons
- Business-rule enforcement
- Custom validation
- State changes
Step naming rules
- Step names must be unique within a flow (case-sensitive).
- The start step cannot be deleted — reassign the start step to a different node first.
Canvas controls
The flow editor provides controls to help you work with complex flows:- Zoom in/out — adjust the view scale (minimum 25%)
- Fit to view — auto-centers and scales to show all nodes
- Tidy up — auto-arranges nodes in a top-to-bottom layout with consistent spacing. Useful after adding many steps or when the layout gets messy
- Snap to grid — nodes align to a 30px grid for clean positioning
Working with nodes
- Drag steps using the drag handle at the top of each node
- Copy/paste nodes using keyboard shortcuts
- Connect steps by clicking the + handle at the bottom of a node and selecting the target step
- Pan the canvas by holding the space bar and dragging
Conditions
When you connect a Default step to another step, a condition node appears on the edge. Each condition has:| Field | Required | Description |
|---|---|---|
| Label | Yes | A short name the LLM uses to decide when to take this path (max 50 characters, must be unique within the step) |
| Description | Yes | Describe when the model should trigger this condition. Provide as much detail as necessary — this is the primary signal the LLM uses to choose between paths. |
| Required entities | No | Entities that must be collected and validated before this condition can activate |
Related pages
Entities
Configure entity types, validation, and collection in your flows.
Quickstart
Build your first no-code flow step by step.
Advanced steps
ASR biasing, DTMF collection, and rich text references in advanced steps.

