Logic Step

Route your workflow down different paths based on conditions you define.

The Logic step routes a workflow down different paths based on values from earlier steps. Branches are checked in array order. The first matching branch determines which step runs next. If no branch matches, an optional fallback branch determines the next step.

Use type: "new_logic_step" on the containing workflow step.

Before you begin

You need:

  • An earlier step containing the values you want to evaluate.
  • The exact name of that source step, supplied in its description property, and the UUID of each source field.
  • The exact name of each step that a branch can run next.

Put specific branches before broader branches because Logic checks them in array order. Add a fallback branch when the workflow must always continue.

The examples in the main guide show the workflow step's config value. The ready-to-use example at the bottom includes the complete step object.

Configure branches

nametyperequiredconstraintsdescription
branchesarrayyesitems: branchOrdered paths that the step can take.

Branch properties

A branch contains the condition to check and, usually, the name of the step to run when it matches.

nametyperequiredconstraintsdescription
labelstringnoName shown for the branch. Use a clear, distinct label so branches are easy to identify.
targetstringnostep nameExact name of the step that runs when the branch matches.
conditionobjectyesgroupRule that must match for the branch to run. See Build conditions.

Although label and target are optional, include both on ordinary branches so the workflow is readable and the matching branch has a destination.

Fallback branch

A fallback branch catches sessions that do not match any ordinary branch. Its label must be exactly Fallback branch, including capitalization and spacing. Its condition must be an empty AND group:

{
  "label": "Fallback branch",
  "target": "Standard review",
  "condition": {
    "type": "group",
    "logicOperator": "AND",
    "conditions": []
  }
}

Build conditions

A condition can compare two values, check whether one value is empty, or group several conditions. The type property identifies the kind of condition.

Each ordinary branch uses two group levels. The outer group contains inner groups, and each inner group contains comparisons or emptiness checks.

Comparison

A comparison checks a value from an earlier step against a fixed value or list of fixed values.

nametyperequiredconstraintsdescription
typestringyesbinaryRuleIdentifies a comparison.
binaryOperatorstringyescomparison operatorComparison to perform. See Choose operators.
leftOperandstringyesUsually a mapping placeholder for a field from an earlier step.
rightOperandstring | arrayyesstring or string listFixed value to compare against.
⚠️

rightOperand must contain a fixed value or list of fixed values. Comparing
one mapped field directly with another mapped field is not supported.

Emptiness check

An emptiness check tests whether a value is present. The operand is usually a mapping placeholder. null, a missing value, and an empty string are empty.

nametyperequiredconstraintsdescription
typestringyesunaryRuleIdentifies a check.
unaryOperatorstringyesIS_EMPTY or IS_NOT_EMPTYCheck to perform.
operandstringyesValue to check.

Grouped conditions

A group combines conditions with AND or OR.

nametyperequiredconstraintsdescription
typestringyesgroupIdentifies a group.
logicOperatorstringyesAND or ORWith AND, all items must match. With OR, at least one must match.
conditionsarrayyesInner groups on an outer group, or checks on an inner group.

For a non-empty ordinary branch:

  • The outer group must contain only inner groups.
  • Every inner group must use the same logicOperator.
  • The inner operator must be different from the outer operator.
  • Inner groups can contain only comparisons and emptiness checks.

An empty conditions array is accepted on an ordinary branch, but it does not define a useful conditional route. Use the exact fallback structure above when you need a catch-all path.

Route workflow paths

Compare a value

This branch checks whether a user's status equals "active":

{
  "branches": [
    {
      "label": "Active user",
      "target": "Active customer flow",
      "condition": {
        "type": "group",
        "logicOperator": "AND",
        "conditions": [
          {
            "type": "group",
            "logicOperator": "OR",
            "conditions": [
              {
                "type": "binaryRule",
                "binaryOperator": "EQUAL",
                "leftOperand": "{{`User`.`status`}}",
                "rightOperand": "active"
              }
            ]
          }
        ]
      }
    }
  ]
}

Check for an empty value

This branch checks whether an email field is empty:

{
  "branches": [
    {
      "label": "Check if email is empty",
      "target": "Request email",
      "condition": {
        "type": "group",
        "logicOperator": "AND",
        "conditions": [
          {
            "type": "group",
            "logicOperator": "OR",
            "conditions": [
              {
                "type": "unaryRule",
                "unaryOperator": "IS_EMPTY",
                "operand": "{{`User`.`email`}}"
              }
            ]
          }
        ]
      }
    }
  ]
}

Combine multiple conditions

This example routes customers to one of three steps:

