Skip to main content
The Sub Flow node allows you to embed and execute another published flow as a nested component within your main flow. This enables code reuse, modular design, and simplified management of complex flow logic.

Behavior

  • Executes the referenced flow from start to end
  • Inherits all dynamic variables and context from the parent flow
  • Preserves the caller’s context (phone number, conversation metadata, etc.)
  • Waits for the sub-flow to complete before continuing to the next node in the main flow
  • Supports arbitrary nesting depth (sub-flows within sub-flows)
  • Automatically flattens during flow initialization for seamless execution

When to use

Use Sub Flow nodes when you want to:
  • Reuse common sequences across multiple flows (e.g., authentication, IVR menu trees)
  • Organize complex logic into manageable, testable units
  • Simplify maintenance by updating shared flows in one place
  • Compose flows dynamically without duplicating node configurations
  • Share context between flows (e.g., pass user data, authentication results, or preferences)

Configuration

ParameterTypeRequiredDescription
flowIdstringYesThe ID of the published flow to execute as a sub-flow

How it works

Flow Resolution

During conversation initialization, the system performs automatic flow resolution:
  1. Discovery — Scans the main flow for all Sub Flow node references
  2. Fetching — Retrieves the referenced flows from the database (iteratively, handling nested sub-flows)
  3. Flattening — Merges all sub-flow nodes and edges directly into the main flow
  4. Execution — The XState actor runs one unified, flat flow with no sub-flow overhead

Node Prefixing

When a sub-flow is embedded, all of its internal nodes are prefixed with the Sub Flow node’s ID to ensure uniqueness. This allows:
  • The same sub-flow to be embedded multiple times without ID collisions
  • Deep nesting (sub-flow-of-sub-flow) with clear node identity chains
  • Proper state tracking for each embedded instance

Example Prefixing

Main Flow:
  [subflow-1] → mainFlow subFlow node → (embeds flow-auth)

After flattening:
  subflow-1__tts-node
  subflow-1__collect-digits
  subflow-1__condition-node
  ...

Agent Hydration

If a sub-flow contains Agent nodes, they are automatically discovered and hydrated during flow initialization. This means:
  • Agent configurations are loaded for all nested agent nodes
  • Tools, LLM settings, and RAG configurations are applied before the flow runs
  • The flow sees all agent nodes—regardless of nesting—as part of the unified graph

Output handles

HandleDescription
CompleteSub-flow executed successfully and reached an end node — main flow continues to the next node
ErrorSub-flow encountered an error or reached an error state

Limitations and considerations

The system prevents cycles during flow initialization. If flow A references flow B and flow B references flow A, the conversation will fail at startup with a clear error message. Plan your flow hierarchy to avoid circular dependencies.
A sub-flow cannot contain only Start and End nodes—it must have at least one executable node (e.g., TTS, Agent, API Call). This ensures the flattened graph remains valid.
Flow flattening is performed once at initialization time. Arbitrarily deep nesting (A → B → C → D) is supported and has minimal runtime overhead after flattening completes.
Only flows that are saved and published can be referenced by a Sub Flow node. Unsaved drafts cannot be used.
Sub-flows share the same variable context as the parent flow. Any variables set by a sub-flow are visible to subsequent nodes in the main flow. There is no variable scope isolation.

Use cases

Create a dedicated flow (e.g., authenticate-customer) that collects PIN, verifies it, and sets an authenticated flag. Embed this flow at the start of multiple customer-facing flows to ensure consistent authentication logic.Flow structure:
Main Flow → Sub Flow (authenticate-customer) → [Authenticated branch logic]
Create a modular menu hierarchy where each level is a separate flow:
  • main-menu — Primary options
  • sales-menu — Sales department options
  • support-menu — Support department options
The main flow embeds main-menu, which in turn embeds sales-menu or support-menu based on the caller’s selection.Flow structure:
Main Flow
  → Sub Flow (main-menu)
    → IVR Menu [1: Sales, 2: Support]
    → Switch node routing to:
      → Sub Flow (sales-menu)
      → Sub Flow (support-menu)
Create a pre-agent-context flow that gathers caller information (order number, issue type) and formats it for the agent. Embed this before an Agent node to ensure agents always receive pre-qualified context.Flow structure:
Main Flow
  → Sub Flow (pre-agent-context)  [Collects and formats context]
  → Agent Node                     [Receives formatted context]
Create a dedicated after-hours-routing flow that checks the time and routes to voicemail or an external service. Embed this at the end of your main flow to provide consistent off-hours behavior.Flow structure:
Main Flow
  → Condition [Operating hours?]
  → If YES: Normal call handling
  → If NO: Sub Flow (after-hours-routing)
Create language-specific flows (flow-english, flow-spanish, flow-french) with the same structure but localized audio/text. Use a Switch node on caller.language to embed the appropriate flow.Flow structure:
Main Flow
  → Speech Input [Detect language]
  → Switch on language
    → Sub Flow (flow-english)
    → Sub Flow (flow-spanish)
    → Sub Flow (flow-french)

Technical details

Flow Flattening Algorithm

Sub-flows are resolved and flattened during conversation initialization (before the XState actor starts). The process:
  1. Scope-bound fetch — Only flows referenced in the current conversation’s main flow are fetched; this prevents unnecessary database queries
  2. Recursive resolution — Nested sub-flows are discovered and fetched in an iterative process until no new flows are found
  3. Edge rewriting — Incoming and outgoing edges are re-routed to maintain flow continuity:
    • Main flow edges targeting the sub-flow node now target the sub-flow’s first real node
    • Sub-flow exit edges now target the main flow’s original target
  4. ID prefixing — All sub-flow nodes are prefixed to avoid collisions
  5. Flattened result — A single, unified FlowSchema with no Sub Flow nodes is passed to the XState actor

Error Handling

The system throws an error at initialization time if:
  • A referenced flow does not exist in the database
  • A flow is missing its flowId configuration
  • A cycle is detected (A → B → A)
  • A sub-flow is missing its Start or End node
  • A sub-flow contains only Start and End with no intermediate nodes
Early error detection prevents runtime failures and makes debugging easier.

Best practices

Organize flows hierarchically — Create a naming convention (e.g., base-* for reusable flows, main-* for entry points) to make your flow library self-documenting.
Keep sub-flows focused — Each sub-flow should have a single, well-defined purpose. Large, multi-purpose sub-flows are harder to test and reuse.
Test sub-flows independently — Before embedding a sub-flow, test it as a standalone flow to ensure it works correctly.
Use descriptive flow names — Instead of flow-123, use authenticate-customer or qualify-sales-lead so the purpose is clear in the editor.
Document shared context — If a sub-flow expects or sets specific variables, document them clearly so integrators know what to provide and what they’ll receive.