API reference

Calculator API v2

Send your cartons, pallets and a container. Get back where every piece goes, how full the load is, and whether it is balanced enough to ship.

Base URL https://www.cargo-load-planner.com/api/v2/calculator
Every placed piece comes back with its position and size in millimetres. Pick one to see its items[] entry.
items[0]
{
  "sno": 1,
  "name": "Pallet A",
  "locx": 0,
  "locy": 0,
  "locz": 0,
  "dimx": 1200,
  "dimy": 1100,
  "dimz": 1000,
  "weight": 412000,
  "stack_level": 1
}

Quick start

From API key to a packed container in three steps.

  1. Get an API key

    Create a key in your Cargo Load Planner account and keep it on your server. Every call except get_calculation_result sends it in the clp-api-key header. The Integration guide covers setup.

  2. Send a calculation

    Save this as request.json: two cartons and a 20 ft container. apply_cog: 1 turns on balance-aware packing.

    request.json
    {
      "multi": 0,
      "cal_type": "c",
      "apply_cog": 1,
      "boxes": [
        {
          "id": 1,
          "name": "box-1",
          "dim1": 45,
          "dim2": 55,
          "dim3": 65,
          "dim_uom": "cm",
          "weight": 10,
          "weight_uom": "kg",
          "count": 1,
          "tilt_length": 1,
          "tilt_width": 1,
          "stacked": 1,
          "heavy": 0,
          "color": "#ff0000",
          "group_id": 0
        },
        {
          "id": 2,
          "name": "box-2",
          "dim1": 75,
          "dim2": 40,
          "dim3": 35,
          "dim_uom": "cm",
          "weight": 10,
          "weight_uom": "kg",
          "count": 1,
          "tilt_length": 1,
          "tilt_width": 1,
          "stacked": 1,
          "heavy": 0,
          "color": "#ffff00",
          "group_id": 0
        }
      ],
      "container": {
        "id": 1,
        "name": "Standard 20 feet",
        "dim_uom": "cm",
        "x": 235,
        "y": 239,
        "z": 590,
        "volume": 33.2,
        "weight": 21770,
        "fs": 0,
        "bs": 0,
        "ls": 0,
        "rs": 0,
        "ts": 0
      }
    }

    Then post it. Set a generous client timeout: large multi-container loads can take several seconds.

    curl -X POST "https://www.cargo-load-planner.com/api/v2/calculator/calculate" \
      -H "Content-Type: application/json" \
      -H "clp-api-key: $CLP_API_KEY" \
      -d @request.json
  3. Read the result

    You get one option back, with a container for each one used.

    • best_option_idWhich entry of options won. Look it up by id; it is not always 0.
    • containers[].itemsWhere every piece sits: locx, locy, locz and dimx, dimy, dimz, in millimetres.
    • unallocatedProducts that did not fit, as id and qty.
    • summaryHow full the container is: volume_percent and weight_percent.
    • cog.safeWhether the centre of gravity is inside its limits. warnings says why not.
    • suggestions[].applyA patch to merge into your request for a better result.
    Response (abridged)
    {
      "version": "2.0",
      "status": "success",
      "description": "",
      "unique_id": "5b1f0d7e-2c3a-4e7b-9a61-8f4d2c6e1b90",
      "multi": 0,
      "cal_type": "c",
      "best_option_id": 2,
      "container": {
        "id": 1,
        "name": "Standard 20 feet",
        "dim_uom": "cm",
        "x": 235,
        "y": 239,
        "z": 590,
        "volume": 33.2,
        "weight": 21770,
        "fs": 0,
        "bs": 0,
        "ls": 0,
        "rs": 0,
        "ts": 0
      },
      "options": [
        {
          "id": 2,
          "containers": [
            {
              "id": 1,
              "items": [
                {
                  "sno": 1,
                  "id": 1,
                  "name": "box-1",
                  "dim1": 450,
                  "dim2": 550,
                  "dim3": 650,
                  "weight": 10000,
                  "volume": 160875000,
                  "count": 1,
                  "tilt_length": 1,
                  "tilt_width": 1,
                  "stacked": 1,
                  "locx": 0,
                  "locy": 0,
                  "locz": 0,
                  "dimx": 650,
                  "dimy": 550,
                  "dimz": 450,
                  "packsno": 1,
                  "option_id": 2,
                  "pallet_id": 1,
                  "color": "#ff0000",
                  "heavy": 0,
                  "group_id": 0,
                  "bearing_kg": 0,
                  "stack_level": 1
                },
                {
                  "sno": 2,
                  "id": 2,
                  "name": "box-2",
                  "dim1": 750,
                  "dim2": 400,
                  "dim3": 350,
                  "weight": 10000,
                  "volume": 105000000,
                  "count": 1,
                  "tilt_length": 1,
                  "tilt_width": 1,
                  "stacked": 1,
                  "locx": 650,
                  "locy": 0,
                  "locz": 0,
                  "dimx": 750,
                  "dimy": 350,
                  "dimz": 400,
                  "packsno": 2,
                  "option_id": 2,
                  "pallet_id": 1,
                  "color": "#ffff00",
                  "heavy": 0,
                  "group_id": 0,
                  "bearing_kg": 0,
                  "stack_level": 1
                }
              ],
              "summary": {
                "max_weight": 21770000,
                "max_volume": 33200000000,
                "packed_weight": 20000,
                "weight_percent": 0.09,
                "packed_volume": 265875000,
                "volume_percent": 0.80
              },
              "cog": {
                "x": 67.5,
                "y": 22.5,
                "z": 21.25,
                "totalWeight": 20.0,
                "xPercent": 28.723404255319153,
                "yPercent": 9.414225941422593,
                "zPercent": 3.6016949152542375,
                "xSafe": false,
                "ySafe": true,
                "zSafe": false,
                "safe": false,
                "warnings": [
                  {
                    "severity": "WARNING",
                    "message": "The load is heavier on the left (28.7% across the width)."
                  },
                  {
                    "severity": "WARNING",
                    "message": "The load sits too far toward the closed end (3.6% along the length)."
                  }
                ]
              },
              "axle_loads": null,
              "loading": {
                "requested": 0,
                "floor_first": true,
                "volume_at_weight_limit_percent": 0.8,
                "reason": "auto: weight limit reached at 1% of volume (below 50%), floor first",
                "mode_used": "floor_first"
              },
              "delivery_groups": null
            }
          ],
          "summary": {
            "max_weight": 21770000,
            "max_volume": 33200000000,
            "packed_weight": 20000,
            "weight_percent": 0.09,
            "packed_volume": 265875000,
            "volume_percent": 0.80
          },
          "unallocated": []
        }
      ],
      "suggestions": [
        {
          "code": "PLACEMENT_POLICY",
          "severity": "recommend",
          "scope": "calculation",
          "container_id": null,
          "message": "In 1 container(s) the load sits against the closed end with its centre of gravity outside the band along the length; 'centred' placement brings 1 of them into the band.",
          "apply": {
            "placement_policy": "centred"
          },
          "requires": null,
          "expected": {
            "c1_cog_z_percent": 50.0,
            "c1_z_safe": true
          },
          "expected_summary": "The load lands at 50.0% along the length, inside the band."
        },
        {
          "code": "ADD_VEHICLE",
          "severity": "info",
          "scope": "calculation",
          "container_id": null,
          "message": "CoG along the length is judged by a fixed band. With a vehicle profile the engine computes axle loads and the exact window the load must sit in.",
          "apply": null,
          "requires": "vehicle",
          "expected": null,
          "expected_summary": null
        }
      ]
    }

    voids, axle and placement are left out. axle_loads and delivery_groups are null because the request had no vehicle and no group_id values. Here the load sits against the back wall, so the response flags the centre of gravity and suggests placement_policy: "centred". Merge that apply patch into your request and call again.

