Every node in a workflow can reference data produced by earlier steps. You do this with template expressions — double-curly-brace placeholders likeDocumentation Index
Fetch the complete documentation index at: https://docs.spojit.com/llms.txt
Use this file to discover all available pages before exploring further.
{{ something }} — anywhere in a node’s configuration (prompts, headers, body, connector arguments, etc.).
This page covers:
- The two data sources: the trigger payload and step outputs
- How to name a step’s output so other nodes can reference it
- Type preservation vs string interpolation
- Common pitfalls
The two data sources
There are only two things you can reference from a template expression.1. The trigger payload — {{ input }}
Whatever data started the workflow is available under the name input. This is:
- The webhook body, for webhook-triggered runs
- The input data you pass to a manual run
- (Soon) the context object for scheduled runs
{{ input.customer_id }}→"cus_123"{{ input.order.total }}→99.99{{ input }}→ the whole object
2. Previous step outputs
Any node upstream of the current one (connected via the graph) can expose its output to downstream nodes — but only if you give the step an output variable name in its properties panel. If you don’t set an output variable, the step’s result is still computed but it’s stored under a hard-to-use autogenerated name. Always set an output variable when a downstream node needs to reference the result.Setting an output variable
- Click the node whose output you want to reference
- Find the Output Variable field in its properties panel (all node types that produce output have this)
- Enter a readable identifier — e.g.
user_lookup,agent_result,parsed_csv - In a downstream node, reference it:
{{ user_lookup }},{{ agent_result }},{{ user_lookup.id }}, etc.
What’s inside a step output
The shape depends on the node type. The most common ones:AI Agent (Connector node in Agent mode)
The bound value is the agent’s primary output:- Without a Response Schema —
{{ agent_result }}is the AI’s text answer (a string). - With a Response Schema —
{{ agent_result }}is the structured object the schema defined; address fields directly:{{ agent_result.userName }},{{ agent_result.items[0].id }}, etc.
Connector in Direct mode
{{ connector_result }} is the parsed tool payload. For HTTP-style tools that’s { data, status, headers, statusText } — drill into the response body with {{ connector_result.data }} and the status code with {{ connector_result.status }}. For other tools the shape is whatever the tool returned — check the connector’s documentation.
Knowledge — Query mode (RAG)
Same rule as AI Agent: without a Response Schema,{{ query_result }} is the synthesised answer string; with a schema it’s the structured object.
Knowledge — Embed mode
{{ embed_result }} is { chunkCount, collectionName, documentType }.
Transform, Condition, Loop, Human Approval, Send Email, etc.
Each node type produces data in the shape documented on its node page. Open the specific node page under Node Types for details.Type preservation
Templates come in two flavors:Standalone expression — type preserved
When the entire value of a field is a single{{ ... }}, the resolver returns the original type without string conversion:
total resolves to a number (99.99) and items to an array — not to strings. This is critical when downstream systems expect typed JSON.
Mixed with text — coerced to string
When templates are mixed with literal text, everything becomes a string:"Hi Alice, your order total is 99.99." — numbers and objects get serialized to JSON inline.
Example — chaining nodes
A workflow that receives a webhook, asks an AI agent to process the payload, then returns an HTTP response:joke
Response node — Body:
Common pitfalls
Referencing a step before setting its output variable
{{ joke }} returns null (and renders as the literal string "null" in mixed contexts) if no upstream node has output variable joke. Check the output variable is set on the correct node.
Forgetting to save and re-compile
Edits to node configuration are saved to the canvas; the compiled version of the workflow graph — what webhooks actually run — is regenerated when the workflow compiles. This happens automatically on Save and when you click Run. If you edit directly via API and skip compile, webhooks will keep running the old compiled version.Using {{ result }} without specifying which step
result is not a reserved name. If no node has outputVariable: result, this resolves to null. Always name your variables per-step ({{ agent_result }}, {{ user_lookup }}, etc.).
Nested template expressions
{{ {{ foo }}.bar }} doesn’t work — templates don’t compose. If you need dynamic path access, compute the full path in an upstream Transform node and store it as a single string variable.
JSON syntax with templates
In a Response node’s body or any other JSON field:"value": "{{ someStep }}"— works; quotes mark this as a string-or-object slot, the resolver preserves type if the whole value is one template"value": {{ someStep }}— breaks the JSON parser in the editor; wrap templates that fill whole values in quotes
Path syntax cheat sheet
| Expression | What it resolves to |
|---|---|
{{ input }} | the whole trigger payload |
{{ input.user.name }} | nested object access |
{{ input.items[0] }} | array index |
{{ input.items[0].price }} | nested index + field |
{{ step_name }} | whole output of a step with outputVariable: step_name |
{{ step_name.field }} | field inside that step’s output |