Skip to content
Docs
flero.ai

Referencing data

The five reference roots Flero understands inside an expression, in detail.


$node["NodeName"], another node's output

{{ $node["HTTP Request"].json.body.email }}
  • The key is the display name of the node, exactly as it appears on the canvas (case-sensitive).
  • Wrap the name in straight double quotes inside square brackets: $node["HTTP Request"].
  • Both .json.<path> and .output.<path> work, they're synonyms. Pick one for consistency in your workflow.
  • .json (or .output) on its own returns the whole output object (useful for passing through unchanged).

The synonym $nodes["…"] exists for the alternate matching path (runtime ID). Stick to $node[…] in human-written expressions.

What happens if the node hasn't run yet?

The expression resolves to an [EXPR-ERROR: Node "X" not found. Available: [list of names]] marker. Common causes:

  • Typo in the name.
  • The node is on a branch that wasn't taken (e.g. the If went false but the expression is in a node on the true path).
  • The node is downstream, you can't reference a node that hasn't run yet.

The error marker lists the available node names so you can spot the typo.


$trigger, the data that started the run

{{ $trigger.body.userId }}

The shape of $trigger depends on the trigger type:

Webhook trigger

{
  "body": { ... },      // parsed JSON (or raw string if non-JSON)
  "headers": { ... },   // request headers, lowercased
  "query": { ... },     // query-string parameters
  "method": "POST",
  "path": "/webhook/abc",
  "timestamp": "2026-05-15T10:00:00Z"
}

Schedule trigger

{
  "scheduledTime": "2026-05-15T09:00:00Z",
  "cronExpression": "0 9 * * *",
  "previousScheduledTime": "2026-05-14T09:00:00Z"
}

Form trigger

{
  "<field1>": "value",
  "<field2>": 42,
  "<fileField>": { "filename": "x.pdf", "size": 123, "contentType": "application/pdf", "data": "<base64>" }
}

Manual / API trigger

Whatever you passed as the request body (empty object by default).

Connector event trigger

Service-specific. See the connector's page in the Connector catalog.


$workflow, workflow-level metadata and variables

{{ $workflow.name }}
{{ $workflow.id }}
{{ $workflow.version }}
{{ $workflow.settings.timeout }}
{{ $workflow.metadata.department }}
{{ $workflow.variables.lastSyncTime }}

Common fields:

Path What it returns
$workflow.id UUID of this workflow
$workflow.name Display name
$workflow.version Current version string
$workflow.settings.<key> Workflow settings (timeout, concurrency, …)
$workflow.metadata.<key> Custom metadata you've set in workflow settings
$workflow.variables.<key> Variables set by a Set node with scope workflow

$workflow.variables is the persistence escape hatch, a key you set in one run is readable in subsequent runs (admin-enabled feature).


$env.VARIABLE_NAME, workspace environment variables

{{ $env.API_BASE_URL }}
{{ $env.STRIPE_PUBLIC_KEY }}

Workspace environment variables are managed under Settings → Workspace → Variables. They're available to every workflow in the workspace and never appear in workflow JSON.

Don't store secrets here that need encryption-at-rest. For secrets, use Credentials instead, they're encrypted and have audit logging.

Acceptable use of $env:

  • Base URLs (API_BASE_URL, WEBHOOK_HOST)
  • Public configuration that varies between environments (ENVIRONMENT, DEFAULT_LOCALE)
  • Public keys / IDs (Stripe publishable key, Google Maps API key with referrer restrictions)

$input, the current node's input

{{ $input.firstName }} {{ $input.lastName }}

$input is the data flowing into this node. Useful inside Loop bodies and Code nodes where it represents the current item / current invocation.

// Inside a Loop body, $input is the current item
{{ $input.email }}

// Inside a Code node, input is the same data accessible programmatically
return { ...input, processed: true };

In simple linear chains, $input and $node["<previous node>"].json resolve to the same thing, $input is just shorter.


Combining references

You can interpolate any number of references into a single string:

GET {{ $env.API_HOST }}/users/{{ $trigger.body.userId }}/orders/{{ $node["Lookup"].json.orderId }}

And navigate through complex paths:

{{ $node["Process payments"].json.results[0].transactions[0].amount }}


Found something out of date? This page lives in the Flero docs content set.