Knowing how to pass data between nodes in n8n is at the heart of building smart, reliable, and efficient workflows. Whether you're automating emails, syncing databases, or building an intelligent chatbot, data has to flow logically from one node to another. This guide will walk you through the correct way to pass and reference data across nodes in n8n, using clear examples and practical tips to help you build robust automations.
Understanding the n8n Data Flow
Each node in n8n, when executed, outputs data in JSON format. This data is temporarily stored in memory and becomes available to subsequent nodes for use. The most common mistake new users make is not understanding how to reference this data in later nodes.
n8n uses a consistent pattern to access data across nodes using expressions. These are dynamic JavaScript-like snippets that evaluate at runtime.
Here’s the basic syntax:
{{ $json["fieldName"] }}
But to pull data from previous nodes properly, you'll often use this:
{{ $node["NodeName"].json["fieldName"] }}
The Right Way to Pass Data Between Nodes
Let’s break down several correct methods to pass and use data in n8n workflows.
1. Using Expressions in Fields
Most node parameters in n8n (like "Email To", "Webhook Response", "Filename") allow you to click the gear icon and switch the field to use an expression. This is where you reference data from earlier nodes.
Example:
Let’s say you use the HTTP Request node and it returns a JSON response like:
{
"user": {
"email": "user@example.com"
}
}
In the next node (e.g., "Send Email"), you can set the "To" field as:
{{ $node["HTTP Request"].json["user"]["email"] }}
This pulls the email address and uses it dynamically.
2. Accessing Data from Previous Nodes
n8n provides several helper variables:
$json— data from current node$node["NodeName"].json— data from a specific previous node$item()— access data from a specific item in a multi-item flow, usually inside loops$items()— access arrays from other items
Tip:
Use $node["NodeName"] when working with data across multiple branches or conditional paths.
3. Using Set Node to Structure Data
Sometimes you want to clean or restructure incoming data before passing it to another node. The Set node lets you define new key-value pairs using expressions.
Steps:
- Add a Set node after your data source.
- Under "Values to Set", click "Add Value", choose a name like
username. - Use the expression:
{{ $node["Previous Node"].json["user"]["name"] }}
This makes the workflow clearer and modular.
4. Using Merge Node to Combine Paths
If you have two different branches like an HTTP request and a data transformer, and both output data you want in a single node, use the Merge node.
Merge Modes:
- Append: Combines all items
- Merge By Index: Merges arrays based on index
- Multiplex: Creates permutations (advanced use)
For most linear workflows, use Merge by Index to combine items side by side into one node.
Table describing merge modes:
| Merge Mode | Description |
|---|---|
| Append Items | Combines outputs into one array |
| Merge by Index | Merges item 0 from each input, item 1 from each input… |
| Multiplex | All combinations of inputs |
5. Using Function Node to Manipulate Data
If you're dealing with complex data structures or need conditional logic, the Function node gives you full JavaScript control. You return data in an array like:
return [
{
json: {
name: $node["Set"].json["username"],
timestamp: new Date().toISOString()
}
}
];
Function nodes are perfect for situations where you want to generate new fields, filter items, or transform nested arrays before passing the data forward.
Mini Use Case: Automate a Personalized Email from a Form
- Trigger: Webhook node receives form submission.
- Transform: Set node extracts name and email.
- Enrich: HTTP request fetches user data with email.
- Email: Send Email node uses:
To:{{ $node["Set"].json["email"] }}Body:Hi {{ $node["Set"].json["name"] }}, thanks for signing up!
With just four nodes and smart data referencing, you can build a clean, dynamic automation.
Debugging Tips for Data Passing
- Use the "Execute Node" feature to run one node at a time and inspect the output.
- Check the JSON tab for exact structure—it helps avoid typos in field names.
- Always label your nodes clearly; complex expressions are easier to manage when names make sense.
- Use Error Handling nodes or if conditionals to catch null or missing data.
Recommendations for Clean Data Flow
- Use the Set node early to flatten or prepare data.
- Avoid chaining too many expressions in one node—it becomes hard to debug.
- Keep variable names consistent across nodes to reduce complexity.
- Regularly use the [$node["YourNodeName"]] pattern instead of $json to prevent scope errors.
Related Automations to Explore
If you're mastering how to pass data between nodes in n8n, you may also enjoy these hands-on guides:
- Complete guide to n8n triggers (chat, webhook, email, slack, telegram and whatsapp)
- Create a fully functional chat agent using n8n
- Create an email automation agent in n8n
FAQ
How do I reference data from a previous node in n8n?
Use {{ $node["NodeName"].json["fieldName"] }} to pull data from a specific node. Replace NodeName with the exact label of the node you're referencing.
Can I access nested fields like an object inside an array?
Yes, but you’ll need to loop through the array using a Function or Code node or use an expression like: {{ $node["Node"].json["items"][0]["value"] }}.
What if the data doesn’t exist in the specified path?
n8n will return undefined. You can guard this using conditional logic like {{ $node["Node"].json["field"] || "default value" }}.
Is it possible to pass binary data between nodes?
Yes, binary data (like files) can be passed, but not all nodes support it natively. Use nodes like "Move Binary Data" or "Write Binary File" to manage it across steps.
Can I merge data from two nodes into one?
Absolutely. Use the Merge node in "Merge By Index" or "Append" mode depending on how you want to combine outputs.
Mastering how to pass data between nodes in n8n unlocks the full potential of the platform. Once you get familiar with expressions, helper variables, and data-debugging tools, your workflows will be cleaner, faster, and easier to maintain.
Copy-paste templates.
Beginner friendly.