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
- Use descriptive workflow names
- Keep workflows focused (single responsibility)
- Document workflow dependencies
- Test nested workflows individually
- Use custom data for clear interfaces
- Avoid deep nesting (keep call chains short)
Related#
- Nested Workflows - Detailed guide
- Infinite Loop Prevention - How loops are prevented
- Passing Data - Data flow between workflows
Tendrl