{{ ... }} inside a Flow Definition, the platform resolves the enclosed path against the execution’s context — trigger input, definition variables, prior step outputs — just before the task runs.
Where expressions can appear
| Location | How they’re used |
|---|---|
Task parameters | Resolved right before the task executes. Values can be plain strings, whole-value expressions, or nested objects and arrays — expressions are resolved recursively at any depth. |
Step exit_conditions | Each condition is a comparison (e.g. {{step_1.output.status}} == "failed") evaluated after all tasks in the step complete, to decide whether the flow continues, skips the next step, or aborts. |
Context roots
Every expression starts from one of these roots:| Root | Example | Resolves to |
|---|---|---|
input | {{input.phone}} | The trigger’s input_data — or, for multi-record jobs, this execution’s record. |
var | {{var.threshold}} | A definition-level variable, by name. |
job | {{job.id}} | Details of the job this execution belongs to: id, source, and metadata (the metadata object from the trigger request). |
system | {{system.execution_id}} | Runtime identifiers: execution_id, definition_id, and definition_version. |
| A step ID | {{step_1.task_a.output.cost}} | The output of a completed task, addressed as {{step_id.task_id.output.<field>}}. |
Dot-path traversal
Paths use dots to walk into nested objects:{{input.contact.address.city}}. Traversal is null-safe — if any segment along the path is missing, the expression resolves to null instead of raising an error. In a mixed string template, a null value renders as an empty string.
To supply a fallback, use the default pipe:
true/false become booleans, bare numbers become numbers, and null stays null. default is the only pipe operator available.
Type preservation
How a value resolves depends on whether the expression stands alone:- Whole-value expression — when the entire parameter value is a single
{{ ... }}, the resolved value keeps its native type: an object stays an object, an array stays an array, a number stays a number. This is how you pass structured data (like a list of records) from one step to the next without serializing it. - Mixed template — when an expression is embedded in surrounding text (
"Hello {{input.name}}"), the result is rendered as a string.
Conditions
Exit conditions compare two values with one of six operators:== != > < >= <=
true/false, or null. A condition with no operator at all is evaluated for truthiness: it passes if the expression resolves to a truthy value.
The ordering operators (
>, <, >=, <=) require both sides to be numeric; if either side can’t be treated as a number, the condition evaluates to false. Equality (==, !=) works on any types.Validation at creation time
When you create a definition, every string in the body is scanned for malformed expressions. If any are found, the request is rejected with422 and a list of the problems:
- Unclosed expressions — a
{{with no matching}}. - Unknown pipe operators — anything other than
defaultafter a|.
Next steps
Flow definitions
Where inputs, variables, steps, and tasks are declared.
Execution models
Immediate, scheduled, windowed, and signaled tasks.