Using Conditions & Branches
Make your workflows smarter with conditional logic. Route executions based on data, create multiple paths, and handle different scenarios automatically.
Time to complete: 15-20 minutes
Why Use Conditions?
Without conditions, workflows are linear. With conditions, they become intelligent:
| Without Conditions | With Conditions |
|---|---|
| Same action for everyone | Different paths based on data |
| No error handling | Graceful error paths |
| Fixed behavior | Dynamic responses |
| One-size-fits-all | Personalized automation |
Logic Nodes Overview
| Node | Purpose | Outputs |
|---|---|---|
| Condition | Simple true/false branching | 2 paths |
| Multi-Condition | Complex boolean logic | Multiple paths |
| Workflow Switch | Jump to different workflow | New workflow |
| Loop | Iterate over arrays | Single path, multiple runs |
| Merge | Combine branches | Single output |
| Delay | Pause or split execution | Normal + timeout paths |
Condition Node
The simplest way to branch your workflow.
How It Works
- Evaluates a single condition
- Routes to True path if condition passes
- Routes to False path if condition fails
Configuration
| Field | Description | Example |
|---|---|---|
| Variable | Data to evaluate | {{contact.lead_score}} |
| Operator | Comparison type | greater_than |
| Value | Compare against | 80 |
Available Operators
Text Operators:
| Operator | Description | Example |
|---|---|---|
equals | Exact match | name equals "John" |
not_equals | Not equal | status not_equals "closed" |
contains | Has substring | email contains "@company.com" |
not_contains | Missing substring | notes not_contains "spam" |
starts_with | Begins with | phone starts_with "+1" |
ends_with | Ends with | email ends_with ".edu" |
is_empty | No value | notes is_empty |
is_not_empty | Has value | email is_not_empty |
Numeric Operators:
| Operator | Description | Example |
|---|---|---|
equals | Equal to | score equals 100 |
greater_than | Greater than | score greater_than 80 |
less_than | Less than | age less_than 18 |
greater_than_or_equal | >= | amount >= 1000 |
less_than_or_equal | <= | days_idle <= 30 |
List Operators:
| Operator | Description | Example |
|---|---|---|
in | Value in list | stage in "lead,prospect,customer" |
not_in | Value not in list | status not_in "spam,invalid" |
Pattern Matching:
| Operator | Description | Example |
|---|---|---|
regex_match | Regular expression | phone regex_match ^\+\d{10,} |
Example: Lead Score Routing
Variable: {{contact.lead_score}}
Operator: greater_than
Value: 80
True → Assign to Sales
False → Add to Nurture Campaign
Output Variables
{{condition_1.condition_result}} - true/false
{{condition_1.left_value}} - The evaluated value
{{condition_1.right_value}} - The comparison value
{{condition_1.operator}} - Operator used
Multi-Condition Node
For complex logic with multiple conditions and paths.
How It Works
- Define condition groups (sets of conditions)
- Create output paths using boolean expressions
- Route based on which paths match
- Default path catches unmatched cases
Configuration Structure
Condition Groups:
Group 1: "High Value"
├── lead_score > 80 AND
└── company_size = "Enterprise"
Group 2: "Engaged"
├── email_opened = true OR
└── page_views > 5
Output Paths:
Path 1: "Priority Lead" (if group1 AND group2)
Path 2: "Standard Lead" (if group1 OR group2)
Default: "New Lead"
Boolean Expressions
Combine groups with logical operators:
| Expression | Meaning |
|---|---|
group1 | Group 1 matches |
group1 AND group2 | Both match |
group1 OR group2 | Either matches |
NOT group1 | Group 1 doesn't match |
(group1 AND group2) OR group3 | Complex logic |
Execution Modes
| Mode | Behavior |
|---|---|
| first_match | Execute first matching path only (default) |
| all_matches | Execute ALL matching paths |
| error_on_all | Return error if no paths match |
Example: Customer Segmentation
Condition Groups:
Group 1: "Enterprise"
- company_size equals "Enterprise"
- annual_revenue greater_than 1000000
Group 2: "Engaged"
- email_opened_last_30d equals true
- page_views greater_than 10
Group 3: "At Risk"
- days_since_login greater_than 60
Output Paths:
| Path | Expression | Action |
|---|---|---|
| VIP Customer | group1 AND group2 | Dedicated support |
| Enterprise Risk | group1 AND group3 | Urgent outreach |
| Engaged SMB | group2 AND NOT group1 | Upgrade campaign |
| At Risk | group3 | Re-engagement flow |
| Default | - | Standard nurture |
Output Variables
{{multicondition_1.success}} - Execution successful
{{multicondition_1.path_id}} - Selected path ID
{{multicondition_1.path_name}} - Selected path name
{{multicondition_1.matching_paths}} - All matching paths
Workflow Switch Node
Jump to a completely different workflow.
When to Use
- Intent routing: Route to specialized workflows
- Escalation: Hand off to different process
- Complex subflows: Call reusable workflows
Switch Modes
| Mode | Use Case |
|---|---|
| intent_based | Route by detected intent |
| condition_based | Route by conditions |
| explicit | Always go to specific workflow |
Intent-Based Switching
Map intents to workflows:
Intent Mappings:
├── "support" → Support Ticket Workflow
├── "billing" → Billing Inquiry Workflow
├── "sales" → Sales Conversation Workflow
└── Default → General FAQ Workflow
Condition-Based Switching
Route based on data:
Conditions:
├── customer_type equals "enterprise" → Enterprise Workflow
├── issue_type equals "urgent" → Urgent Response Workflow
└── Default → Standard Workflow
Context Preservation
| Option | Purpose |
|---|---|
| pass_context | Share data with target workflow |
| save_context | Save current state for return |
| pause_current | Pause for later resumption |
Loop Node
Iterate over arrays to process multiple items.
How It Works
- Receives an array
- Executes downstream nodes for each item
- Collects results from all iterations
Configuration
| Field | Description | Example |
|---|---|---|
| array_source | Path to array | {{api_response.items}} |
| concurrent | Process in parallel | true |
| max_concurrent | Max parallel items | 5 |
| continue_on_error | Skip failed items | true |
Iteration Variables
Inside the loop, these variables are available:
{{loop_1.current_item}} - Current array item
{{loop_1.current_index}} - Zero-based index
{{loop_1.total_items}} - Total items count
Example: Process Order Items
Loop over: {{order.items}}
Concurrent: true
Max concurrent: 10
For each item:
→ Check inventory
→ Update stock
→ Generate label
Output Variables
{{loop_1.results}} - Array of all results
{{loop_1.iterations}} - Total iterations
{{loop_1.successful}} - Successful count
{{loop_1.errors}} - Array of errors
Merge Node
Combine multiple branches back into one.
Why Use Merge
After a condition splits your workflow, you may want to:
- Continue with a single path
- Combine data from different branches
- Ensure one output regardless of path taken
Merge Strategies
| Strategy | Behavior |
|---|---|
| first_non_null | Return first input that has data |
| merge_objects | Deep merge all objects |
| concatenate_arrays | Join all arrays together |
Example: First Non-Null
Input 1: null
Input 2: { name: "John" }
Input 3: { name: "Jane" }
Result: { name: "John" } // First non-null
Example: Merge Objects
Input 1: { email: "john@example.com" }
Input 2: { phone: "+1234567890" }
Input 3: null
Result: {
email: "john@example.com",
phone: "+1234567890"
}
Configuration
Strategy: merge_objects
Inputs: Connect from multiple branches
Output Variables
{{merge_1.output}} - Merged result
{{merge_1.merged_from.input1}} - Was input1 included?
{{merge_1.merged_from.input2}} - Was input2 included?
Delay Node
Pause execution or create time-based splits.
Delay Types
| Type | Use Case |
|---|---|
| time | Wait fixed duration |
| until_calendar_date | Wait until specific date |
| until_date_property | Wait until entity's date field |
| until_day_of_week | Wait until specific day |
| until_time_of_day | Wait until specific time |
| condition | Wait for email activity |
| whatsapp_condition | Wait for WhatsApp activity |
| website_condition | Wait for website activity |
| percentage_split | A/B test routing |
Time Delay
Wait for a fixed duration:
Delay Duration: 30
Delay Unit: minutes
Available Units:
- seconds
- minutes
- hours
- days
- weeks
- months
Wait for Activity
Wait until specific engagement occurs:
Email Activity:
Delay Type: condition
Activity Type: opened
Email Message ID: {{email_send_1.message_id}}
Timeout: 3 days
Website Activity:
Delay Type: website_condition
Activity Type: page_view
URL Pattern: /pricing
Contact ID: {{contact.id}}
Timeout: 7 days
Percentage Split (A/B Testing)
Split traffic for testing:
Branches:
├── Variant A: 50%
└── Variant B: 50%
Seed Field: {{contact.email}} // For deterministic split
Output Paths
| Path | When |
|---|---|
| output | Normal completion |
| timeout | Condition not met in time |
Common Patterns
Pattern 1: Error Handling
API Request Node
│
▼
Condition: status_code equals 200
│
├── True → Process Response
│
└── False → Error Handler
├── Log Error
└── Send Alert
Pattern 2: Lead Qualification
New Lead Trigger
│
▼
Multi-Condition Node
│
├── "Hot Lead" (score > 80 AND company_size = Enterprise)
│ └── Assign to Sales + Slack Alert
│
├── "Warm Lead" (score > 50)
│ └── Add to Nurture Sequence
│
└── "Cold Lead" (default)
└── Add to Long-term Drip
Pattern 3: Bulk Processing with Loop
Get All Pending Orders
│
▼
Loop: {{orders}}
│
▼ (for each order)
│
├── Check Inventory
├── Process Payment
├── Send Confirmation
│
▼
Merge Results
│
▼
Send Summary Report
Pattern 4: Follow-up Sequence
Send Email
│
▼
Delay: Wait 3 days
│
▼
Condition: email_opened
│
├── True → Send Follow-up B
│
└── False → Send Follow-up A (resend)
│
▼
Delay: Wait 5 days
│
▼
Condition: still no open
│
└── Mark as Unresponsive
Pattern 5: A/B Testing
New Signup Trigger
│
▼
Delay: Percentage Split (50/50)
│
├── Variant A → Welcome Email V1
│
└── Variant B → Welcome Email V2
│
▼
Track Results (both paths)
Best Practices
Condition Design
✅ Use specific operators (equals vs contains)
✅ Handle null/empty cases explicitly
✅ Keep conditions simple and readable
✅ Document complex logic with node aliases
❌ Don't nest too many conditions
❌ Don't forget default/else paths
❌ Don't compare incompatible types
Branch Management
✅ Name your paths clearly
✅ Use merge nodes to recombine
✅ Keep parallel branches balanced
✅ Test all possible paths
❌ Don't create orphaned branches
❌ Don't let branches diverge indefinitely
❌ Don't forget error handling paths
Performance
✅ Evaluate fastest conditions first
✅ Use concurrent loops when possible
✅ Set reasonable timeouts
✅ Limit loop iterations
❌ Don't loop over very large arrays
❌ Don't create infinite loops
❌ Don't forget timeout paths
Troubleshooting
Condition Always False
- Check variable path - Is it spelled correctly?
- Verify data exists - Does field have value?
- Check types - Comparing string to number?
- Test values - Print actual vs expected
Wrong Path Taken
- Review operator -
equalsvscontains? - Check case sensitivity - "John" vs "john"
- Verify logic - AND vs OR?
- Test with debug mode - See actual evaluation
Loop Not Executing
- Check array source - Does it return array?
- Verify array length - Is it empty?
- Test variable path - Correct nesting?
- Check permissions - Can access data?
Merge Not Working
- Check connections - All inputs connected?
- Verify strategy - Right merge type?
- Test input data - What's actually arriving?
- Review timing - All branches complete?
Next Steps
With conditional logic mastered, continue with:
- AI Nodes & Prompts - Add AI intelligence
- Testing Workflows - Debug effectively
- Error Handling - Build resilient workflows
Quick Reference
Operators
| Category | Operators |
|---|---|
| Equality | equals, not_equals |
| Comparison | greater_than, less_than, >=, <= |
| Text | contains, starts_with, ends_with |
| Presence | is_empty, is_not_empty |
| List | in, not_in |
Boolean Logic
AND - Both conditions must be true
OR - Either condition can be true
NOT - Inverts the condition
() - Groups for precedence
Node Outputs
| Node | Key Output |
|---|---|
| Condition | condition_result (true/false) |
| Multi-Condition | path_id, path_name |
| Loop | current_item, current_index |
| Merge | output |
| Delay | Path: output or timeout |