Appearance
Looping Lists
A Looping List is a map group that iterates a source and produces one child item per iteration. It is the mechanism behind every parent/child mapping in the platform — sales order lines, item prices, shipment packages, and so on.
For the mechanics of adding a Looping List to a route, and for filtering and delete handling, see Action Mapping.
What makes a map group a Looping List
A Looping List has exactly one inner map group (the shape of a single child) and no property maps of its own. Everything you map inside it describes one child; the loop repeats that shape once per item it produces.
Custom Lists
A Looping List doesn't have to target a list the Data Model already declares. It can also populate a Custom List — a user-defined, free-form child collection you can attach to any entity to extend the common model with a relationship it doesn't already define. The looping methods below work the same either way; the only difference is whether the destination is a declared property or a Custom List you named.
For what a Custom List is, when to use one, how to set it up, and how its children behave and sync, see the dedicated Custom Lists guide.
Looping Methods (read / publish side)
When you configure a Looping List on a read action, a Looping Method picker appears beside the source selector. It controls how the loop turns the source into children. There are three methods:
| Method | In-app help | What it does |
|---|---|---|
| Loop All | "Each matched item becomes a child." | The selector matches an array in the source; each matched element becomes one child. |
| Group by Field | "Groups items by a field into sub-lists." | Takes a targeted list and groups its items by a target field. A nested Looping List can be embedded from each grouping to build sub-lists. |
| Split by Separator | "Splits a value into one child each." | Takes a single delimited scalar and splits it on a separator, fanning out to one child per token. |
Loop All
The connector selector (a JSONPath on JSON, XPath on XML) points at an array in the source. Each element of that array becomes exactly one child, and the inner map group maps each element's fields onto the child.
Source:
json
{
"contacts": [
{ "name": "A" },
{ "name": "B" }
]
}With a Looping List whose selector points at contacts, this produces two children — one for A, one for B. This is the everyday case: a repeating array in the payload becomes a list on the model.
Group by Field
Group by Field takes a targeted list and groups its items by the value of a target field (the Group By Property). Each distinct value becomes one grouping. You can then embed a nested Looping List from those groupings to build sub-lists — turning one flat list into a hierarchy.
Use it when the connector hands you a single flat collection but the model needs a hierarchy. For example, a flat list of shipment lines that needs to become Shipment → Packages → Package Contents:
| Flat shipment line | Package ID |
|---|---|
| Line 1 | PKG-1 |
| Line 2 | PKG-1 |
| Line 3 | PKG-2 |
Grouping the rows by package id turns each distinct package into a grouping; a nested Looping List embedded from those groupings produces each package's contents sub-list — PKG-1 becomes a Package whose contents are Line 1 and Line 2, and PKG-2 becomes a Package whose contents are Line 3.
Because every line in a grouping shares the group's key, the intermediate item can also take its own properties from the grouped lines — each Package can map package-level fields (a tracking number, weight, carrier) off the lines it was grouped from. So a single Group by Field builds all three layers at once:
- Shipment — the parent the Looping List sits on.
- Packages — the groupings (layer 2), each carrying package-level fields read from its grouped lines.
- Package Contents — the nested Looping List over the lines within each grouping (layer 3).
Split by Separator
Preview
Split by Separator is in Preview and is rolling out across environments. Your Central environment may not run it yet — availability may lag the configuration UI until the full release completes.
Split by Separator operates on a single delimited scalar value rather than an array. It splits that one value on a separator (e.g. ;) and fans out to one child per token. Here, one source row = one parent, and the split column produces N children (projections) from it.
- Each split child's only intrinsic data is the token itself — typically mapped to the child's primary key.
- Other child fields come from the parent via "map from parent" (the child pulls values off the parent record it was split from).
- Empty or blank tokens produce no child — they are skipped, so a trailing separator or a doubled delimiter does not create an empty item.
Source — a HubSpot-style contact with a delimited custom field:
json
{
"id": "contact-1001",
"firstName": "Jordan",
"properties": {
"property_certifications": "CPA;PMP;CFA"
}
}Configure a Looping List whose:
- Central List = a Custom List named
Certifications - Looping Method = Split by Separator, separator =
; - Child sub-type =
Certification - Child primary-key map = the split token
The model then gets a Certifications Custom List with three ChildCustomEntity children, keyed by each token:
json
{
"id": "contact-1001",
"firstName": "Jordan",
"customLists": {
"Certifications": [
{ "subType": "Certification", "primaryKey": "CPA" },
{ "subType": "Certification", "primaryKey": "PMP" },
{ "subType": "Certification", "primaryKey": "CFA" }
]
}
}(Illustrative shape — the exact envelope differs, but the important part is: one delimited value became three keyed children.)
Keys are scoped per parent
The same child key can exist under multiple parents independently — CPA under contact-1001 is a distinct child from CPA under another contact. Each child also syncs downstream with its own create / update / delete lifecycle.
Save / Subscribe Side
On a save action, a Looping List does the reverse: it emits the children back out, one output element per child. For a JSON connector that is an array named by the connector property; for XML a repeating element; for a file, one row per child (parent columns repeated).
Each emitted child carries its own operation — create, update, or delete — based on the child's key state. Which operations are actually written is governed by the Looping List's Supported Operations, and deletes are never assumed. See Filtering Looping List Items by Operation in the Action Mapping guide for the full rules and the _destroy recipe.
Custom-list children need a sub-typed child model
When a Looping List targets a Custom List, the child Data Model must have an Entity Sub Type. If it does not, the platform raises an error rather than emitting untyped children — so set the child model's sub type before saving the map.
See Also
- Custom Lists — Attaching a user-defined child collection to any entity
- Action Mapping — Adding Looping Lists to a route, filters, and delete handling
- Data Adaptation — Transform and adapt values inside a child map
- Data Models — Defining child models and Entity Sub Types
- Code View — View the underlying map-group configuration