Docs / Strand / nodes/flow-call

Flow Call Node

The Flow Call node executes another workflow as a step in the current workflow.

Overview#

Flow Call nodes enable modular workflow design by allowing workflows to call other workflows.

Use Cases
  • Reusable workflow components
  • Modular design
  • Breaking complex workflows into smaller pieces
  • Shared business logic

Configuration#

Field Type Required Description
flow_id string Yes The ID of the workflow to call, not its name. Copy it from the target workflow's editor URL or the Flows list
data object No Custom data to pass (supports templating)

Basic Usage#

Simple Call#

Configuration:

json

{
  "flow_id": "6208953a_f5b1_46ae_8bfc_837054cece0f"
}

This passes the current event to the called workflow.

Custom Data#

Configuration:

json

{
  "flow_id": "6208953a_f5b1_46ae_8bfc_837054cece0f",
  "data": {
    "user_id": "{{ steps.user_lookup.output_payload.id }}",
    "action": "update"
  }
}

Passing Data#

Default Behavior#

If you don't specify data, the current event is automatically passed:

json

{
  "payload": { /* current payload */ },
  "meta": { /* current meta */ }
}

Custom Data Object#

Pass a custom object with full templating support:

Direct connection:

json

{
  "user_id": "{{ payload.id }}",
  "context": {
    "source_workflow": "{{ meta.workflow_id }}",
    "timestamp": "{{ meta.received_at }}"
  },
  "processed_data": {{ payload | tojson }}
}

Non-direct access:

json

{
  "user_id": "{{ steps.user_lookup.output_payload.id }}",
  "context": {
    "source_workflow": "{{ meta.workflow_id }}",
    "timestamp": "{{ meta.received_at }}"
  },
  "processed_data": {{ steps.process.output_payload | tojson }}
}

Accessing Output#

The nested workflow's output is available through the Flow Call node:

jinja

{{ steps.flow_call_node.output_payload }}
{{ steps.flow_call_node.output_payload.result }}

Infinite Loop Prevention#

Strand automatically prevents infinite loops by tracking the call chain.

Loop Detection

If a workflow tries to call itself (directly or indirectly), an error is raised:

code

Infinite loop detected: workflow 'workflow-id' is already in the call chain
Call chain: workflow-a -> workflow-b -> workflow-a

Examples#

User Processing Workflow#

Main Workflow:

code

[Event] -> [Flow Call: process-user] -> [Send Notification]

Flow Call Configuration:

json

{
  "flow_id": "6208953a_f5b1_46ae_8bfc_837054cece0f",
  "data": {
    "user_id": "{{ payload.user_id }}",
    "action": "{{ payload.action }}"
  }
}

Conditional Workflow Call#

Flow Call with Dynamic ID:

json

{
  "flow_id": "{{ vars.admin_flow_id if payload.role == 'admin' else vars.user_flow_id }}"
}

Best Practices#

Tips
  1. Use descriptive workflow names
  2. Keep workflows focused (single responsibility)
  3. Document workflow dependencies
  4. Test nested workflows individually
  5. Use custom data for clear interfaces
  6. Avoid deep nesting (keep call chains short)