Authentication

Send your key in the clp-api-key header, and Content-Type: application/json on POST requests. get_calculation_result is the one call that takes no key: the calculation id is the access token, so share it only where you would share the result.

Header
clp-api-key: YOUR_API_KEY
  • A missing, invalid or expired key, an inactive subscription, or a used-up API allowance all return 401 with the body Unauthorized.
  • Every calculation is saved and counts toward your plan's API allowance.
Keep the key on your server.Browser calls to the API are accepted, but a key in front-end code is visible to anyone who opens the network tab. Call the API from your backend.

Units and coordinates

Requests use the units you declare. Responses always use millimetres and grams.

A typo in a unit is not an error.An unknown dim_uom is read as millimetres and an unknown weight_uom as grams, so m, ft or CM quietly gives you sizes or weights that are 10 to 1000 times too small. Use exactly: mm, cm, meter, inch, feet, yard and kg, gm, lb, all lowercase.
WhereUnitNotes
boxes[].dim1, dim2, dim3mm, cm, meter, inch, feet, yardSet by dim_uom. Whole numbers only: for 45.5 cm send 455 with mm.
boxes[].weightkg, gm, lbSet by weight_uom. Weight of one unit.
container.x, y, zsame as container.dim_uomx is the width, y the height and z the length.
container.volumeUsable volume.
container.weightkgMaximum payload.
container.fs, bs, ls, rs, tsmmClearance kept at the front, back, left, right and top. Always millimetres.
items[]: loc*, dim*mmlocx, locy, locz, dimx, dimy, dimz, and the echoed dim1dim3.
weights in the responsegramsitems[].weight, summary.packed_weight, summary.max_weight.
volumes in the responsemm³items[].volume, summary.packed_volume, summary.max_volume.
*_percentpercent, 0–1000.09 means 0.09 %, not 9 %.
cog.x, y, zcmcog.totalWeight is in kg.
bearing_kg, weight_kg, axle_loadskgReports that already use kilograms.

