Flatten
Explode the list at a field path into one record per element, keeping the parent's other fields.
Explode the list at a field path into one record per element, keeping the parent's other fields.
When to use it
Expand a list into separate records while preserving the parent’s other fields. Use it before row-based processing of an array. Check the output field choice to avoid replacing another meaningful field on the parent.
Add and configure
- Add Flatten from the workflow step picker.
- Give the step a recognisable name and connect its required inputs.
- Set the options below. Nested names identify fields within an object or a list item.
- Validate the recipe, inspect the test result, then run it on the intended data.
The step identifier used in the editor’s code view is flatten.
Settings
| Setting | Accepted value | Required | Default | What it controls |
|---|---|---|---|---|
Index Field (index_field) | string; minimum characters 1 or null | No | null | Field that receives each element's 0-based position in its list. |
Into (into) | string; minimum characters 1 or null | No | null | Top-level field that receives each element; the list itself is dropped. Omitted: the element replaces the list where it was. |
Keep Empty (keep_empty) | boolean | No | false | Keep a record whose list is missing, null or empty as one row with a null element, instead of dropping it. |
Max Output Records (max_output_records) | integer; minimum 1; maximum 500000 | No | 100000 | The step fails (output_cap) rather than emit more rows than this. |
Path (path) | string | Yes | Not specified | Plain field path of the list to explode (e.g. $.items, $.order.lines; a trailing [*] is accepted). Nested lists are flattened by chaining steps. |
Spread (spread) | boolean | No | false | Merge each (object) element's fields into the row instead — an element field wins over a parent field of the same name; the list itself is dropped. |
Inputs and outputs
| Direction | Port | Content | Required | Multiple records |
|---|---|---|---|---|
| Inputs | in | records | Yes | Yes |
| Outputs | out | records | Yes | Yes |
Effects, testing, and recovery
Transforms or passes records without a declared external side effect.
The declared preview behaviour is to execute this step. Reads, processing, or model usage can therefore be real. Read dry runs before using a preview with live connections.
No duplicate-prevention key is declared for this step. The step declares safe replay for its supported recovery path.
Example: One row per order line
Step settings:
{
"into": "line",
"path": "$.lines"
}
Input records:
[
{
"lines": [
{
"sku": "a"
},
{
"sku": "b"
}
],
"order": "o1"
}
]
Expected output for this example:
[
{
"line": {
"sku": "a"
},
"order": "o1"
},
{
"line": {
"sku": "b"
},
"order": "o1"
}
]
Example: Unwrap search hits into rows, with their rank
Step settings:
{
"index_field": "rank",
"path": "$.matches",
"spread": true
}
Input records:
[
{
"matches": [
{
"text": "first"
},
{
"text": "second"
}
],
"query": "q"
}
]
Expected output for this example:
[
{
"query": "q",
"rank": 0,
"text": "first"
},
{
"query": "q",
"rank": 1,
"text": "second"
}
]
Example: Explode tags in place, keeping untagged posts
Step settings:
{
"keep_empty": true,
"path": "$.tags"
}
Input records:
[
{
"post": 1,
"tags": [
"red",
"blue"
]
},
{
"post": 2,
"tags": []
}
]
Expected output for this example:
[
{
"post": 1,
"tags": "red"
},
{
"post": 1,
"tags": "blue"
},
{
"post": 2,
"tags": null
}
]
Check the result
Inspect the selected run’s status, counts, errors, and output records. An empty collection can be a valid result, and a completed step can contain per-record failures where the step defines that behaviour. Check the next step’s expected record shape before publishing or delivering the result.