What is a Condition?
A Condition step evaluates a field in the pipeline context and branches the automation into two paths:- Then — steps that run when the condition is true
- Otherwise — steps that run when the condition is false (optional)
Configuration
Every condition has three fields:Field
The field path references any value in the pipeline context. Common paths:Operators
Value
The value you compare against. How you enter it depends on the operator:
The value field automatically parses JSON. If you type
3, it’s treated as the number 3. If you type true, it’s treated as boolean true. If you need the literal string "true", wrap it in quotes: "true".
Branching
Then (on true)
Steps added to the Then branch run only when the condition evaluates to true. You can add any step type inside a branch — Transform, Destination, Upsert Contact, or even another Condition.Otherwise (on false)
Steps added to the Otherwise branch run only when the condition evaluates to false. This branch is optional. If you leave it empty, the pipeline simply skips it and continues.After the condition
Any steps placed after the condition step in the main pipeline run regardless of which branch was taken. Use this for steps that should always execute.Nesting Conditions
You can place a Condition inside another Condition’s branch to create multi-level logic. Nesting is limited to 2 levels deep.- First checks if the call completed
- If yes, checks whether the rating was low
- Sends different notifications depending on the outcome
Common Patterns
Route by call status
Branch on whether the call was successful:- Field:
call.status - Operator:
eq - Value:
completed - Then: Sync results to CRM, send follow-up email
- Otherwise: Alert the team to retry or follow up manually
Route by call outcome
Use structured data fields from your Script to route based on what happened during the call:- Field:
call.structured_data.appointment_booked - Operator:
eq - Value:
true - Then: Send confirmation email, update CRM status to “Booked”
- Otherwise: Send nurture email, update CRM status to “Follow up”
Flag low ratings
Alert your team when a customer gives a low satisfaction score:- Field:
call.structured_data.rating - Operator:
lte - Value:
2 - Then: SMS to team with call summary, email to customer success manager
- Otherwise: (skip)
Check for missing data
Only proceed if a required field exists:- Field:
contact.email - Operator:
exists - Then: Send follow-up email to contact
- Otherwise: (skip — no email available)
Route by end reason
Branch based on how the call ended — useful for distinguishing voicemail from hangups:- Field:
call.end_reason - Operator:
eq - Value:
voicemail - Then: Sync to CRM as “Left voicemail”, schedule retry
- Otherwise: (skip)
Route by multiple values
Check if the call ended in one of several statuses:- Field:
call.status - Operator:
in - Value:
["User unavailable", "rang-out", "failed"] - Then: Schedule a retry call via webhook
- Otherwise: (skip — call was answered)
Escalate based on a threshold
If the call lasted less than 30 seconds, it likely didn’t go well:- Field:
call.duration - Operator:
lt - Value:
30 - Then: SMS to team — “Very short call with {{contact.full_name}} ({{call.duration}}s). May need manual follow-up.”
- Otherwise: (skip)
Branch by trigger data
Route differently based on data from the incoming webhook:- Field:
trigger.priority - Operator:
eq - Value:
high - Then: Create Call immediately using priority Script
- Otherwise: Create Call using standard Script
Tips
- Keep conditions simple. One condition checking one field is easier to debug than nested logic. If you find yourself nesting 2 levels deep, consider whether two separate automations would be clearer.
- Check the Execution Log. When a condition branch is not taken, the log shows that branch as “Skipped” in grey. This makes it easy to verify your conditions are evaluating as expected.
- Use
existsbefore accessing optional data. If a field might not be present (e.g.,contact.emailfor contacts without an email), use anexistscondition before steps that depend on it. - Types are sorted out for you. Values carry their type through the pipeline, and a comparison converts them to match where it sensibly can. A structured data field holding the text
"4"still compares correctly against the number4, and the text"true"still compares correctly againsttrue. The same applies to values used in templates and integration requests. If you genuinely need to compare the literal text rather than the number, wrap it in quotes. - The
inoperator expects a JSON array. Enter the value as["option1", "option2"]with square brackets and quotes around strings.

