Skip to main content
Conditions control whether work happens. They appear in two places in an automation, and both use the same expression language. Under the hood a condition is a list of expr expressions joined by a logical operator. The builder writes those expressions for you from a field, an operator and a value, so you rarely type one by hand.

Adding Conditions

On the trigger

  1. Select the trigger’s event type
  2. In the trigger configuration, add one or more conditions
  3. Pick a field from the event, an operator, and a value
  4. With more than one condition, choose AND or OR

On a condition step

  1. Add a Condition step to the canvas
  2. Each branch leaving the step gets its own condition
  3. Configure each branch’s field, operator and value
  4. Add the steps that should run on each branch
A condition step has no separate “else” field. A branch with no condition on it is the fall-through, and it is the way to express “otherwise”.

Comparison Operators

The builder offers these operators for scalar fields. For array fields, the builder offers contains, does not contain, is empty and is not empty.

Combining Conditions

AND

Every condition must be satisfied. Select AND when you add more than one condition.
  • Invoice status is overdue AND amount is greater than 1000

OR

At least one condition must be satisfied. Select OR.
  • Failure reason is insufficient_funds OR failure reason is card_declined
You can also write both into a single expression with && and ||:

Branching

If / otherwise

Add a condition step with two branches: one carrying the condition, one left unconditioned as the fall-through. Example: only chase invoices that are still owed
  • Branch 1 — condition {{get_invoice_step.outputs.amountDue}} > 0 → send an invoice reminder
  • Branch 2 — no condition → the run ends here

Several outcomes

Add more branches to the same condition step, one per outcome, each with its own condition, and leave one unconditioned as the catch-all. Example: reacting to a payment failure reason
  • failureReason == "insufficient_funds" → email asking the customer to top up
  • failureReason == "expired_card" → send a billing info request
  • no condition → notify the team on Slack

Available Data

A condition can read two things: the triggering event’s payload, and the outputs of steps that already ran.

Trigger event data

Trigger conditions are evaluated directly against the event payload, so fields are referenced by their bare name — no braces.
The fields available depend on the event type. For example: Every event type’s full payload is in the reference.

Step outputs

Conditions on a path reference earlier data with a {{...}} path:
Lookup actions return the reduced invoice and subscription shapes — status, amountDue, overdueDays, dueInDays, autoRenew, daysUntilRenewal, acv, arr, mrr and more. The CRM, quote and bulk actions return their own result fields, including a reason explaining why an action wrote nothing.
Conditions read what the run actually carries. There is no derived customer segment, lifetime value, or other computed attribute available to an automation condition — filter on the concrete fields above, or on tags via a preceding lookup step.

Collections and Null

Because conditions are expr expressions, collection helpers are available:
Null handling matters most on CRM change events, which carry only the fields that changed. An identifier that is absent resolves to nil rather than breaking the expression, so changedFields.Amount.after is safe to write. An expression that cannot be evaluated against the payload is treated as not satisfied — it will not accidentally let a run through.

Common Patterns

Only act on invoices still owed

Steps: get_invoice → condition Condition: {{get_invoice_step.outputs.amountDue}} > 0 Prevents a reminder going out to a customer who paid while the automation was waiting.

High-value failed payment alert

Trigger: payment_failed Trigger condition: amount > 10000 Then: send_slack_message to your revenue channel.

Only failures tied to an invoice

Trigger: payment_failed Trigger condition: invoiceId != nil retry_invoice_payment needs an invoice, so this keeps the run from starting for a payment that has none.

Retry only when the last attempt failed

Steps: retry_invoice_payment → condition Condition: {{retry_step.outputs.status}} == "failed"

Act only when a deal enters a stage

Trigger: salesforce_opportunity_changed or hubspot_deal_changed Trigger condition: stageEntered && stage == "Closed Won" stageEntered is false the first time a record is seen, so this fires on the actual transition rather than on every sync.

Nested Logic

Conditions do not nest inside one another. Build layered logic by chaining condition steps: a branch of one condition step can lead into another condition step, and so on. Example:
  1. Condition step — is this a CRM renewal opportunity?
    • Yes → condition step: is the subscription still auto-renewing?
      • Yes → cancel_renewal_for_lost_opportunity
      • fall-through → end
    • fall-through → end

Best Practices

Filter at the Trigger

A trigger condition is cheaper than starting a run and stopping it in step two.

Re-check Before Acting

After a delay, look the record up again and condition on its current state.

Always Add a Fall-Through

Leave one branch unconditioned so a run has somewhere to go.

Test Edge Cases

Test with boundary values, and with events that are missing optional fields.

Next Steps

Actions

Explore available actions.

Triggers

Configure what starts your automations.

Reference

Condition syntax and full event payloads.