Coordinates

The origin is the back-left-floor corner of the container. X runs left to right across the width, Y runs up, and Z runs from the closed back wall to the doors. The diagram at the top of this page uses the same axes. Each item's locx, locy, locz is its corner nearest the origin, and dimx, dimy, dimz is its size after rotation.

In the request, a package's dim1, dim2, dim3 are its length, width and height, while a container's x, y, z are its width, height and length. Note that z is the long side.

Endpoints

Every path below is relative to the base URL.

Base URL
https://www.cargo-load-planner.com/api/v2/calculator
EndpointWhat it doesKey
POST /calculatePacks your cargo and reports balance, fill and suggestions.Required
GET /get_calculation_result/{id}Fetches a saved calculation: request and result.Not needed
GET /placement_info/{id}Fetches the placement report as Base64.Required

POST /calculate

Packs the products in boxes into the container and returns every placement, the fill figures, the centre of gravity and suggestions.

Key
Required
Body
Request body
Returns
Response body
  • Every call is saved. The unique_id in the response identifies it for the two GET endpoints.
  • With multi: 0 everything goes into one container and what does not fit is listed in unallocated. With multi: 1 more containers of the same type are added until all cargo is loaded.

GET /get_calculation_result/{calculation_id}

Returns a saved calculation as { "output", "input" }: the v2 result and the request exactly as saved.

Key
Not needed
Path
calculation_id from unique_id
Returns
Saved calculation
  • When the calculation was submitted in cm, output.container is returned in mm (dim_uom: "mm").
  • An unknown id returns 400 with the text No such calculation exist. If the account behind the calculation has no valid subscription, it returns 401.

GET /placement_info/{calculation_id}

Returns the placement report for a saved calculation as a Base64 string. Decode it to get the report file.

Key
Required
Path
calculation_id from unique_id
Returns
Base64 text
  • Failures do not use an error status. A bad key, an unknown id or a report that cannot be built all return 200 with an empty body, so check for an empty string.

Request body

One JSON object. Everything except the fields marked required is optional.

Top-level fields

