Conditional Logic
Hyphen supports conditional execution at two levels: gating an entire workflow, and branching individual steps.
Top-Level Conditions
A condition on the workflow definition gates the entire run. If it evaluates to false, the workflow ends immediately with status condition_not_met and no steps execute.
{
"name": "process_high_value",
"definition": {
"condition": {
"greaterThan": ["@input.order_total", 10000]
},
"actions": [ ]
}
}
Use top-level conditions to prevent unnecessary execution ā for example, only running a reconciliation workflow when there are actually records to process.
Step-Level Branching: filter + onFalse
Each step can have a filter that determines whether it executes. If the filter is false, the step is skipped ā unless an onFalse alternative is defined.
{
"type": "send_notification",
"filter": {
"condition": {
"greaterThan": ["@input.amount", 5000]
}
},
"properties": {
"channel": "urgent",
"message": "High-value: ${{input.amount}}"
},
"onFalse": {
"type": "send_notification",
"properties": {
"channel": "standard",
"message": "Processed: ${{input.amount}}"
}
}
}
The onFalse step has the same structure as any other step ā it can have its own type, properties, and even nested filter/onFalse for multi-branch logic.
Comparison Operators
| Operator | Syntax | Description |
|---|---|---|
equal |
{ "equal": [left, right] } |
Strict equality |
notEqual |
{ "notEqual": [left, right] } |
Not equal |
greaterThan |
{ "greaterThan": [left, right] } |
Greater than (numeric) |
lessThan |
{ "lessThan": [left, right] } |
Less than (numeric) |
greaterOrEqual |
{ "greaterOrEqual": [left, right] } |
Greater or equal |
lessOrEqual |
{ "lessOrEqual": [left, right] } |
Less or equal |
hasKey |
{ "hasKey": "path" } |
Key exists in context |
in |
{ "in": [value, array] } |
Value is in list |
matches |
{ "matches": [value, regex] } |
Regex match |
Operands can be literal values or @path references:
{ "equal": ["@input.status", "active"] }
{ "greaterThan": ["@input.amount", 1000] }
{ "in": ["@input.country", ["US", "CA", "MX"]] }
{ "matches": ["@input.email", ".*@company\\.com$"] }
{ "hasKey": "@input.metadata.priority" }
The length helper extracts array or string length:
{ "greaterThan": [{ "length": "@unmatched_invoices" }, 0] }
Combinators: and, or, not
Combine conditions for complex logic:
and ā all conditions must be true:
{
"and": [
{ "greaterThan": ["@input.amount", 1000] },
{ "equal": ["@input.verified", true] }
]
}
or ā at least one must be true:
{
"or": [
{ "equal": ["@input.customer_type", "premium"] },
{ "greaterThan": ["@input.years_active", 5] }
]
}
not ā inverts a condition:
{
"not": { "equal": ["@input.status", "cancelled"] }
}
Nested Condition Trees
Combinators nest to any depth. Here's a real-world example that gates an approval step:
Require approval when: amount over $10,000 AND (vendor is new OR country is high-risk) AND the invoice is not already pre-approved.
{
"type": "PbotApproval",
"filter": {
"condition": {
"and": [
{ "greaterThan": ["@input.amount", 10000] },
{
"or": [
{ "equal": ["@input.vendor_status", "new"] },
{ "in": ["@input.country", ["RU", "CN", "IR", "KP"]] }
]
},
{
"not": { "equal": ["@input.pre_approved", true] }
}
]
}
},
"properties": {
"comment": "High-value invoice from {{input.vendor_status}} vendor in {{input.country}}",
"request_payload": {
"amount": "@input.amount",
"vendor": "@input.vendor_name",
"country": "@input.country"
}
}
}
Evaluation order. Conditions evaluate depth-first. Inner conditions resolve before outer combinators. All @path references resolve against the current execution context at the time the condition is evaluated.
Multi-Branch Pattern
Chain filter/onFalse for multi-way branching:
{
"type": "route_premium",
"filter": {
"condition": { "equal": ["@input.tier", "premium"] }
},
"properties": { "queue": "premium" },
"onFalse": {
"type": "route_standard",
"filter": {
"condition": { "equal": ["@input.tier", "standard"] }
},
"properties": { "queue": "standard" },
"onFalse": {
"type": "route_basic",
"properties": { "queue": "basic" }
}
}
}
This evaluates as: premium ā standard ā basic (fallback).
ā Next: Scheduling