{
  "branches": [
    {
      "label": "High-value active customer",
      "target": "Premium customer flow",
      "condition": {
        "type": "group",
        "logicOperator": "AND",
        "conditions": [
          {
            "type": "group",
            "logicOperator": "OR",
            "conditions": [
              {
                "type": "binaryRule",
                "binaryOperator": "EQUAL",
                "leftOperand": "{{`User`.`status`}}",
                "rightOperand": "active"
              }
            ]
          },
          {
            "type": "group",
            "logicOperator": "OR",
            "conditions": [
              {
                "type": "binaryRule",
                "binaryOperator": "GREATER_THAN_OR_EQUAL",
                "leftOperand": "{{`User`.`credit`}}",
                "rightOperand": "1000"
              }
            ]
          },
          {
            "type": "group",
            "logicOperator": "OR",
            "conditions": [
              {
                "type": "binaryRule",
                "binaryOperator": "CONTAINS",
                "leftOperand": "{{`User`.`kind`}}",
                "rightOperand": "vip"
              },
              {
                "type": "binaryRule",
                "binaryOperator": "GREATER_THAN",
                "leftOperand": "{{`User`.`credit`}}",
                "rightOperand": "10000"
              }
            ]
          }
        ]
      }
    },
    {
      "label": "New customer with valid email",
      "target": "Customer onboarding",
      "condition": {
        "type": "group",
        "logicOperator": "AND",
        "conditions": [
          {
            "type": "group",
            "logicOperator": "OR",
            "conditions": [
              {
                "type": "binaryRule",
                "binaryOperator": "EQUAL",
                "leftOperand": "{{`Customer`.`kind`}}",
                "rightOperand": "new"
              }
            ]
          },
          {
            "type": "group",
            "logicOperator": "OR",
            "conditions": [
              {
                "type": "unaryRule",
                "unaryOperator": "IS_NOT_EMPTY",
                "operand": "{{`Customer`.`email`}}"
              }
            ]
          }
        ]
      }
    },
    {
      "label": "Fallback branch",
      "target": "Standard customer flow",
      "condition": {
        "type": "group",
        "logicOperator": "AND",
        "conditions": []
      }
    }
  ]
}

Choose operators

Comparison operators

operatorapplies todescription
EQUALnumeric, string, date, time, setLeft equals right. Numbers compare numerically ("2.0" equals "2"). Sets compare as order-independent exact matches. Datetimes compare by UTC instant.
NOT_EQUALnumeric, string, date, time, setLeft does not equal right.
GREATER_THANnumeric, date, time, datetimeLeft is greater than right. Missing operands evaluate to false.
LESS_THANnumeric, date, time, datetimeLeft is less than right.
GREATER_THAN_OR_EQUALnumeric, date, time, datetimeLeft is greater than or equal to right.
LESS_THAN_OR_EQUALnumeric, date, time, datetimeLeft is less than or equal to right.
CONTAINSstring, setString: left contains substring right. Set: left contains every value in right (extras on the left are allowed).
NOT_CONTAINSstring, setInverse of CONTAINS.
STARTS_WITHstringLeft starts with right.
DOES_NOT_START_WITHstringLeft does not start with right.
ENDS_WITHstringLeft ends with right.
DOES_NOT_END_WITHstringLeft does not end with right.
IS_LONGER_THANstring vs numeric lengthleft.length > Number(right). Right is an integer length, not another string.
IS_NOT_LONGER_THANstring vs numeric lengthleft.length <= Number(right).
IS_SHORTER_THANstring vs numeric lengthleft.length < Number(right).
IS_NOT_SHORTER_THANstring vs numeric lengthleft.length >= Number(right).
IS_LONGER_OR_EQUALstring vs numeric lengthleft.length >= Number(right).
IS_NOT_LONGER_OR_EQUALstring vs numeric lengthleft.length < Number(right).
IS_SHORTER_OR_EQUALstring vs numeric lengthleft.length <= Number(right).
IS_NOT_SHORTER_OR_EQUALstring vs numeric lengthleft.length > Number(right).

Keep these details in mind:

  • String operators (CONTAINS, STARTS_WITH, ENDS_WITH, and their opposites) use the string form of the value.
  • Ordering operators (GREATER_THAN and related operators) require comparable values: numbers, dates in YYYY-MM-DD format, times in HH:mm:ss format, or date and time values. Values that cannot be compared do not match.
  • Length operators compare the number of characters in leftOperand with a numeric rightOperand. For example, "hello" with a right operand of "5" matches IS_LONGER_OR_EQUAL.
  • When rightOperand is an array, EQUAL, NOT_EQUAL, CONTAINS, and NOT_CONTAINS treat the values as sets. A single value is treated as a one-item set. Other operators convert the array to a comma-separated string.

Emptiness operators

operatordescription
IS_EMPTYOperand is null, missing, or an empty string.
IS_NOT_EMPTYOperand is not null, missing, or an empty string.

Limitations and common errors

  • No branch is taken. Add a fallback branch if the workflow must always continue.
  • The wrong branch is taken. Branches run in array order. Put more specific conditions before broader conditions.
  • The destination cannot be found. Set target to the exact step name.
  • A condition is rejected. Confirm that the configuration has exactly two group levels, that all inner groups use the same operator, and that the inner operator differs from the outer operator.
  • A mapped value cannot be found. Confirm that the mapping uses the exact step name and field identifier from an earlier step.

Ready-to-use example

The complete step below routes premium customers to Premium customer details and sends everyone else to Standard customer details. Add both destination steps to the same workflow and replace the mapped field UUID with the customer type field from Customer intake.

{
  "description": "Choose customer path",
  "type": "new_logic_step",
  "edges": [
    {
      "prev": "Customer intake"
    }
  ],
  "config": {
    "branches": [
      {
        "label": "Premium customer",
        "target": "Premium customer details",
        "condition": {
          "type": "group",
          "logicOperator": "AND",
          "conditions": [
            {
              "type": "group",
              "logicOperator": "OR",
              "conditions": [
                {
                  "type": "binaryRule",
                  "binaryOperator": "EQUAL",
                  "leftOperand": "{{`Customer intake`.`323e4567-e89b-42d3-a456-426614174002`}}",
                  "rightOperand": "premium"
                }
              ]
            }
          ]
        }
      },
      {
        "label": "Fallback branch",
        "target": "Standard customer details",
        "condition": {
          "type": "group",
          "logicOperator": "AND",
          "conditions": []
        }
      }
    ]
  }
}

Did this page help you?