FieldTypeDescription
cal_type requiredstringc packs into a container, p onto a pallet. Anything other than c is treated as p.
boxes requiredarrayThe products to load. See boxes.
container requiredobjectThe container or pallet. See container.
multi0 | 10 uses one container and lists what does not fit. 1 adds containers until everything is loaded. Default 0.
apply_cog0 | 11 packs for balance. See Balance options. Default 0.
placement_policystringcompact (default), centred or spread. Needs apply_cog: 1.
spread_allow_end_gapsbooleanWith spread, allow gaps at the back wall and the doors. Default false.
cog_limitsobjectSafe range for the centre of gravity. See Balance options.
vehicleobjectAdds axle loads and a vehicle-derived length limit.
loading_modestringauto (default), floor_first or stack. See Loading and stacking.
stack_same_footprint_onlybooleanA box may only rest inside the footprint of what carries it.
max_floor_load_kg_per_m2numberFloor load limit, checked under every stack. 0 means no limit.
constraints_overrideobjectFine-tuning of engine settings. All fields optional.

boxes

One object per product.

Product and size

FieldTypeDescription
id requiredintegerUnique id of the product. Responses refer to it in unallocated.
namestringLabel for the product.
dim1 requiredintegerLength.
dim2 requiredintegerWidth.
dim3 requiredintegerHeight.
dim_uom requiredstringmm, cm, meter, inch, feet or yard.
weight requirednumberWeight of one unit.
weight_uom requiredstringkg, gm or lb.
count requiredintegerQuantity.
colorstringColour such as #ff0000. Returned unchanged.
group_idintegerDelivery stop. The lowest stop is loaded nearest the doors; 0 means no stop and sits at the back. Default 0.

Orientation and stacking

FieldTypeDescription
tilt_length0 | 11 lets the packer tip the package around its length, 0 does not. Default 1.
tilt_width0 | 11 lets the packer tip the package around its width, 0 does not. Default 1.
stacked0 | 11 allows other packages on top, 0 means nothing on top. Default 1.
heavy0 | 11 keeps the package on the floor. Default 0.

Stacking rules

Optional. Left out, a product behaves as before.

FieldTypeDescription
max_load_on_top_kgnumberLoad the package can carry. 0 means nothing on top. Omit for no limit.
self_stack_onlybooleanOnly the same product may rest on it.
max_self_stackintegerMost units of this product stacked, counting itself. 0 means unlimited.
max_self_stack_height_mmintegerThe same limit as a height in mm. 0 means unlimited.
bottom_onlybooleanFloor only. Same as heavy: 1.
top_onlybooleanCarries nothing and is packed after everything else.
keep_uprightbooleanNo tipping. Same as tilt_length: 0 and tilt_width: 0.
min_support_percentnumberShare of its footprint that must rest on what is below. Default from constraints_override, else 50.

container

FieldTypeDescription
id requiredintegerId of the container.
name requiredstringLabel for the container.
dim_uom requiredstringmm, cm, meter, inch, feet or yard.
x requiredintegerWidth.
y requiredintegerHeight.
z requiredintegerLength.
volume requirednumberUsable volume in m³.
weight requirednumberMaximum payload in kg.
fsintegerClear space kept at the front, in mm. Default 0.
bsintegerClear space kept at the back, in mm.
lsintegerClear space kept on the left, in mm.
rsintegerClear space kept on the right, in mm.
tsintegerHeadroom kept above the load, in mm.

For a pallet (cal_type: "p") describe the pallet in the same object.

Balance options

With apply_cog: 1 the packer prefers a low centre of gravity, applies placement_policy, mirrors groups of boxes sideways to level the width, and among equally good packings picks one that is safe. The cog report is in every response either way.

cog_limits

FieldTypeDescription
xMin, xMaxnumberSafe range for the centre of gravity across the width, as a percent of the width (0 is the left wall). Defaults 40 and 60.
yBestnumberHeight percent at or below which the load is ideal. Default 40.
yAcceptablenumberAbove yBest and up to this value the load is safe but raises a CAUTION. Above it is CRITICAL. Default 60.
zMin, zMaxnumberSafe range along the length, as a percent of the length (0 is the back wall, 100 the doors). Defaults 40 and 60.

Every field is optional and keeps its default when left out.

placement_policy

Where the finished load sits along the length. It only moves whole groups of boxes, so nothing inside a group changes.

compact
The load stays against the closed end. Its centre of gravity is at 12 %, outside the band.
centred
The whole load moves along the length until its centre of gravity reaches the middle of the band.
spread
Groups of boxes are spaced evenly along the length, then nudged so the centre of gravity sits in the band. Ends are flush unless spread_allow_end_gaps is true.
closed endband 40–60 %doors
vehicle: axle loads

