Control Flow Nodes
Nodes for managing workflow execution paths — branching, looping, merging, and more
Control Flow Nodes
Control flow nodes are the directors of your workflow. They make decisions, loop through data, pause execution, and combine multiple execution paths. Let's look at each one.
Start Node
When to use: Every workflow needs a Start Node. It's your entry point and defines how the workflow gets triggered.
The Start Node is where your workflow begins. It can be triggered manually by a user, on a schedule, or by an incoming webhook. You can also define what input data your workflow expects.
Configuration
Configuration:
trigger_type: manual | scheduled | webhook
input_schema: JSON Schema for validation
Example: Order Processing Workflow
Start Node Configuration:
trigger_type: webhook
input_schema:
type: object
required:
- order_id
- customer_email
- items
properties:
order_id:
type: string
customer_email:
type: string
items:
type: array
When someone places an order, the webhook sends this data through to the next nodes, which might check inventory, charge the card, and send a confirmation email.
Note: The Start Node doesn't do any processing—it just captures incoming data and validates it against your schema. If validation fails, the workflow won't run.
Common Patterns
- Manual trigger: User clicks a button in your UI
- Scheduled trigger: Workflow runs every morning at 9 AM
- Webhook trigger: External service (Stripe, GitHub, Shopify) sends data
If Node
When to use: Any time you need to split your workflow into two paths based on a condition.
The If Node checks a condition and routes execution down one of two paths: true or false. Use it for simple yes/no decisions.
Configuration
Configuration:
condition: "{{ input.value }} > 100"
# Or structured mode:
field: "status"
operator: equals | not_equals | greater | less | contains | matches
value: "active"
Example 1: Approval Threshold
If Node Configuration:
condition: "{{ input.amount }} > 1000"
Flow:
- If amount > $1000 → true path (send for manager approval)
- If amount ≤ $1000 → false path (auto-approve)
Example 2: Order Status Check
If Node Configuration:
field: "order_status"
operator: equals
value: "paid"
Flow:
- If status is "paid" → true path (proceed to shipping)
- If status is not "paid" → false path (send payment reminder email)
When to Use If vs. Switch
Use If Node for simple binary decisions. Use Switch Node (below) if you have 3+ paths.
Tip: You can nest If nodes for complex logic, but it gets messy fast. Consider using Switch or Code nodes for complex conditions.
Switch Node
When to use: When you have 3 or more different paths based on the same value.
The Switch Node routes execution based on matching values, patterns, or ranges. It's cleaner than chaining If nodes when you have multiple cases.
Configuration
Configuration:
mode: value | pattern | range | type | expression
field: "status"
cases:
- value: "pending"
port: "pending"
- value: "approved"
port: "approved"
- value: "rejected"
port: "rejected"
default: "other"
Example 1: Order Status Router
Switch Node Configuration:
mode: value
field: "order_status"
cases:
- value: "pending"
port: "pending"
- value: "processing"
port: "processing"
- value: "shipped"
port: "shipped"
- value: "delivered"
port: "delivered"
default: "unknown"
Flow:
- pending → send confirmation email
- processing → update inventory
- shipped → notify customer with tracking
- delivered → send satisfaction survey
- anything else → log error
Example 2: Priority-Based Routing
Switch Node Configuration:
mode: value
field: "priority"
cases:
- value: "critical"
port: "critical"
- value: "high"
port: "high"
- value: "normal"
port: "normal"
default: "low"
Note: Each case creates a separate output port. You can connect different nodes to each port.
Loop Node
When to use: When you need to repeat an action for each item in an array or over a range of numbers.
The Loop Node iterates over arrays, ranges, or objects. For each iteration, it outputs loop with the current item. When done, it outputs done.
Configuration
Configuration:
mode: array | range | object | batch | page
field_to_loop_on: "items"
batch_size: 10 # For batch mode
Example 1: Process Orders (Array)
Incoming data:
{
"orders": [
{ "id": "ORD-001", "amount": 50 },
{ "id": "ORD-002", "amount": 120 },
{ "id": "ORD-003", "amount": 75 }
]
}
Loop Node Configuration:
mode: array
field_to_loop_on: "orders"
Outputs:
- loop output:
{ "id": "ORD-001", "amount": 50 } - loop output:
{ "id": "ORD-002", "amount": 120 } - loop output:
{ "id": "ORD-003", "amount": 75 } - done output: (once all items processed)
Connect your processing nodes to the loop port. Each will execute once for each order.
Example 2: Batch Processing (Batch Mode)
Loop Node Configuration:
mode: batch
field_to_loop_on: "email_addresses"
batch_size: 100
Perfect for sending emails to 10,000 users—processes them 100 at a time.
Example 3: Range Loop (Generate Numbers)
Loop Node Configuration:
mode: range
from: 1
to: 12 # Loop 12 times
Useful for generating 12 months of reports, paginating through results, etc.
Warning: Be careful with large arrays—a 1 million item loop will create 1 million executions. Consider using batch mode for large datasets.
Common Patterns
- Email list: Loop through recipients and send personalized emails
- Data import: Loop through CSV rows and insert into database
- API pagination: Loop through page numbers and fetch all results
Merge Node
When to use: When multiple execution branches need to come back together before continuing.
The Merge Node waits for input from multiple paths, then combines them and passes the result forward. This is essential for parallel workflows.
Configuration
Configuration:
strategy: wait_all | first | append | merge_objects
timeout: 30000 # milliseconds
Example: Parallel Data Collection
Workflow:
- Start → split into 3 paths:
- Path A: Fetch user data from database
- Path B: Fetch user analytics from API
- Path C: Fetch preferences from cache
- All 3 paths → Merge Node (wait_all strategy)
- Merge → Log the combined result
Merge Configuration:
strategy: wait_all
timeout: 30000
The Merge waits for all 3 paths to finish (up to 30 seconds), then outputs:
{
"user_data": { ... },
"analytics": { ... },
"preferences": { ... }
}
Merge Strategies
| Strategy | Behavior | Use When |
|---|---|---|
| wait_all | Waits for all inputs, combines them | You need all results before proceeding |
| first | Uses the first input to arrive | You only care about the fastest result |
| append | Combines arrays into one | Merging array results |
| merge_objects | Deep merges objects | Combining multiple data objects |
Tip: Always set a timeout. If one branch hangs, the workflow won't wait forever.
Delay Node
When to use: When you need to pause execution for a certain amount of time.
The Delay Node pauses execution, then passes the input through to the output unchanged. Useful for rate limiting, spreading out notifications, or waiting for external systems.
Configuration
Configuration:
delay_ms: 5000 # Delay in milliseconds
# Or dynamic:
delay_expression: "{{ input.wait_time }}"
Example 1: Fixed Delay (Rate Limiting)
Delay Node Configuration:
delay_ms: 1000 # 1 second between API calls
Workflow:
- Start with list of API endpoints
- Loop through each endpoint
- Delay 1 second (rate limiting)
- HTTP Request to that endpoint
This prevents overwhelming the API with requests.
Example 2: Dynamic Delay (Retry with Backoff)
Delay Node Configuration:
delay_expression: "{{ input.retry_delay }}"
Incoming data:
{
"retry_count": 2,
"retry_delay": 4000 // 4 seconds
}
The workflow pauses for 4 seconds before retrying.
Common Patterns
- Rate limiting: Delay between API calls
- Exponential backoff: Retry failed requests with increasing delays
- Staggered notifications: Send emails over time instead of all at once
Note: The Delay Node doesn't block other workflows—only this execution is paused.
Chain Node
When to use: When you want to execute another workflow from within your current workflow, or link workflows together.
The Chain Node lets you reuse workflows. You can call another workflow, wait for it to complete, and use its output as input for the next step.
Configuration
Configuration:
workflow_id: "wf_abc123"
operation: execute | create | update
wait_for_completion: true
Example: Multi-Step Order Processing
Main Workflow:
Start (order data)
↓
Log: "Processing order"
↓
Chain Node: Call "Validate Order" workflow
↓
Chain Node: Call "Process Payment" workflow
↓
Chain Node: Call "Send Confirmation Email" workflow
↓
End
Each Chain node waits for the called workflow to complete before moving to the next step.
Configuration:
Chain Node 1:
workflow_id: "wf_validate_order"
operation: execute
wait_for_completion: true
Chain Node 2:
workflow_id: "wf_process_payment"
operation: execute
wait_for_completion: true
Tip: Break complex workflows into smaller, reusable pieces and chain them together. Makes debugging and testing easier!
Common Patterns
- Sub-workflows: Complex logic in separate workflows
- Reusable processes: "Send Email" workflow used by multiple workflows
- Parallel workflows: Multiple workflows executing simultaneously
Terminal Node
When to use: When you need to execute shell commands (in a sandboxed environment).
The Terminal Node runs shell commands in a secure sandbox. It's useful for running scripts, system commands, or tools not available through other nodes.
Configuration
Configuration:
command: "echo 'Hello World'"
timeout: 30000 # milliseconds
working_directory: "/tmp"
Example 1: Convert Image Format
Terminal Node Configuration:
command: "convert input.jpg output.png"
working_directory: "/tmp/images"
timeout: 10000
Example 2: Generate Report
Terminal Node Configuration:
command: "python /scripts/generate_report.py --date {{ input.date }} --output report.pdf"
timeout: 30000
Example 3: Compress File
Terminal Node Configuration:
command: "gzip -9 file.txt"
working_directory: "/data"
timeout: 5000
Warning: Terminal Node commands run in a sandbox. You can't access system files outside the working directory. Use File Operations Node for file system access in your workflows.
Common Control Flow Patterns
Pattern 1: Decision Tree
Start
↓
Check: Is order > $1000?
├─ YES → Send for approval
│ ↓
│ Approval Node
│ ├─ Approved → Charge card
│ └─ Rejected → Send cancellation email
│
└─ NO → Charge card directly
↓
Send confirmation email
↓
End
Pattern 2: Batch Processing
Start (with array of items)
↓
Loop (for each item)
├─ Process item
├─ Store result
└─ Move to next item (when loop → done)
↓
Log summary
↓
End
Pattern 3: Parallel Execution with Merge
Start
├─ Path A: Fetch data from DB
├─ Path B: Fetch data from API
└─ Path C: Fetch from cache
↓ (all paths merge here)
Merge Node
↓
Combine results
↓
End
Workflow Execution Example
Let's trace through a complete order workflow:
1. Start Node
Receives: { order_id: "ORD-123", customer: "Alice", amount: 250, items: [...] }
2. If Node
Condition: amount > 100
Result: TRUE (250 > 100)
Routes to: approval path
3. Approval Node (in true path)
Waits for manager approval
Result: Approved
4. HTTP Request (in approval path)
Calls payment processor
5. Log Node
Logs: "Order ORD-123 approved and charged"
6. Loop Node (for each item)
Iterates through items array
For each iteration → Update inventory
7. Merge Node (collects loop results)
Waits for all Loop iterations to complete
8. Email Node
Sends confirmation email to Alice
9. End
Workflow complete
Next Steps
- Learn data transformation: Check out Data Processing Nodes
- Integrate with APIs: See Communication Nodes
- Add AI capabilities: Visit AI & Intelligence Nodes
- Need custom logic? Check Code Node