If you’re exploring workflow automation with n8n, understanding how to use JSON effectively is essential. JSON (JavaScript Object Notation) is the backbone of data exchange in n8n. Whether you’re connecting APIs, transforming data, or building complex workflows, mastering JSON lets you unlock n8n’s full potential and streamline your automation tasks.
In this guide, we’ll take a deep dive into working with JSON inside n8n. We’ll start with the basics of JSON and its role in n8n, then move into practical tips, common challenges, and real-world examples. By the end, you’ll feel confident handling JSON data in your workflows, enabling you to build smarter and more flexible automations.
What is JSON and Why It Matters in n8n
What is JSON?
JSON, short for JavaScript Object Notation, is a widely used, human-readable format for storing and exchanging data. Its popularity comes from its simplicity, versatility, and compatibility with nearly every programming language and tool — including n8n.
At its core, JSON consists of key-value pairs, where keys are strings and values can be strings, numbers, booleans, arrays, or even nested objects. Here is a simple JSON object representing a person:
{
"name": "Alice",
"age": 30,
"isMember": true,
"interests": ["reading", "traveling", "coding"]
}
JSON is text-based but structured, making it easy for both humans and machines to read and write.
Why JSON is Central to n8n
In n8n, every piece of data flowing between nodes is formatted as JSON. When you connect a node that fetches data from an API or a database, the result arrives as JSON. When you transform data or prepare a payload to send somewhere else, you’re working with JSON.
This is crucial because:
- Universal format: Most APIs, databases, and services use JSON, so understanding JSON means you can work with almost any external system.
- Flexible and expressive: JSON can represent simple flat data or complex nested structures — perfect for real-world automation where data is rarely simple.
- Human-readable: JSON is easy to inspect during debugging or development.
If you want to unlock the full power of n8n, mastering how to manipulate JSON is a must.
Accessing JSON in n8n
How Data Flows as JSON in n8n
When n8n runs a workflow, each node receives data as an array of JSON objects called items
. Each object in the array represents one unit of data, like a row from a spreadsheet or an individual API record.
For example, if you use an HTTP Request node to fetch a list of users, you might get back JSON like:
[
{ "id": 1, "name": "Alice", "email": "alice@example.com" },
{ "id": 2, "name": "Bob", "email": "bob@example.com" }
]
Each object is one item
. Downstream nodes receive this array and can process or transform it.
Viewing JSON Data in n8n
n8n’s user interface makes inspecting JSON easy. After running a node, you can click it and open the Output tab. There you have two views:
- Table View: Shows the data in a tabular format, great for a quick glance.
- JSON View: Displays the full raw JSON object for each item, helpful for detailed inspection.
For example, clicking on the HTTP Request node output reveals the exact JSON the API returned. This visibility helps you understand the data structure before you write any code or set fields in later nodes.
Understanding the items
Array
Inside nodes like the Function node, you work directly with the items
array. Each element looks like this:
{
json: {
id: 1,
name: "Alice",
email: "alice@example.com"
}
}
Notice that the actual data is inside the json
property. This structure allows n8n to include additional metadata if needed, but for most workflows, you only care about item.json
.
Parsing and Manipulating JSON with the Function Node
The Function node in n8n lets you write JavaScript to manipulate JSON data directly. This is incredibly powerful because you can customize data exactly as you want.
Basic Example: Adding a New Field
Suppose you fetched user data and want to add a new field nameUpperCase
that contains the uppercase version of the user’s name. Here’s how you do it:
items.forEach(item => {
if (item.json.name) {
item.json.nameUpperCase = item.json.name.toUpperCase();
}
});
return items;
Explanation
- The
items.forEach()
function iterates over each JSON object. - For each item, it checks if the
name
field exists to avoid errors. - It adds a new key,
nameUpperCase
, with the uppercase string. - Finally, you return the modified
items
array for the next node.
More Complex Manipulations
You can do far more complex transformations in the Function node:
- Filtering records (
items.filter(...)
) - Mapping and reshaping JSON (
items.map(...)
) - Combining fields
- Calculating values (e.g., totals, averages)
- Parsing or formatting dates
Here’s an example where you filter out users under 18 and add an isAdult
flag:
items = items.filter(item => item.json.age >= 18);
items.forEach(item => {
item.json.isAdult = true;
});
return items;
Best Practices in Function Node
- Always return
items
. - Handle cases where fields might be missing.
- Avoid mutating
items
outside the function scope. - Comment your code for readability.
Creating JSON Data Manually
Sometimes you want to create JSON data from scratch or add new data fields without code. The Set node is perfect for this.
Using the Set Node to Build JSON
The Set node lets you create or overwrite JSON fields. You simply add key-value pairs directly in the UI.
For example, to create a user record, you might add:
Field | Value |
---|---|
name | John Smith |
email | john@example.com |
isActive | true |
signupDate | 2025-07-01 |
Behind the scenes, n8n builds the following JSON object:
{
"name": "John Smith",
"email": "john@example.com",
"isActive": true,
"signupDate": "2025-07-01"
}
Dynamic Values with Expressions
The Set node supports expressions, so you can pull values from earlier nodes or system variables:
For example, you can set signupDate
to the current date:
{{$now}}
Or use data from a previous node:
{{$json["userEmail"]}}
Data Types Matter
- Strings should be entered as plain text.
- Numbers and booleans should be input without quotes.
- Dates are strings but can be formatted with expressions.
Being mindful of data types ensures your JSON payloads work correctly in downstream nodes.
Working with Nested JSON
JSON data often comes nested—objects inside objects, arrays within objects—reflecting complex real-world data.
Example Nested JSON
Imagine an API returns this user profile:
{
"user": {
"id": 101,
"profile": {
"firstName": "Emily",
"lastName": "Clark",
"address": {
"street": "123 Maple St",
"city": "Springfield",
"postalCode": "12345"
}
}
},
"orders": [
{ "id": 1, "amount": 49.99 },
{ "id": 2, "amount": 29.99 }
]
}
Accessing Nested Fields
Inside a Function node, you can access nested fields with dot notation:
let firstName = item.json.user.profile.firstName;
let city = item.json.user.profile.address.city;
Modifying Nested JSON
You can also modify nested fields:
item.json.user.profile.address.postalCode = "54321";
Flattening Nested JSON
Sometimes nested JSON is harder to work with. You can “flatten” it by pulling nested values to the top level:
item.json.firstName = item.json.user.profile.firstName;
item.json.city = item.json.user.profile.address.city;
item.json.orderCount = item.json.orders.length;
This makes later processing or exporting easier.
Looping Over Nested Arrays
If you want to process arrays inside JSON, such as the orders
list, use loops:
item.json.orders.forEach(order => {
order.amountWithTax = order.amount * 1.2; // Add 20% tax
});
Or, to extract total amount of all orders:
let total = item.json.orders.reduce((sum, order) => sum + order.amount, 0);
item.json.totalOrderAmount = total;
Dealing with Missing Nested Fields
To avoid errors, use optional chaining (supported in modern JavaScript):
let postalCode = item.json.user?.profile?.address?.postalCode || "Unknown";
This prevents crashes if any level of nesting is missing.
Using JSON in HTTP Request Node
One of the most common ways to use JSON in n8n is when working with APIs using the HTTP Request node.
Sending JSON Payloads
When you want to send data, such as creating a new user on a service, you typically use a POST or PUT request.
Steps to send JSON in HTTP Request node:
- Set the HTTP Method to POST or PUT.
- Under Body Parameters, choose JSON.
- Use the UI or expressions to set the JSON keys and values.
- Add the header
Content-Type: application/json
.
Example: You send this JSON to an API to create a user:
{
"name": "Alice",
"email": "alice@example.com",
"subscribed": true
}
The HTTP Request node automatically sends this with the correct headers.
Receiving and Parsing JSON Responses
Most APIs respond with JSON. The HTTP Request node automatically parses the response JSON and passes it to the next node in the items
array.
You can inspect the response in the output tab to understand what fields are available for further processing.
Converting Data to/from JSON
Sometimes your data isn’t in JSON object form but as strings or other types.
Parsing JSON Strings
If a node returns a JSON string (a JSON object serialized as text), you must parse it to use it as JSON:
items.forEach(item => {
if (item.json.rawDataString) {
item.json.parsedData = JSON.parse(item.json.rawDataString);
}
});
return items;
Stringifying JSON Objects
In rare cases, you might need to convert JSON back into a string, for example, to log it or send as plain text:
items.forEach(item => {
item.json.stringified = JSON.stringify(item.json);
});
return items;
Debugging Tips for JSON in n8n
Working with JSON can sometimes cause errors or unexpected results. Here are some tips to debug and fix issues quickly:
- Validate your JSON: Use online JSON validators or tools like jsonlint.com to check structure.
- Inspect node output: Always check the Output tab in nodes to see actual JSON.
- Log inside Function nodes: Use
console.log(item.json)
or more detailed logs to understand your data. - Use try/catch: Wrap risky code in try/catch blocks to catch errors gracefully:
try {
// risky code here
} catch (error) {
console.error(error);
}
- Watch out for undefined fields: Always check if a field exists before using it to avoid runtime errors.
- Test with sample data: Use the Set node to create mock data for testing.
- Check types: Ensure booleans, numbers, and strings are used correctly.
Real-World Example Workflow: API Data Transformation
Let’s build a practical example to tie it all together.
Scenario:
You want to:
- Fetch a list of users from an API.
- Combine their first and last names into a full name.
- Filter out users who are not active.
- Send the cleaned and formatted data to another API.
Step 1: HTTP Request Node — Fetch Users
Set up an HTTP Request node:
- Method: GET
- URL:
https://api.example.
com/users
Assume the API returns:
[
{ "first_name": "Alice", "last_name": "Smith", "active": true },
{ "first_name": "Bob", "last_name": "Jones", "active": false }
]
Step 2: Function Node — Format and Filter Data
Add a Function node with this code:
items = items.filter(item => item.json.active === true);
items.forEach(item => {
item.json.fullName = `${item.json.first_name} ${item.json.last_name}`;
});
return items;
This filters out inactive users and adds a new field fullName
.
Step 3: HTTP Request Node — Send Data
Use another HTTP Request node to POST the cleaned data:
- Method: POST
- URL:
https://api.another-service.com/receive-users
- Body Parameters: JSON
- Use expression to pass the full
items
array or map necessary fields.
Conclusion
JSON is the universal language of data in n8n workflows. Whether you’re connecting APIs, transforming records, or sending payloads, mastering JSON gives you full control over your automations.
To summarize:
- Understand that all data in n8n flows as JSON inside the
items
array. - Use the Function node to manipulate JSON dynamically with JavaScript.
- Use the Set node to create or update JSON data without code.
- Handle nested JSON carefully by accessing fields with dot notation or flattening.
- Use the HTTP Request node to send and receive JSON from APIs.
- Convert data to and from JSON strings when needed.
- Debug with careful inspection, logging, and validation.
With these skills, you can automate complex workflows that move and transform data between any system that speaks JSON.