Send a vehicle and each container comes back with per-axle loads in axle_loads, and the length limit is derived from the axle limits instead of cog_limits.zMin and zMax. Positions are millimetres along the vehicle from the back wall of the cargo space, positive toward the doors. Anything ahead of the cargo, such as a steering axle or kingpin, is negative.

FieldTypeDescription
id, nameinteger, stringIdentify the vehicle.
typestringrigid or tractor_semi.
axlesarrayAxle groups: name, role (steering, drive or trailer), position_mm, tare_kg and max_kg.
kingpin_position_mmintegertractor_semi only. Usually negative.
tractor_front_sharenumbertractor_semi only. Share of the kingpin load that reaches the steering axle, typically 0.100.25. Default 0.15.
body_tare_kg, body_cog_position_mmnumber, integerWeight of a body or chassis that is not already in the axle tares, and where it acts.
gross_max_kgnumberLegal gross vehicle weight.
min_steering_share_percentnumberLeast share of the load on the steering axle. Default 20.
Example vehicle
{
  "vehicle": {
    "id": 1,
    "name": "18 t rigid",
    "type": "rigid",
    "axles": [
      {
        "name": "Front",
        "role": "steering",
        "position_mm": -800,
        "tare_kg": 3300,
        "max_kg": 7500
      },
      {
        "name": "Rear",
        "role": "drive",
        "position_mm": 5000,
        "tare_kg": 2500,
        "max_kg": 11500
      }
    ],
    "gross_max_kg": 18000
  }
}

Loading and stacking options

loading_modeBehaviour
autoFloor-first when the payload limit would be reached below floor_first_threshold_percent of the volume, so heavy cargo. Otherwise stack. Decided per container.
floor_firstOne layer across the whole floor first. Boxes are stacked only when the floor is full.
stackWalls are packed to full height.
constraints_override: engine settings

Every field is optional.

FieldTypeDescription
x_balance_enabledbooleanMirror groups of boxes sideways to move the centre of gravity toward the middle. Default true.
x_balance_only_outside_bandbooleanOnly mirror when the width balance is outside its band. Default false.
x_balance_min_gain_percentnumberSkip a mirror that would improve balance by less than this. Default 1.
min_reported_gap_mmintegerGaps shorter than this are not reported as filler positions. Default 50.
min_reported_side_gap_mmintegerSide gaps narrower than this are not reported as filler positions. Default 150.
min_spread_free_length_mmintegerspread is skipped when the free length is below this. Default 500.
min_support_percentnumberDefault footprint support for stacked boxes, 0100. Default 50.
floor_first_threshold_percentnumberauto loading switches to floor-first below this volume percent, 0100. Default 50.

Response body

The result of /calculate, and output in /get_calculation_result.

response
├─ status, description, unique_id, best_option_id      top level
├─ container                                            the container you sent
├─ options[]                                          one entry: the winner
│  ├─ summary, unallocated[]
│  └─ containers[]
│     ├─ items[]                                  where each piece sits
│     ├─ summary                                       fill for this container
│     ├─ cog                                       balance report
│     └─ loading, axle_loads, voids, delivery_groups, placement, axle
├─ selection                                        how the option was chosen
└─ suggestions[]                                   what to change, with a patch

Top level

FieldTypeDescription
versionstring"2.0".
statusstringsuccess or failed. A failed status still comes with HTTP 200. See Errors.
descriptionstringEmpty on success. On failure, what was wrong.
unique_idstringId of the saved calculation. Use it with the GET endpoints.
multi, cal_typenumber, stringEcho of your request.
best_option_idintegerId of the winning option.
containerobjectThe container you sent.
optionsarraySee options and containers.
selectionobject | nullHow the option was chosen. See Other reports.
suggestionsarraySee Suggestions.

Options and containers

In practice options has one entry: the winning packing. It holds a container for each one used.

FieldTypeDescription
idintegerEquals best_option_id.
containersarrayOne entry per container used. id starts at 1.
summaryobjectTotals across all containers.
unallocatedarrayProducts that did not fit: id and qty.

