Template syntax
How {{env}}, {{input}}, {{vars}}, {{secrets}}, and {{nodes}} resolve at runtime
String fields in nodes (URLs, headers, bodies, conditions, set values, and output maps) support mustache-style tokens. The engine replaces each {{…}} before the node runs.
The previous node’s JSON is not a template scope. It is already the next node’s execute input — use JMESPath there (body.id, products[0]). See How flows work.
previous / input / vars / node ids — those are not mustache scopes.Scopes
| Token | Source | Example |
|---|---|---|
{{env.KEY}} | Environment variables | {{env.API_BASE}} |
{{secrets.KEY}} | Secrets file for the selected env | {{secrets.API_TOKEN}} |
{{input.path}} | Flow run input (CLI --input / Run panel) | {{input.username}} |
{{vars.key}} | Variables set by set nodes | {{vars.token}} |
{{nodes.id}} | Full output of a prior node | {{nodes.login}} |
{{nodes.id.path}} | Nested field on a prior node output | {{nodes.login.body.id}} |
Missing paths resolve to an empty string ("").
Run input vs wire vs input node
| Need | Use |
|---|---|
Field from Run panel / --input in a string | {{input.email}} |
| Put that payload on the wire for the next node | input node |
| Field from the last step inside extract/assert/json | JMESPath body.id |
| Field from a named earlier node in a string | {{nodes.httpId.body.id}} |
| Combine bags | merge sources: ["previous", "input", …] |
Dot paths
{{input.profile.age}}
{{nodes.login.body.user.id}}
{{env.API_BASE}}
Examples
URL and headers
{
"method": "GET",
"url": "{{env.API_BASE}}/users/{{nodes.userId}}",
"headers": {
"Authorization": "Bearer {{secrets.API_TOKEN}}"
}
}
JSON body as a string
{
"method": "POST",
"url": "{{env.API_BASE}}/users",
"headers": { "Content-Type": "application/json" },
"body": "{\"username\": \"{{input.username}}\", \"email\": \"{{input.email}}\"}"
}
Object body
{
"body": {
"username": "{{input.username}}",
"token": "{{secrets.API_TOKEN}}"
}
}
Conditions (if)
{
"type": "if",
"data": {
"condition": "{{input.active}}",
"checks": [{ "path": "status", "op": "gte", "value": 200 }]
}
}
checks[].path is JMESPath on the wire (e.g. status after HTTP).
set variables
{
"type": "set",
"data": {
"variables": {
"greeting": "Hello {{input.username}}",
"retryCount": 3
}
}
}
Template node vs {{…}}
{{…}}tokens — string substitution in templated fields.templatenode — also supports Eta (<%= it.input.name %>,<%= it.previous %>) after mustache resolution. See template node.
JMESPath (wire, not mustache)
extract, transform, assert, and json query the previous node output with JMESPath:
| Goal | Expression |
|---|---|
| HTTP body id | body.id |
| First product | body.products[0] |
| Nested name | body.user.name |