Building load units
A job carries exactly two flat lists: carriers[] (what you load into) and cargo[] (what you ship). Every entry in either list is described inline, directly in the request body. How a unit behaves once placed (stacking, orientation) lives in Constraints.
When to use this
- You're describing your own carriers and cargo inline in a job; there is nowhere to define one once and reference it by id in this API.
- You want to know exactly which fields belong to a carrier entry, which belong to a cargo entry, and which are shared.
The anatomy of a load unit
Every entry, carrier or cargo, is a flat inline object: there is no nesting, no stored reference to look up, and no separate upload step:
carriers[] |
cargo[] |
|
|---|---|---|
| Role | what you load into (supply) | what you ship (demand) |
| Required | externalId, geometry |
amount, geometry |
| Count | quantity (null = the solver decides) |
amount (>= 1) |
| Only here | name, tareWeight |
description, color, constraints, groups |
| Both, but not the same field | category (pallet or container) |
category (free text) |
Two nuances in that Required row are worth knowing. A carrier's externalId is effectively required: the request-level check only caps its length, but a carrier without one is rejected anyway, so always send it. A cargo line's weight is the opposite: an omitted weight is read as 0 and passes validation, so nothing rejects its absence. Send it anyway, or the plan you get back is computed on a weightless load.
The coordinate frame is fixed everywhere: X longitudinal, Y lateral, Z vertical, Z = 0 at the floor (see Concepts).
Geometry: the shape of a unit
Geometry is a box, and only a box, in this API. A carrier and a cargo line describe their outer shape the same way:
{ "type": "box", "dimensionX": 600, "dimensionY": 400, "dimensionZ": 400 }
typemust be exactly"box". Any other value is rejected with400, with a pointer namingGeometry.Type.dimensionX/dimensionY/dimensionZ: all three required, all three must be greater than0, expressed in the job'sunits.length.Xis length,Yis width,Zis height.
Cargo geometry and weight
A cargo line's geometry is the same box shape; give it a weight too. Attach behavioural rules (whether other cargo may stack on it, how it may be rotated) via constraints; see Constraints. Optionally give it a display category for the viewer. amount says how many identical units this one line represents:
{
"externalId": "BOX-A",
"category": "box",
"amount": 120,
"geometry": { "type": "box", "dimensionX": 600, "dimensionY": 400, "dimensionZ": 400 },
"weight": 18
}
Key fields
| Field | On | Notes |
|---|---|---|
geometry |
every unit | Box only: { "type": "box", "dimensionX", "dimensionY", "dimensionZ" }. |
weight |
cargo | Always send it. >= 0, per single unit, in units.weight. An omitted weight is read as 0 rather than rejected. |
tareWeight |
carriers | Optional, >= 0, in units.weight, the carrier's own empty weight, stored with the job. Per-carrier weight in the result is kpis.loadedWeight: the summed weight of that carrier's placements. |
amount |
cargo | Required, >= 1: how many identical units the line represents. |
quantity |
carriers | null/omitted = unlimited instances (the solver decides how many); else must be > 0. |
externalId |
carriers | Effectively required, non-empty, <=128 chars. Duplicates across carriers are allowed. |
externalId |
cargo | Optional echo label, <=128 chars, not unique; never a join key. |
description / color |
cargo | Optional echo fields; cargo has no name (carriers have name, not description). |
groups |
cargo | Optional labels. A label affects placement only when the job also declares it in the top-level groups block and sets configuration.groupSeparation; see Anatomy of a job. Every other label stays inert. Echoed back as group (singular) on placements and unplaced items either way. |
category |
carriers | Which kind of carrier this is: pallet or container, matched exactly. Any other value is rejected with 400, and on a MixedPalletizing job so is container. Omit it and the kind implied by problemType is filled in and echoed. It decides the shape drawn around the cargo in the placement-instruction PDF, and is reserved as an input to solving, so label a carrier for what it is. It still does not select the problem type: problemType on the job is the only field that does; see Anatomy of a job. |
category |
cargo | Optional display hint (<=64 chars when present), echoed on the result. Free text, presentation only, and unrelated to a carrier's category. |
constraints |
cargo | allowStackingOnTop / allowedRotations; see Constraints. |
Notes & caveats
- Everything is inline. There is nowhere to store a reusable carrier or cargo definition and reference it by id: every entry is written out in full in the request body.
- Box-only geometry.
/v2implements the box-packing subset of the target API; other geometry types are not implemented, so anygeometry.typeother than"box"is a400. - Carriers have no
constraintsfield.allowStackingOnTopandallowedRotationsapply to cargo lines only. tareWeightrecords the empty carrier. It is optional, expressed inunits.weight, and stored with the job. The weight figures the result reports are about the load, not the carrier:kpis.loadedWeightper carrier andsummary.totalWeightacross the job are both sums of placement weights.
Related
- Constraints:
allowStackingOnTopandallowedRotationson a cargo line. - Units: the
units.length/units.weighta geometry's dimensions and weights are expressed in.