summary

FieldTypeDescription
max_weight, max_volumenumberCapacity in grams and mm³.
packed_weight, packed_volumenumberLoaded amount in grams and mm³.
weight_percent, volume_percentnumberFill as a percent, 0–100.

items

Every placed piece. The positions are final: when a placement policy moved the load, the coordinates already include it.

FieldTypeDescription
snointegerSerial number of the placed piece.
id, nameinteger, stringThe product this piece belongs to.
dim1, dim2, dim3integerLength, width and height in mm as you sent them.
weightnumberWeight in grams.
volumenumberVolume in mm³.
countintegerQuantity this row stands for. Each row is one placed piece.
tilt_length, tilt_width, stacked, heavy, group_id, colorEcho of the product settings.
locx, locy, loczintegerPosition of the corner nearest the origin, in mm.
dimx, dimy, dimzintegerSize along X, Y and Z after rotation, in mm.
packsnointegerLoading order.
option_id, pallet_idintegerThe option and container this piece is in. pallet_id is the container id.
bearing_kgnumberWeight the piece carries, in kg.
stack_levelinteger1 is the floor.

cog

Present on every container, whether or not apply_cog is on. Limits come from cog_limits, or the defaults.

FieldTypeDescription
x, y, znumberCentre of gravity in cm from the origin.
totalWeightnumberTotal cargo weight in kg.
xPercent, yPercent, zPercentnumberPosition as a percent of the container width, height and length.
xSafe, ySafe, zSafebooleanEach axis against its limits.
safebooleantrue when all three are safe.
warningsarrayseverity (WARNING, CAUTION or CRITICAL) and message.

Other container reports

Each container also carries these. Reports that do not apply are null.

loading

FieldTypeDescription
requestednumber0 auto, 1 floor_first, 2 stack.
mode_usedstringfloor_first or stack, the mode actually used for this container.
floor_firstbooleanWhether the container was floor-first.
volume_at_weight_limit_percentnumberShare of the volume the cargo would fill when the payload limit is reached.
reasonstringWhy the mode was chosen.
axle_loads: per-axle loads (null without a vehicle)
FieldTypeDescription
vehicle_name, vehicle_typestringFrom your vehicle.
cargo_kg, cog_z_mm, cog_z_percentnumberCargo weight and where its centre sits along the length.
groups[]arrayPer axle group: name, role, position_mm, tare_kg, body_kg, cargo_kg, load_kg, max_kg, percent_of_max, ok.
gross_kg, gross_max_kgnumberTotal weight and its limit.
steering_share_percent, min_steering_share_percentnumberLoad on the steering axle and its minimum.
ok, warningsboolean, arrayOverall result and the reasons for any failure.
windowobjectThe centre-of-gravity range that keeps every axle legal: feasible, z_min_mm, z_max_mm, z_min_percent, z_max_percent, limiting_low, limiting_high, note.
voids: empty space and filler positions
FieldTypeDescription
container_volume, packed_volume, total_void_volume, reported_void_volumenumberIn mm³.
free_length_mmintegerLength not taken up by loaded groups.
components[]arrayGroups of boxes that can move as a unit: index, z_min, z_max, x_min, x_max, y_max, width, length, weight, packed_volume, packsnos, cog_x, cog_z, mirrored.
voids[]arrayEmpty space: type_name (BACK_GAP, BETWEEN_GAP, FRONT_GAP, SIDE, TOP, INTERNAL), position and size in mm, volume, needs_filler and recommendation.
fillers[]arrayThe voids that need filler, in order along the length.

Sizes are in mm. axle is a legacy quarter-length summary kept for existing clients.

delivery_groups: unloading order (null without group_id values)
FieldTypeDescription
groups[]arrayPer stop: group_id, sequence (1 is unloaded first), boxes, weight_kg, z_min, z_max, intruders.
in_delivery_orderbooleanThe lowest stop is nearest the doors.
contiguousbooleanNo stop's boxes sit inside another stop's length.
notestringA one-line summary.
placement: what the placement policy did
FieldTypeDescription
policy, applied, notestring, booleanThe policy used and whether it moved anything.
shift_mm, gaps_mm, free_length_mmnumber, arrayWhat centred or spread did.
cog_z_before_percent, cog_z_after_percent, target_z_percent, z_in_band_afternumber, booleanLength balance before and after.
z_band_source, z_band_min_percent, z_band_max_percent, z_band_notestring, numberThe band used. vehicle when derived from axle limits.
x_applied, x_note, mirrored_componentsboolean, string, arraySideways mirroring.
cog_x_before_percent, cog_x_after_percent, target_x_percent, x_in_band_afternumber, booleanWidth balance before and after.

