APIs love to return arrays, but n8n processes items one at a time. You call an endpoint and receive a response with 50 customers nested inside a data array. That single response becomes one n8n item containing all 50 records packed together. Your downstream nodes see just one item, not 50. They cannot process each customer individually, send personalized emails, or route records based on their properties.
The Split Out node solves this mismatch. It takes a single item containing an array and separates it into multiple individual items. Each array element becomes its own item flowing through the workflow independently.
The Array Problem in Workflows
Most external data arrives as arrays inside larger objects. A CRM returns contacts within a results field. A webhook delivers orders within a payload.items array. A database query returns rows bundled together. Without a way to unpack these arrays, you cannot:
- Process each record through conditional logic
- Send individual API calls per record
- Filter specific items based on their properties
- Route different records to different destinations
You could write JavaScript in a Code node to handle this, but the Split Out node provides a cleaner, zero-code solution that anyone on your team can understand and maintain.
What the Split Out Node Does
The Split Out node transforms data structure, not content:
- Extracts array elements from a specified field
- Creates separate items for each array element
- Optionally preserves parent data alongside each split item
- Handles nested paths using dot notation
- Supports binary data when working with files
Think of it like unpacking a box of individually wrapped items. The box (parent object) may contain useful information (shipping label, packing slip), but you need access to each item inside to actually work with them.
What Youβll Learn
- When to use Split Out versus Loop Over Items, Code node, or Aggregate
- Step-by-step configuration for extracting arrays into items
- How to preserve parent fields so split items retain context
- Working with nested arrays and complex data structures
- The inverse relationship with the Aggregate node
- Common mistakes that cause empty outputs or lost data
- Real-world patterns for API responses, webhooks, and batch processing
When to Use the Split Out Node
Before diving into configuration, understand when Split Out is the right choice versus other data manipulation nodes.
| Scenario | Best Choice | Why |
|---|---|---|
API returns array in data field, need individual items | Split Out | Extract array elements into separate items |
| Process 100 records in batches of 10 | Loop Over Items | Batch processing with controlled iteration |
| Combine multiple items back into single array | Aggregate | Inverse of Split Out |
| Complex array transformation with logic | Code node | Full JavaScript control |
| Filter certain array elements before processing | Split Out + Filter | Split first, then filter individual items |
| Route different items to different branches | Split Out + If | Split first, then route by conditions |
Rule of thumb: Use Split Out when you need to convert an array field into separate workflow items. Use Loop Over Items when you need controlled batch processing with delays or rate limiting. Use Code node when your transformation requires custom logic beyond simple extraction.
Split Out vs Loop Over Items: The Key Distinction
This comparison confuses many users. Both nodes deal with multiple records, but they serve different purposes.
Split Out transforms data structure. One item containing an array becomes multiple items. The node executes once and outputs all items immediately.
Loop Over Items controls execution flow. It processes items in batches with the ability to add delays between batches, making it essential for API rate limiting.
| Aspect | Split Out | Loop Over Items |
|---|---|---|
| Primary purpose | Extract array into items | Process items in batches |
| Input | One item with array field | Multiple items already split |
| Output timing | All items at once | Batches over time |
| Use with delays | No | Yes |
| Rate limiting | No | Yes |
Common pattern: Use Split Out first to extract your array, then use Loop Over Items if you need controlled batch processing with delays.
Understanding Array-to-Item Transformation
Before configuring the node, visualize what actually happens when you split out an array.
n8n Data Structure Basics
n8n workflows pass data as arrays of items. Each item is a JSON object. A node receives items, processes them, and outputs items.
[Item 0] β [Node] β [Item 0, Item 1, Item 2]
When an API returns data with an embedded array, you receive one item containing that array:
// One n8n item containing array
{
"status": "success",
"count": 3,
"users": [
{ "id": 1, "name": "Alice" },
{ "id": 2, "name": "Bob" },
{ "id": 3, "name": "Carol" }
]
}
The users array is trapped inside this single item. Downstream nodes see one item, not three users.
What Split Out Produces
After Split Out with field set to users:
// Three n8n items
[
{ "id": 1, "name": "Alice" },
{ "id": 2, "name": "Bob" },
{ "id": 3, "name": "Carol" }
]
Each array element becomes its own item. Three users means three items. Now downstream nodes process each user individually.
Visual Flow
Before Split Out:
βββββββββββββββββββββββββββββββββββββββ
β Item 0 β
β βββββββββββββββββββββββββββββββββββ β
β β status: "success" β β
β β count: 3 β β
β β users: [Alice, Bob, Carol] β β
β βββββββββββββββββββββββββββββββββββ β
βββββββββββββββββββββββββββββββββββββββ
After Split Out (field: users):
βββββββββββββββββ βββββββββββββββββ βββββββββββββββββ
β Item 0 β β Item 1 β β Item 2 β
β id: 1 β β id: 2 β β id: 3 β
β name: "Alice" β β name: "Bob" β β name: "Carol" β
βββββββββββββββββ βββββββββββββββββ βββββββββββββββββ
Notice that status and count disappeared by default. The next section covers how to preserve parent data.
Your First Split Out
Letβs walk through a basic configuration step by step.
Step 1: Add the Split Out Node
- Open your n8n workflow
- Click + to add a node
- Search for βSplit Outβ
- Click to add it to your canvas
- Connect it to your data source
Step 2: Configure the Field
Assume your input looks like this:
{
"response": {
"orders": [
{ "orderId": "A001", "total": 150 },
{ "orderId": "A002", "total": 89 },
{ "orderId": "A003", "total": 245 }
]
}
}
Configure the node:
- Field To Split Out:
response.orders
The node uses dot notation to navigate nested paths. response.orders tells the node to look inside response, then extract the orders array.
Step 3: Test the Node
- Click Test step (or execute the workflow)
- Check the output panel
Expected output (3 items):
[
{ "orderId": "A001", "total": 150 },
{ "orderId": "A002", "total": 89 },
{ "orderId": "A003", "total": 245 }
]
Each order is now its own item. You can filter by total, route high-value orders differently, or process each with an HTTP Request to another system.
Common First-Time Mistakes
Mistake: Field name without path
If your array is nested but you only specify the field name:
β Field: orders
β
Field: response.orders
The node looks for orders at the top level, finds nothing, and returns no items.
Mistake: Using brackets instead of dots
β Field: response["orders"]
β
Field: response.orders
Stick to dot notation for nested paths.
Configuration Deep Dive
The Split Out node offers several options for controlling exactly how arrays become items.
Field To Split Out
What it does: Specifies which field contains the array to extract.
Accepts:
- Simple field names:
items,users,data - Nested paths with dots:
response.data.results,payload.order.lineItems - Expressions for dynamic paths:
{{ $json.arrayField }}
Example configurations:
| Input Structure | Field To Split Out |
|---|---|
{ "users": [...] } | users |
{ "data": { "items": [...] } } | data.items |
{ "response": { "body": { "results": [...] } } } | response.body.results |
Using expressions:
When the field name itself comes from dynamic data:
{{ $json.fieldName }} // If fieldName contains "users", extracts from users array
Include Options
This setting controls what happens to other fields from the parent object. Three options exist:
No Other Fields (Default)
Only the array element data appears in output items. Parent fields like status, count, or metadata are discarded.
When to use: You only need the array contents. Parent data is irrelevant to downstream processing.
All Other Fields
Every field from the parent object gets copied into each output item alongside the array element data.
Input:
{
"status": "success",
"requestId": "req_123",
"users": [
{ "id": 1, "name": "Alice" }
]
}
Output with All Other Fields:
{
"status": "success",
"requestId": "req_123",
"id": 1,
"name": "Alice"
}
When to use: You need parent context (like requestId) preserved with each split item.
Selected Other Fields
Choose specific parent fields to include. Other fields are discarded.
When to use: You need some parent data but not everything. Keeps output clean and reduces data volume.
Destination Field Name
What it does: Changes the output field name containing split data.
By default, split data appears at the root level of each item. With Destination Field Name set:
Without destination field:
{ "id": 1, "name": "Alice" }
With destination field βuserβ:
{
"user": { "id": 1, "name": "Alice" }
}
When to use:
- Avoid field name collisions when including parent fields
- Match expected structure for downstream nodes
- Keep split data organized within each item
Disable Dot Notation
What it does: Treats dots in field names as literal characters, not path separators.
Some APIs return field names containing dots:
{
"api.response.items": [...]
}
With dot notation enabled (default), api.response.items means βlook for api, then response, then items.β This fails.
With dot notation disabled, api.response.items matches the literal field name.
When to use: Your field names actually contain periods as part of the name, not as path separators.
Include Binary
What it does: Preserves binary data (files, images) attached to items during splitting.
When to use: Your items have associated binary data that downstream nodes need access to.
Example: Splitting a list of email attachments where each has binary file data attached.
Preserving Parent Data
One of the most common frustrations with Split Out involves losing context. You split an array and suddenly cannot access the parent objectβs metadata. This section addresses that problem directly.
The Parent Data Loss Problem
Consider this API response:
{
"orderId": "ORD-12345",
"orderDate": "2024-03-15",
"customer": {
"id": "CUST-789",
"name": "Acme Corp"
},
"lineItems": [
{ "sku": "WIDGET-A", "quantity": 5, "price": 10.00 },
{ "sku": "GADGET-B", "quantity": 2, "price": 25.00 }
]
}
You split on lineItems to process each product. But now you need orderId and customer.name for each line item. With default settings, they are gone.
Solution: Include All Other Fields
Set Include to βAll Other Fieldsβ:
Output:
[
{
"orderId": "ORD-12345",
"orderDate": "2024-03-15",
"customer": { "id": "CUST-789", "name": "Acme Corp" },
"sku": "WIDGET-A",
"quantity": 5,
"price": 10.00
},
{
"orderId": "ORD-12345",
"orderDate": "2024-03-15",
"customer": { "id": "CUST-789", "name": "Acme Corp" },
"sku": "GADGET-B",
"quantity": 2,
"price": 25.00
}
]
Each line item now carries its parent order context. You can filter line items while still knowing which order they belong to.
Solution: Include Selected Fields
When you need only specific parent fields, select them individually:
Configuration:
- Include: Selected Other Fields
- Fields to Include:
orderId,customer
Output:
[
{
"orderId": "ORD-12345",
"customer": { "id": "CUST-789", "name": "Acme Corp" },
"sku": "WIDGET-A",
"quantity": 5,
"price": 10.00
}
]
The orderDate field is excluded because it was not selected.
Avoiding Field Name Collisions
What if both parent and array items have a field named id?
{
"id": "parent-id",
"items": [
{ "id": "item-1" }
]
}
With Include All Other Fields, both id values try to exist at the same level. n8n keeps the array elementβs value, overwriting the parentβs.
Solutions:
- Use Selected Other Fields and rename the parent field using an Edit Fields node beforehand
- Use Destination Field Name to nest split data, avoiding collisions
- Transform data with a Code node before splitting
Pattern: Relating Items Back to Parent
After processing split items, you may need to relate results back to their original parent. Include a unique identifier from the parent:
- Split Out with
orderIdincluded - Process each item (enrich, transform, filter)
- Use Merge node to join processed items back to order data
- Or use Aggregate to collect results grouped by
orderId
Working with Nested Arrays
Real-world data often contains arrays nested multiple levels deep. Understanding how to handle these structures prevents confusion.
Single-Level Nesting
Most common scenario. Array exists one level inside the response:
{
"data": {
"users": [...]
}
}
Field To Split Out: data.users
Straightforward dot notation path.
Multi-Level Nesting
Array buried several levels deep:
{
"response": {
"body": {
"content": {
"items": [...]
}
}
}
}
Field To Split Out: response.body.content.items
Just extend the dot notation path.
Arrays Containing Arrays
Complex structure with nested arrays:
{
"departments": [
{
"name": "Engineering",
"employees": [
{ "id": 1, "name": "Alice" },
{ "id": 2, "name": "Bob" }
]
},
{
"name": "Sales",
"employees": [
{ "id": 3, "name": "Carol" }
]
}
]
}
To get individual employees, you need two split operations:
Step 1: Split Out on departments
Output: Two items (Engineering, Sales), each containing their employees array.
Step 2: Split Out on employees (with Include All Other Fields)
Output: Three items (Alice, Bob, Carol), each with their department name preserved.
Pattern: Nested Array Processing
For structures like the above:
- First Split Out extracts top-level array
- Include parent fields to preserve context
- Second Split Out extracts nested array
- Each final item carries full lineage data
Without including parent fields at each step, you lose the relationship between nested items and their containers.
Split Out vs Aggregate: The Inverse Relationship
These two nodes are opposites. Understanding their relationship helps design better workflows.
Aggregate: Items to Array
The Aggregate node takes multiple items and combines them into a single item containing an array.
[Item 0] [Item 1] [Item 2] β [Aggregate] β [{ "items": [Item 0, Item 1, Item 2] }]
Split Out: Array to Items
Split Out takes an item containing an array and separates it into multiple items.
[{ "items": [Item 0, Item 1, Item 2] }] β [Split Out] β [Item 0] [Item 1] [Item 2]
Round-Trip Pattern
A common workflow pattern:
- Receive data with array (e.g., API response)
- Split Out to process each element individually
- Transform, filter, or enrich each item
- Aggregate results back into a single array
- Send combined results downstream (e.g., batch API call)
Visual:
[API Response] β [Split Out] β [Process Each] β [Aggregate] β [Batch API Call]
β β β
1 item with 100 individual 1 item with
100 records items 100 processed records
This pattern lets you work with individual records while maintaining the ability to batch operations.
When to Use Each
| Goal | Node |
|---|---|
| Work with individual records | Split Out first |
| Prepare batch API payload | Aggregate at end |
| Process loop results | Aggregate after loop |
| Unpack API response array | Split Out |
For more on workflow design patterns, see our workflow best practices guide.
Real-World Examples
Example 1: Processing API Response Items
Scenario: You query a CRM API that returns contacts in a data array. You need to check each contactβs email validity and update a database.
Input from HTTP Request:
{
"success": true,
"data": [
{ "id": "C001", "email": "[email protected]", "status": "active" },
{ "id": "C002", "email": "invalid-email", "status": "active" },
{ "id": "C003", "email": "[email protected]", "status": "inactive" }
]
}
Workflow:
- HTTP Request fetches contacts
- Split Out on
data - Filter node keeps only valid emails (regex match)
- If node routes by status
- Database node updates records
Split Out Configuration:
- Field To Split Out:
data - Include: No Other Fields (we only need contact data)
Output (3 items):
[
{ "id": "C001", "email": "[email protected]", "status": "active" },
{ "id": "C002", "email": "invalid-email", "status": "active" },
{ "id": "C003", "email": "[email protected]", "status": "inactive" }
]
Each contact flows through the workflow individually, allowing per-contact logic.
Example 2: E-commerce Order Line Items
Scenario: An order webhook delivers order data with line items. You need to check inventory for each product.
Webhook payload:
{
"orderId": "ORD-5678",
"customerEmail": "[email protected]",
"lineItems": [
{ "sku": "SHIRT-M-BLUE", "quantity": 2 },
{ "sku": "PANTS-32-BLACK", "quantity": 1 },
{ "sku": "SOCKS-PACK-3", "quantity": 5 }
]
}
Workflow:
- Webhook node receives order
- Split Out on
lineItemswith parent fields - HTTP Request checks inventory per SKU
- If node routes out-of-stock items
- Aggregate results
- Send order confirmation or backorder email
Split Out Configuration:
- Field To Split Out:
lineItems - Include: Selected Other Fields
- Fields:
orderId,customerEmail
Output (3 items):
[
{ "orderId": "ORD-5678", "customerEmail": "[email protected]", "sku": "SHIRT-M-BLUE", "quantity": 2 },
{ "orderId": "ORD-5678", "customerEmail": "[email protected]", "sku": "PANTS-32-BLACK", "quantity": 1 },
{ "orderId": "ORD-5678", "customerEmail": "[email protected]", "sku": "SOCKS-PACK-3", "quantity": 5 }
]
Each line item carries order context for downstream processing.
Example 3: Splitting and Reaggregating for Batch Operations
Scenario: Process each record individually but send results as a batch to avoid rate limits.
Workflow:
[Get 100 Records] β [Split Out] β [Enrich Each] β [Aggregate] β [Batch API]
- Database returns 100 records in
resultsarray - Split Out extracts into 100 items
- Each item gets enriched (geocoding, data lookup, etc.)
- Aggregate collects all 100 enriched items
- Single API call sends batch payload
Aggregate Configuration:
- Mode: All Item Data
- Put Output in Field:
enrichedRecords
Final HTTP Request body:
{
"records": {{ $json.enrichedRecords }}
}
One API call with 100 records instead of 100 individual calls.
Example 4: Processing Nested Survey Responses
Scenario: Survey tool returns responses with nested answer arrays.
Input:
{
"surveyId": "SURV-001",
"responses": [
{
"respondentId": "R001",
"answers": [
{ "questionId": "Q1", "value": "Very Satisfied" },
{ "questionId": "Q2", "value": 5 }
]
},
{
"respondentId": "R002",
"answers": [
{ "questionId": "Q1", "value": "Dissatisfied" },
{ "questionId": "Q2", "value": 2 }
]
}
]
}
Two-step split:
Step 1: Split Out on responses
[
{ "respondentId": "R001", "answers": [...] },
{ "respondentId": "R002", "answers": [...] }
]
Step 2: Split Out on answers with Include All Other Fields
[
{ "respondentId": "R001", "questionId": "Q1", "value": "Very Satisfied" },
{ "respondentId": "R001", "questionId": "Q2", "value": 5 },
{ "respondentId": "R002", "questionId": "Q1", "value": "Dissatisfied" },
{ "respondentId": "R002", "questionId": "Q2", "value": 2 }
]
Each answer now carries its respondent context.
Common Mistakes and Troubleshooting
Mistake 1: Wrong Field Path
Symptom: Split Out returns zero items or an error.
Cause: The field path does not match your data structure.
Debug steps:
- Check the input data structure in the previous nodeβs output
- Verify exact field names (case-sensitive)
- Count the nesting levels and match with dot notation
Example fix:
Input: { "response": { "data": { "items": [...] } } }
β Field: items
β Field: data.items
β
Field: response.data.items
Use our workflow debugger to inspect data at each step.
Mistake 2: Losing Parent Data
Symptom: Split items lack context needed for downstream processing.
Cause: Include setting defaults to βNo Other Fields.β
Fix: Change Include to βAll Other Fieldsβ or βSelected Other Fieldsβ and specify the fields you need.
Prevention: Always consider what parent data downstream nodes require before configuring Split Out.
Mistake 3: Confusing Split Out with Loop Over Items
Symptom: You expected batched processing with delays but got instant output.
Cause: Using the wrong node for the job.
When you need Split Out:
- Transform array field into items
- No rate limiting needed
- Instant processing acceptable
When you need Loop Over Items:
- Process items in controlled batches
- Add delays between batches
- Respect API rate limits
Mistake 4: Empty Array Returns No Items
Symptom: Workflow stops with no output from Split Out.
Cause: The array field was empty [] or the field did not exist.
Debug:
- Check if the upstream API returned data
- Verify the array is not empty before splitting
- Add an If node to handle empty arrays gracefully
Pattern for handling empty arrays:
[API Call] β [If: Array Length > 0] β True: [Split Out] β [Process]
β False: [Handle Empty Case]
Mistake 5: Binary Data Not Preserved
Symptom: File attachments or images disappear after splitting.
Cause: βInclude Binaryβ option not enabled.
Fix: Enable Include Binary in the node options when your data includes binary attachments.
Mistake 6: Dot Notation Conflicts
Symptom: Field path not found despite correct-looking configuration.
Cause: Actual field name contains dots (e.g., api.response).
Fix: Enable Disable Dot Notation so the node treats periods as literal characters.
Debug tip: Look at raw JSON output from the previous node. If field names contain periods, disable dot notation.
Pro Tips and Best Practices
1. Name Your Nodes Descriptively
Instead of βSplit Outβ or βSplit Out1β, use names describing what you are splitting:
- βSplit Order Line Itemsβ
- βExtract Users from Responseβ
- βSeparate Survey Answersβ
Clear naming makes workflows self-documenting and easier to debug.
2. Test with Small Datasets First
Before splitting 10,000 records, test with 5. Verify output structure matches expectations. Large splits can be slow to inspect and may hide structural issues in the volume.
3. Consider Downstream Data Needs Early
Before configuring Split Out, ask: βWhat data will downstream nodes need?β Include those parent fields from the start rather than debugging missing data later.
4. Use Expressions for Dynamic Validation
Add an If node before Split Out to verify the array exists and has items:
{{ $json.data && $json.data.length > 0 }}
This prevents silent failures from empty arrays. Test expressions using our expression validator.
5. Combine with Aggregate for Round-Trips
When you split, process, and need results combined:
Split Out β Process β Aggregate
This pattern appears constantly in production workflows.
6. Document Your Field Paths
Complex nested paths like response.body.data.results[0].items are hard to remember. Add a sticky note to your workflow documenting the expected input structure.
7. Handle Errors Gracefully
Items that cause errors in downstream nodes will not reach your Aggregate. Consider error handling branches to ensure complete processing. See our workflow best practices for error handling patterns.
For complex splitting scenarios, our workflow development services and consulting packages can design robust data transformation pipelines.
Frequently Asked Questions
What is the difference between Split Out and Loop Over Items in n8n?
Split Out transforms data structure by converting an array field into separate workflow items. It runs once and outputs all items immediately. Use it when you need individual items from an array to flow through your workflow.
Loop Over Items (also called Split In Batches) controls execution flow by processing items in configurable batch sizes with optional delays between batches. Use it when you need to respect API rate limits or process large datasets without overwhelming downstream services.
The common pattern is using both: Split Out first extracts your array into items, then Loop Over Items processes those items in controlled batches. For example, an API returns 500 contacts in a data array. Split Out creates 500 items. Loop Over Items then processes them 50 at a time with 1-second delays between batches.
How do I preserve parent fields when splitting an array in n8n?
Set the Include option to either βAll Other Fieldsβ or βSelected Other Fieldsβ in your Split Out node configuration.
With βAll Other Fields,β every field from the parent object gets copied into each split item. With βSelected Other Fields,β you choose specific fields to include. For example, if your input has orderId, customerName, and a lineItems array, and you split on lineItems:
- No Other Fields: Each item has only line item data (sku, quantity, price)
- All Other Fields: Each item has orderId, customerName, plus line item data
- Selected Other Fields (orderId): Each item has orderId plus line item data
Always consider what downstream nodes need. If youβll filter or route items but later need to reference the parent order, include the parent identifier field at minimum.
Why does my Split Out node return zero items?
Three common causes:
-
Wrong field path: Your Field To Split Out does not match the actual data structure. Check nested paths carefully.
data.itemsdiffers fromresponse.data.items. Examine the input nodeβs output to verify the exact path. -
Empty array: The array exists but contains no elements. An empty
[]produces zero output items. Add an If node before Split Out to check{{ $json.arrayField.length > 0 }}and handle the empty case. -
Field does not exist: The field name is misspelled or the data structure differs from expected. Check for typos and case sensitivity. If your field name contains periods (like
api.response), enable βDisable Dot Notation.β
Debug by checking the Split Out nodeβs input panel to see exactly what data it received, then compare against your field configuration.
Can I split nested arrays within arrays in n8n?
Yes, but it requires multiple Split Out nodes in sequence.
Consider data like departments containing employees:
{ "departments": [{ "name": "Engineering", "employees": [...] }, ...] }
Step 1: Split Out on departments produces items for each department.
Step 2: Split Out on employees (with Include All Other Fields) produces items for each employee, carrying their department data.
The key is enabling βInclude All Other Fieldsβ at each step so nested items retain their parent context. Without this, you lose the relationship between employees and their departments. For very complex nested structures, a Code node may provide more control using JavaScript array methods like flatMap().
How do I process split items individually and then combine the results?
Use the Split Out β Process β Aggregate pattern:
- Split Out extracts your array into individual items
- Processing nodes (HTTP Request, Filter, Set, etc.) work on each item
- Aggregate node collects all processed items back into a single array
For example, splitting 50 customer records, enriching each with an external API lookup, then aggregating results for a batch database insert:
[Get Customers] β [Split Out: customers] β [HTTP: Enrich Each] β [Aggregate: All Item Data] β [Database: Batch Insert]
The Aggregate node configuration should use βAll Item Dataβ mode with an output field name like enrichedCustomers. Your database node then receives one item containing all 50 enriched records in an array, perfect for batch operations.
This pattern maximizes efficiency: individual processing where needed, batch operations where supported.