Logic Step
Route your workflow down different paths based on conditions you define.
The Logic step lets you branch your workflow based on conditions. You define a list of branches, each with its own condition. When the session reaches the Logic step, branches are evaluated in order—the first one whose condition is true determines which path the workflow takes next.
Branches
A Logic step contains an ordered list of branches. Each branch has a condition that is evaluated when the session reaches this step.
| name | type | required | description |
|---|---|---|---|
label | string | no | A human-readable name for the branch (e.g. "High Value Customer", "Invalid Input"). |
target | string | no | The description of the step to route to when this branch matches. |
condition | object | yes | The rule that must be true for this branch to be taken. See Conditions below. |
To define a catch-all fallback branch that always matches, set condition to a group with an empty conditions array:
{
"label": "Fallback",
"target": "default_step",
"condition": {
"type": "group",
"logicOperator": "AND",
"conditions": []
}
}Conditions
A condition can take one of three forms: a comparison between two values, an emptiness check on a single value, or a logical group that combines multiple conditions. All three forms are identified by a type field.
Comparison
A comparison condition evaluates a field from a previous step against a static value using one of the available operators.
| name | type | required | description |
|---|---|---|---|
type | string | yes | Must be binaryRule. |
binaryOperator | string | yes | The comparison to apply. See Operators. |
leftOperand | string | yes | A mapping placeholder referencing a field from a previous step (e.g. {{Webhook.response.statusCode}}). |
rightOperand | string | yes | A static value to compare against (e.g. "200"). |
The right operand must always be a static value. Comparing two mapping placeholders against each other is not currently supported.
Emptiness check
An emptiness check tests whether a single value is present or absent. The operand is typically a mapping placeholder.
| name | type | required | description |
|---|---|---|---|
type | string | yes | Must be unaryRule. |
unaryOperator | string | yes | IS_EMPTY or IS_NOT_EMPTY. |
operand | string | yes | The value to check. |
Grouped conditions
A group combines multiple conditions using AND or OR logic. Groups can be nested inside other groups.
| name | type | required | description |
|---|---|---|---|
type | string | yes | Must be group. |
logicOperator | string | yes | AND (all must be true) or OR (at least one must be true). |
conditions | array | yes | One or more conditions (comparison, emptiness check, or nested group). |
Operators
Comparison operators
| operator | applies to | description |
|---|---|---|
EQUAL | numeric, string | Left equals right. |
NOT_EQUAL | numeric, string | Left does not equal right. |
GREATER_THAN | numeric | Left is greater than right. |
LESS_THAN | numeric | Left is less than right. |
GREATER_THAN_OR_EQUAL | numeric | Left is greater than or equal to right. |
LESS_THAN_OR_EQUAL | numeric | Left is less than or equal to right. |
CONTAINS | string | Left contains the substring right. |
NOT_CONTAINS | string | Left does not contain the substring right. |
STARTS_WITH | string | Left starts with right. |
DOES_NOT_START_WITH | string | Left does not start with right. |
ENDS_WITH | string | Left ends with right. |
DOES_NOT_END_WITH | string | Left does not end with right. |
IS_LONGER_THAN | string | Length of left is greater than length of right. |
IS_NOT_LONGER_THAN | string | Length of left is not greater than length of right. |
IS_SHORTER_THAN | string | Length of left is less than length of right. |
IS_NOT_SHORTER_THAN | string | Length of left is not less than length of right. |
IS_LONGER_OR_EQUAL | string | Length of left is greater than or equal to length of right. |
IS_NOT_LONGER_OR_EQUAL | string | Length of left is not greater than or equal to length of right. |
IS_SHORTER_OR_EQUAL | string | Length of left is less than or equal to length of right. |
IS_NOT_SHORTER_OR_EQUAL | string | Length of left is not less than or equal to length of right. |
A few things to note:
- String-only operators (
CONTAINS,STARTS_WITH,ENDS_WITH, and their negations) will fail if the operand resolves to a number. - Numeric-only operators (
GREATER_THAN,LESS_THAN, and their variants) will fail if the operand resolves to a non-numeric string.
Emptiness operators
| operator | description |
|---|---|
IS_EMPTY | Operand is null, undefined, or an empty string. |
IS_NOT_EMPTY | Operand is not null, undefined, or an empty string. |
Examples
Single condition
Let's look at the simplest possible Logic step—one branch that checks whether a user's status equals "active".
{
"branches": [
{
"condition": {
"type": "group",
"logicOperator": "AND",
"conditions": [
{
"type": "group",
"logicOperator": "OR",
"conditions": [
{
"type": "binaryRule",
"binaryOperator": "EQUAL",
"leftOperand": "{{`User`.`status`}}",
"rightOperand": "active"
}
]
}
]
}
}
]
}Checking for an empty value
Here's a branch that checks whether an email field was left blank before continuing.
{
"branches": [
{
"label": "Check if email is empty",
"condition": {
"type": "group",
"logicOperator": "AND",
"conditions": [
{
"type": "group",
"logicOperator": "OR",
"conditions": [
{
"type": "unaryRule",
"unaryOperator": "IS_EMPTY",
"operand": "{{`User`.`email`}}"
}
]
}
]
}
}
]
}Multiple branches with nested logic
Building on those basics, here's a complete example with three branches. Each branch uses a different combination of operators and nested groups to route customers to the right flow.
{
"branches": [
{
"label": "High-value active customer",
"target": "premium_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": "onboarding_flow",
"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": "Default fallback",
"target": "standard_flow",
"condition": {
"type": "group",
"logicOperator": "AND",
"conditions": []
}
}
]
}Updated 20 days ago