Present when apply_cog is 1 and either placement_policy is not compact or sideways balancing is on.

selection: how the option was chosen
FieldTypeDescription
appliedbooleantrue when the balance check changed the choice.
evaluatedbooleanfalse when apply_cog was off or there was a single option.
ranked_option_id, chosen_option_idintegerThe winner before and after the balance check.
reasonstringWhy.
candidates[]arrayoption_id, rank, safe, violation and warnings for each equivalent option.

suggestions

Each suggestion carries an apply patch. Merge it into the request you sent and call again. Merge constraints_override field by field.

FieldTypeDescription
codestringOne of the codes below.
severitystringrecommend or info.
scope, container_idstring, integercalculation or container, and which container.
messagestringWhat is wrong, in one sentence.
applyobject | nullFields to merge into your request. null when you must supply data.
requiresstring | nullWhat to add when apply is null.
expected, expected_summaryobject, stringOutcome of a trial run, when one was made. Only for PLACEMENT_POLICY.

Codes

codeMeaning
ENABLE_COGapply_cog is off. Patch: { "apply_cog": 1 }.
LOADING_MODE_FLOOR_FIRSTWeight-bound containers were packed in stacks. Patch: { "loading_mode": "floor_first" }.
PLACEMENT_POLICYThe load sits at the closed end and centred or spread would bring it into the band. Trial-run, so expected holds real numbers.
ADD_VEHICLELength balance is judged by a fixed band. Send a vehicle for axle loads. apply is null, requires is vehicle.
RELAX_SUPPORT_PERCENTProducts are unallocated under a support requirement above 50 %. Patch: { "constraints_override": { "min_support_percent": 50 } }.

Errors

StatusMeaning
200The call ran. Check status: failed means the input was rejected, and description says why.
400A field has the wrong type, the calculation threw, or the calculation id does not exist. The body is JSON for a wrong type and plain text otherwise.
401The key is missing, invalid or expired, the subscription is inactive, or the API allowance is used up. The body is Unauthorized.
415A POST without Content-Type: application/json.

Rejected input

Invalid dimensions : Item ids (3). means a product cannot fit the container in any allowed rotation, after the clearances fs, bs, ls, rs and ts are taken off. Check the units first, then whether tilt_length and tilt_width forbid the rotation it needs.

200 with status failed
{
  "version": "2.0",
  "status": "failed",
  "description": "Invalid dimensions : Item ids (3).",
  "unique_id": "5b1f0d7e-2c3a-4e7b-9a61-8f4d2c6e1b90",
  "multi": 0,
  "cal_type": "c",
  "best_option_id": 0,
  "container": {
    "id": 1,
    "name": "Standard 20 feet",
    "dim_uom": "cm",
    "x": 235,
    "y": 239,
    "z": 590,
    "volume": 33.2,
    "weight": 21770,
    "fs": 0,
    "bs": 0,
    "ls": 0,
    "rs": 0,
    "ts": 0
  },
  "options": [],
  "selection": null,
  "suggestions": []
}

Wrong field types

Sizes and counts are whole numbers, so "dim1": 45.5 is rejected. The response lists the field path. Text abridged.

400
{
  "type": "https://tools.ietf.org/html/rfc9110#section-15.5.1",
  "title": "One or more validation errors occurred.",
  "status": 400,
  "errors": {
    "$.boxes[0].dim1": [
      "The JSON value could not be converted to System.Int64. Path: $.boxes[0].dim1 | LineNumber: 6 | BytePositionInLine: 20."
    ]
  }
}

Ready to capture space you're paying for?

Start a 10-day free trial. Prove the ROI on your next shipment.