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 | ID of the workflow to call |
data |
object | No | Custom data to pass (supports templating) |
Basic Usage
Simple Call
Configuration:
json
{
"flow_id": "process-user"
}
This passes the current event to the called workflow.
Custom Data
Configuration:
json
{
"flow_id": "process-user",
"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 calling itself
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": "process-user",
"data": {
"user_id": "{{ payload.user_id }}",
"action": "{{ payload.action }}"
}
}
Conditional Workflow Call
Flow Call with Dynamic ID:
json
{
"flow_id": "{{ 'process-admin' if payload.role == 'admin' else 'process-user' }}"
}
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