Separating groups along the carrier
A job can ask for its cargo to be loaded as contiguous blocks along the carrier, one block per group, in an order you choose. Each group then loads and unloads as one physically contiguous section.
When to use this
- A load that is unloaded in stages, where each stage's cargo has to come off as one block and the cargo needed last is loaded first. This API has no notion of routes or stops: you decide which group comes off when, and express that as the order the sections are packed in.
- A load shared between customers, where each customer's cargo has to come off as one block.
- Any load where a group has to be reachable without moving another group first.
It is not free. A section's leftover space cannot be filled by another group's cargo, so a separated job may need more carriers than the same cargo would without it, and it takes longer to solve because every section is solved separately. Leave it off unless the contiguity is worth that.
Walkthrough
By default cargo[].groups is a free label array: you can hang a route, a customer and a handling note on the same line and none of them moves a box. To make one of those labels decide where cargo sits, you do two things, and they are deliberately separate.
Declare the group. The top-level groups block names the groups this job knows about and gives each one a packingOrder. Declaring a name is what promotes it from a label into a claim on a section of the carrier. A label you do not declare here stays inert, which is what makes this additive: a request that declares nothing behaves exactly as it always has.
Activate the separation. configuration.groupSeparation says how strictly to keep the declared groups apart. Today it takes one mode, segmented. Omit the block and there is no separation, whatever the groups block contains. That is on purpose: you can leave your declarations in the request permanently and turn the behaviour on and off with one field, without restructuring your cargo.
{
"groups": {
"route-a": { "packingOrder": 1 },
"route-b": { "packingOrder": 2 }
},
"cargo": [
{ "groups": ["route-a", "fragile"], ... }, // section route-a; "fragile" does nothing
{ "groups": ["route-b"], ... }, // section route-b
{ "groups": ["fragile"], ... } // no declared group: the trailing section
],
"configuration": { "groupSeparation": { "mode": "segmented" } }
}
What segmented guarantees
Each declared group gets its own contiguous stretch of the carrier along the packing axis, in packingOrder order, with 1 nearest the x = 0 end that the default -X consolidation packs toward. The sections sit end to end along whichever horizontal axis you consolidate on, -X or -Y. Within a carrier they are never interleaved: a later section is never placed in front of an earlier one.
Cargo that matches no declared group is not scattered and does not jump the queue. It shares a single section that follows every declared one, wherever those lines happen to sit in cargo[].
Across carriers the guarantee is narrower. A group that does not fit continues on the next carrier, and its remainder can land on a carrier after one that already holds the group behind it. Packing a group can also leave less usable room than its volume alone suggests, so a separated job may need more carriers than the same cargo would without it.
The rules
| Rule | Why |
|---|---|
packingOrder is required on every declared group while groupSeparation is set, and the values must be distinct. | A group with no order has nowhere to sit, and a tie has no answer that is not arbitrary. Gaps are fine: 10, 20, 30 leaves room to insert a group later without renumbering. |
| A cargo line may name at most one declared group. | One unit cannot occupy two sections. Naming two is rejected with 400 against that line. To split a line between groups, send one cargo line per group. |
| A line may still carry any number of undeclared labels. | ["route-a", "fragile"] keeps working: only route-a is declared, so it decides the section and fragile stays a label. |
| Matching is case-sensitive. | The result echoes your labels back verbatim, so folding case here would merge two groups you see as distinct. Route-A does not match a declared route-a; it falls into the trailing section. |
| At most 20 declared groups, and a name is at most 64 characters. | Each section costs its own solve and they share one time budget, which is what makes 20 the ceiling. Both limits apply whether or not groupSeparation is set, so switching it on never turns a body the API accepted into one it rejects. Rejected with 400 against groups. |
| A declared group nobody references is allowed. | It simply produces no section, so a fixed set of routes can live in a request template. |
groupSeparation with no declared group is rejected. | You asked for a discipline with nothing to govern. The 400 points at configuration.groupSeparation. |
groupSeparation cannot be combined with a Z consolidation direction. | A section is a slice of the carrier taken along the packing axis. Sliced vertically, every section above the first would start at the highest point of the one below it, leaving its cargo hanging over empty space. Consolidate on -X or -Y instead; the pair is rejected with 400 rather than solved into a load that cannot be built. |
Key fields
| Field | Where | Type | Notes |
|---|---|---|---|
groups |
job | object |
The groups this job declares, keyed by the name a cargo line opts into. At most 20; a name is 1-64 characters. Declaring a group nobody references is allowed and produces no section. |
groups[name].packingOrder |
declared group | integer |
Where the section sits along the packing axis; 1 is nearest the x = 0 end. Required on every declared group once groupSeparation is set, distinct across groups, gaps allowed. |
cargo[].groups |
cargo entry | string[] |
Free labels. At most one of them may be a declared group; the rest stay inert. Echoed back as group (singular) on placements and unplaced items. |
configuration.groupSeparation.mode |
job | string |
Only segmented today. Required whenever the groupSeparation object is present; omit the whole object to switch the feature off. |
Related
- Anatomy of a job: where
groupsandconfigurationsit in the request body. - Optimization objectives:
consolidationpicks the packing axis, which is the axis the sections run along. - Constraints: the per-item controls, which apply inside a section exactly as they do without one.
- Errors & troubleshooting: the 400 shape every rule below comes back in.