Skip to main content

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)
If a branch has no steps, it is skipped. The pipeline continues after the condition with any remaining steps. On the automation canvas a condition card splits into two side-by-side columns labelled Then and Otherwise. Each column ends in an Add step placeholder, so you build a branch by adding steps into its column. Deleting a condition asks for confirmation and tells you how many steps inside its branches go with it. See Steps for how the canvas works.

Configuration

Every condition has three fields:

Field

The field path references any value in the pipeline context. Common paths:

End reason values

call.end_reason holds a code, not the label you see in the Call Log. Compare against the code: The full list, including the transfer, take-over, telephony and error codes, is in Call Statuses & End Reasons. Older calls can still hold the previous title-case text, such as User Hangup, AI Hangup, Voicemail or Failed. If an automation needs to match both old and new calls, use in with both forms, for example ["voicemail_reached", "Voicemail"].
A dial that reached the person’s line but wasn’t answered — dial_no_answer, dial_busy or user_declined — has call.status completed, even though the Call Log shows it as Not Connected. To act only on calls that were actually answered, check call.end_reason as well as call.status.

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.
This example:
  1. First checks if the call completed
  2. If yes, checks whether the rating was low
  3. Sends different notifications depending on the outcome

Common Patterns

Route by call status

Branch on whether the call finished normally (remember that unanswered dials are also completed — see the note under End reason values):
  • 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.fields.appointment_booked.value
  • 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.fields.rating.value
  • 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_reached
  • Then: Sync to CRM as “Left voicemail”, schedule retry
  • Otherwise: (skip)

Route by multiple values

Check if the call ended in one of several ways — here, any dial that didn’t reach a person:
  • Field: call.end_reason
  • Operator: in
  • Value: ["dial_no_answer", "dial_busy", "dial_no_response"]
  • 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 conditions several 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 exists before accessing optional data. If a field might not be present (e.g., contact.email for contacts without an email), use an exists condition 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 number 4, and the text "true" still compares correctly against true. 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 in operator expects a JSON array. Enter the value as ["option1", "option2"] with square brackets and quotes around strings.