Expressions

Expressions let you dynamically reference data from upstream nodes inside any configuration field. They use a safe, sandboxed syntax so your workflows stay secure.

Basic Syntax

Expressions are wrapped in double curly braces. The most common variable is $json, which references the output of the immediately upstream node:

Expression syntax
{{ $json.fieldName }}

When the workflow runs, the expression is replaced with the actual value from the upstream node's output. For example, if the upstream node produced {"email": "user@example.com"}, then {{ $json.email }} resolves to user@example.com.

Secure expressions

Expressions are sandboxed for security. Only property access, string concatenation, and a small set of built-in helpers are supported. Arbitrary code execution is not possible through expressions.

Dot Notation for Nested Access

Use dot notation to access nested properties at any depth:

Nested field access
{{ $json.customer.name }}
{{ $json.customer.address.city }}
{{ $json.items[0].product.title }}
{{ $json.metadata.tags[2] }}

Array elements are accessed with bracket notation using zero-based indices. You can chain dot and bracket notation freely.

Where Expressions Are Used

Most text-based configuration fields in the node panel support expressions. You can mix static text with expressions:

Mixed static and dynamic content
Hello {{ $json.customer.name }}, your order #{{ $json.orderId }} has shipped!
Field TypeExpression Support
Text inputsFull support -- static text + expressions
URL fieldsFull support
JSON body fieldsFull support for values
Dropdown selectsNot supported -- use a fixed selection
Boolean togglesNot supported -- use If/Else node instead

Field Picker

You do not need to memorize field paths. The configuration panel includes a field picker that displays the output schema of the upstream node as a navigable tree. Click any field to insert the corresponding expression at the cursor position.

The field picker is available in any expression-enabled input. Click the {} icon next to the input field to open it.

Use the field picker

The field picker prevents typos and shows you exactly what data is available. It is especially useful when working with deeply nested JSON structures or unfamiliar API responses.

Live Preview

When you type an expression, the configuration panel shows a live preview of the resolved value beneath the input field. The preview uses the most recent test output from the upstream node, so you can see exactly what your expression will produce.

If the expression references a field that does not exist, the preview shows undefined and highlights the input with a warning. This helps catch errors before you run the workflow.

Expression Templates

Build complex strings by combining multiple expressions with static text. This is particularly useful for constructing API URLs, email bodies, or Slack messages:

Template examples
# API endpoint with dynamic path
https://api.example.com/users/{{ $json.userId }}/orders/{{ $json.orderId }}

# Slack message
:white_check_mark: *{{ $json.customer.name }}* just placed order #{{ $json.orderId }} for ${{ $json.total }}

# SQL query
SELECT * FROM orders WHERE customer_id = '{{ $json.customerId }}' AND status = 'pending'

SQL injection

When building SQL queries with expressions, prefer using parameterized queries in the Database node rather than string interpolation. The example above is for illustration only.

Subflow Expressions

When a workflow runs as a subflow (invoked by a Subflow node in a parent workflow), the inputs passed by the parent are available through the $subflow variable:

Subflow expression syntax
{{ $subflow.contactEmail }}
{{ $subflow.companyName }}
{{ $subflow.options.sendNotification }}

The $subflow variable contains only the inputs defined in the subflow's trigger configuration. It is separate from $json, which still refers to the upstream node's output within the subflow.

$json vs $subflow

Inside a subflow, $json refers to the previous node's output (as usual), while $subflow refers to the parameters passed from the parent workflow. They are independent and can be used together.

Available Variables

VariableDescription
$jsonOutput of the immediately upstream node
$subflowInput parameters passed from a parent workflow (only available in subflows)
$executionIdUnique identifier for the current workflow execution
$timestampCurrent Unix timestamp in milliseconds
$workflowIdIdentifier of the current workflow