Load planning (beta)
Place cargo in a trailer or container with centre of gravity and unload order.
loading.solve
Beta
job
How to call it
REST
POST
/v1/loading/solve
202
GraphQL
mutation
openLoadingSolve
MCP
open_loading_solve
Place cargo in a trailer or container in three dimensions, with centre of gravity and optional unload order. Dimensions in centimetres, weights in kilograms. Billed one job.
Request schema
Generated from the same validation rules the endpoint runs, so a field cannot be documented without being validated.
POST /v1/loading/solve
{
"type": "object",
"properties": {
"callback": {
"type": [
"object",
"null"
],
"properties": {
"events": {
"type": "array",
"items": {
"type": "string",
"maxLength": 32
}
},
"format": {
"type": [
"string",
"null"
],
"enum": [
"native",
"ce_binary",
"ce_structured"
]
},
"secret": {
"type": [
"string",
"null"
],
"minLength": 16,
"maxLength": 255,
"description": "Required when callback.signature is standard_webhooks."
},
"signature": {
"type": [
"string",
"null"
],
"enum": [
"native",
"standard_webhooks"
]
},
"url": {
"type": "string",
"maxLength": 2048,
"format": "uri",
"description": "Required when callback is present."
}
}
},
"candidate_limit": {
"type": [
"integer",
"null"
],
"minimum": 1,
"maximum": 3
},
"container": {
"type": "object",
"properties": {
"corner_cm": {
"type": [
"number",
"null"
],
"minimum": 0
},
"height_cm": {
"type": "number",
"exclusiveMinimum": 0
},
"length_cm": {
"type": "number",
"exclusiveMinimum": 0
},
"max_payload_kg": {
"type": [
"number",
"null"
],
"minimum": 0
},
"preset": {
"type": [
"string",
"null"
],
"maxLength": 64
},
"quantity_limit": {
"type": [
"integer",
"null"
],
"minimum": 1
},
"width_cm": {
"type": "number",
"exclusiveMinimum": 0
}
},
"required": [
"height_cm",
"length_cm",
"width_cm"
]
},
"items": {
"type": "array",
"minItems": 1,
"items": {
"type": "object",
"properties": {
"auto_palletize": {
"type": [
"boolean",
"null"
]
},
"bearing_level": {
"type": [
"integer",
"null"
],
"minimum": 0
},
"can_rotate": {
"type": [
"boolean",
"null"
]
},
"cargo_form": {
"type": [
"string",
"null"
],
"enum": [
"loose",
"pre_palletized"
]
},
"height_cm": {
"type": "number",
"exclusiveMinimum": 0
},
"id": {
"type": [
"string",
"null"
],
"maxLength": 128
},
"length_cm": {
"type": "number",
"exclusiveMinimum": 0
},
"max_stack_layers": {
"type": [
"integer",
"null"
],
"minimum": 1
},
"name": {
"type": [
"string",
"null"
],
"maxLength": 191
},
"orientation": {
"type": [
"string",
"null"
],
"enum": [
"any",
"upright_only",
"side_only"
]
},
"pallet_profile": {
"type": [
"array",
"null"
]
},
"prohibit_mixed_pallet": {
"type": [
"boolean",
"null"
]
},
"quantity": {
"type": [
"integer",
"null"
],
"minimum": 1
},
"sku": {
"type": [
"string",
"null"
],
"maxLength": 128
},
"stackable": {
"type": [
"boolean",
"null"
]
},
"unload_priority": {
"type": [
"integer",
"null"
],
"minimum": 0
},
"unload_stop_id": {
"type": [
"string",
"null"
],
"maxLength": 128
},
"weight_kg": {
"type": [
"number",
"null"
],
"minimum": 0
},
"width_cm": {
"type": "number",
"exclusiveMinimum": 0
}
},
"required": [
"height_cm",
"length_cm",
"width_cm"
]
}
},
"leftover_policy": {
"type": [
"string",
"null"
],
"enum": [
"allow_loose",
"keep_unloaded"
]
},
"loading_method": {
"type": [
"string",
"null"
],
"enum": [
"direct_container",
"palletize_then_container"
]
},
"mode": {
"type": [
"string",
"null"
],
"enum": [
"auto",
"sync",
"async"
]
},
"target_utilization_percent": {
"type": [
"number",
"null"
],
"minimum": 1,
"maximum": 100
},
"unloading": {
"type": [
"object",
"null"
],
"properties": {
"direction": {
"type": [
"string",
"null"
],
"enum": [
"rear_to_front",
"front_to_rear"
]
},
"mode": {
"type": [
"string",
"null"
],
"enum": [
"none",
"unload_sequence"
]
},
"rehandle_penalty": {
"type": [
"number",
"null"
],
"minimum": 0
},
"stops": {
"type": [
"array",
"null"
]
}
}
}
},
"additionalProperties": false,
"required": [
"container",
"items"
]
}
Request example
{
"container": {
"preset": "custom",
"length_cm": 600,
"width_cm": 240,
"height_cm": 240,
"max_payload_kg": 24000
},
"items": [
{
"id": "PAL-1",
"quantity": 4,
"length_cm": 120,
"width_cm": 100,
"height_cm": 120,
"weight_kg": 400
}
]
}
Response
What a successful call returns: the schema of `data` and `meta`, with a description of each field, followed by an example response from a real call.
POST /v1/loading/solve
Response schema
{
"description": "Ranked ways to load the items into the container, each with where every unit sits, utilization and balance. Answered in the request's units (cm and kg). The example is shortened to the first candidate.",
"data": {
"type": "object",
"properties": {
"coordinate_system": {
"type": "object",
"properties": {
"unit": {
"type": "string",
"description": "Unit of every position and size."
},
"origin": {
"type": "string",
"description": "Where x, y and z are measured from."
},
"x_axis": {
"type": "string"
},
"y_axis": {
"type": "string"
},
"z_axis": {
"type": "string"
}
}
},
"candidates": {
"type": "array",
"items": {
"type": "object",
"properties": {
"rank": {
"type": "integer",
"description": "1 is the recommended candidate."
},
"algorithm": {
"type": "string",
"description": "The placement heuristic that produced it."
},
"score": {
"type": "number",
"description": "The ranking score; higher is better."
},
"placements": {
"type": "array",
"items": {
"type": "object",
"properties": {
"x_cm": {
"type": "number",
"description": "Position along the length axis, from the origin of `coordinate_system`."
},
"y_cm": {
"type": "number",
"description": "Position along the width axis."
},
"z_cm": {
"type": "number",
"description": "Height above the floor."
},
"length_cm": {
"type": "number",
"description": "Footprint along x after rotation."
},
"width_cm": {
"type": "number",
"description": "Footprint along y after rotation."
},
"height_cm": {
"type": "number",
"description": "Extent along z after rotation."
},
"rotation_key": {
"type": "string",
"description": "How the item was turned: the order its own length (L), width (W) and height (H) take along x, y and z."
},
"stack_level": {
"type": "integer",
"description": "1 on the floor, 2 on top of one item, and so on."
},
"container_index": {
"type": "integer",
"description": "Which container or package, from 1."
},
"unit_sequence": {
"type": "integer",
"description": "Loading order within the container, from 1."
},
"unit_key": {
"type": "string",
"description": "Identifies the unit: `item-{row}-{n}`, row and unit counted from 1."
},
"item_id": {
"type": "string",
"description": "The caller's item id."
},
"name": {
"type": "string"
},
"sku": {
"type": [
"string",
"null"
]
},
"weight_kg": {
"type": "number",
"description": "Weight of the unit."
},
"cargo_form": {
"type": "string",
"description": "`loose`, or `pallet` for a unit built on a pallet."
},
"source_item_count": {
"type": "integer",
"description": "Items the unit stands for (above 1 for a built pallet)."
},
"pallet_group_key": {
"type": [
"string",
"null"
],
"description": "The pallet this unit was built into, when palletized."
},
"metadata": {
"type": "object",
"description": "The item's handling rules as the solver applied them.",
"properties": {
"stackable": {
"type": "boolean"
},
"max_stack_layers": {
"type": [
"integer",
"null"
]
},
"bearing_level": {
"type": [
"integer",
"null"
]
},
"allowed_orientations": {
"type": "array",
"items": {
"type": "string"
},
"description": "The rotations this item may take."
},
"stack_level": {
"type": "integer"
}
}
}
}
},
"description": "One entry per unit."
},
"unplaced": {
"type": "array",
"items": {
"type": "object",
"properties": {},
"additionalProperties": true
},
"description": "Units that did not fit."
},
"metrics": {
"type": "object",
"properties": {
"container_count": {
"type": "integer"
},
"placed_quantity": {
"type": "integer"
},
"unplaced_quantity": {
"type": "integer"
},
"used_volume_m3": {
"type": "number"
},
"container_volume_m3": {
"type": "number"
},
"volume_utilization_percent": {
"type": "number"
},
"used_weight_kg": {
"type": "number"
},
"max_payload_kg": {
"type": "number"
},
"payload_utilization_percent": {
"type": "number"
},
"target_achieved": {
"type": "boolean",
"description": "Whether `target_utilization_percent` was reached."
},
"gravity_max_quadrant_percent": {
"type": "number",
"description": "Share of the load in the heaviest floor quadrant."
},
"gravity_imbalanced": {
"type": "boolean"
}
}
},
"warnings": {
"type": "array",
"items": {
"type": "string"
},
"description": "Codes such as TARGET_UTILIZATION_NOT_REACHED or GRAVITY_IMBALANCED."
},
"checksum": {
"type": "string",
"description": "Identifies this exact layout."
}
}
}
}
}
},
"meta": {
"type": "object",
"properties": {
"solver_version": {
"type": "string"
},
"rules_version": {
"type": "string"
},
"candidate_limit": {
"type": "integer"
},
"input_hash": {
"type": "string",
"description": "Hash of the request; equal requests give equal answers."
},
"units": {
"type": "object",
"properties": {
"dimensions": {
"type": "string"
},
"weight": {
"type": "string"
}
}
},
"mode": {
"type": "string"
}
}
}
}
Response example
{
"request_id": "req_01k8zq3m5n7p9r1t3v5x7z9b2d",
"capability": "loading.solve",
"billing": {
"unit": "job",
"quantity": 1,
"counted": true,
"breakdown": {
"item_rows": 1,
"units": 4,
"candidates": 3
}
},
"data": {
"coordinate_system": {
"unit": "cm",
"origin": "container_inner_bottom_left_rear",
"x_axis": "container_length",
"y_axis": "container_width",
"z_axis": "up"
},
"candidates": [
{
"rank": 1,
"algorithm": "balanced_volume",
"score": 16.667,
"placements": [
{
"x_cm": 0,
"y_cm": 0,
"z_cm": 0,
"length_cm": 120,
"width_cm": 100,
"height_cm": 120,
"rotation_key": "LWH",
"stack_level": 1,
"container_index": 1,
"unit_sequence": 1,
"unit_key": "item-1-1",
"item_id": "PAL-1",
"name": "PAL-1",
"sku": null,
"weight_kg": 400,
"cargo_form": "loose",
"source_item_count": 1,
"pallet_group_key": null,
"metadata": {
"stackable": true,
"max_stack_layers": null,
"bearing_level": null,
"allowed_orientations": [
"LWH",
"WLH",
"LHW"
],
"stack_level": 1
}
},
{
"x_cm": 0,
"y_cm": 100,
"z_cm": 0,
"length_cm": 120,
"width_cm": 100,
"height_cm": 120,
"rotation_key": "LWH",
"stack_level": 1,
"container_index": 1,
"unit_sequence": 2,
"unit_key": "item-1-2",
"item_id": "PAL-1",
"name": "PAL-1",
"sku": null,
"weight_kg": 400,
"cargo_form": "loose",
"source_item_count": 1,
"pallet_group_key": null,
"metadata": {
"stackable": true,
"max_stack_layers": null,
"bearing_level": null,
"allowed_orientations": [
"LWH",
"WLH",
"LHW"
],
"stack_level": 1
}
},
{
"x_cm": 120,
"y_cm": 0,
"z_cm": 0,
"length_cm": 120,
"width_cm": 100,
"height_cm": 120,
"rotation_key": "LWH",
"stack_level": 1,
"container_index": 1,
"unit_sequence": 3,
"unit_key": "item-1-3",
"item_id": "PAL-1",
"name": "PAL-1",
"sku": null,
"weight_kg": 400,
"cargo_form": "loose",
"source_item_count": 1,
"pallet_group_key": null,
"metadata": {
"stackable": true,
"max_stack_layers": null,
"bearing_level": null,
"allowed_orientations": [
"LWH",
"WLH",
"LHW"
],
"stack_level": 1
}
},
{
"x_cm": 120,
"y_cm": 100,
"z_cm": 0,
"length_cm": 120,
"width_cm": 100,
"height_cm": 120,
"rotation_key": "LWH",
"stack_level": 1,
"container_index": 1,
"unit_sequence": 4,
"unit_key": "item-1-4",
"item_id": "PAL-1",
"name": "PAL-1",
"sku": null,
"weight_kg": 400,
"cargo_form": "loose",
"source_item_count": 1,
"pallet_group_key": null,
"metadata": {
"stackable": true,
"max_stack_layers": null,
"bearing_level": null,
"allowed_orientations": [
"LWH",
"WLH",
"LHW"
],
"stack_level": 1
}
}
],
"unplaced": [],
"metrics": {
"container_count": 1,
"placed_quantity": 4,
"unplaced_quantity": 0,
"used_volume_m3": 5.76,
"container_volume_m3": 34.56,
"volume_utilization_percent": 16.667,
"used_weight_kg": 1600,
"max_payload_kg": 24000,
"payload_utilization_percent": 6.667,
"target_achieved": false,
"gravity_max_quadrant_percent": 50,
"gravity_imbalanced": true
},
"warnings": [
"TARGET_UTILIZATION_NOT_REACHED",
"GRAVITY_IMBALANCED"
],
"checksum": "dfe9189f5980c2d4ca6945a426c2197d879ee85934809c80a591f4562ed9246e"
}
]
},
"meta": {
"solver_version": "php-guillotine-3d-1.2",
"rules_version": "ocean-no-sequence-1.2",
"candidate_limit": 3,
"input_hash": "4c4ebf12319f01e2c9bf8c1ff12eec06f9a236c9a6bc50b01adad01d18b3ad7b",
"units": {
"dimensions": "cm",
"weight": "kg"
},
"mode": "sync"
}
}
Example response when queued (202)
{
"request_id": "req_01k8zq3m5n7p9r1t3v5x7z9b2d",
"capability": "loading.solve",
"billing": {
"unit": "job",
"quantity": 1,
"counted": true,
"breakdown": {
"item_rows": 1,
"units": 4,
"candidates": 3
}
},
"data": {
"job": {
"id": "job_01k8zq4a6c8e0g2j4l6n8q0s2u",
"status": "queued",
"capability": "loading.solve",
"poll_after_ms": 1000,
"result_url": "/v1/jobs/job_01k8zq4a6c8e0g2j4l6n8q0s2u/result",
"cancel_url": "/v1/jobs/job_01k8zq4a6c8e0g2j4l6n8q0s2u/cancel"
}
},
"meta": {
"mode": "async"
}
}
What it costs
One solve run, whatever the item count.
Every billable response carries a billing block with the unit, the quantity and how the quantity was derived.
Errors it can return
| Status | Code | Description |
|---|---|---|
| 401 | TOKEN_INVALID |
Unknown or revoked API token. |
| 401 | TOKEN_MISSING |
No API token. Send Authorization: Bearer <your token>. |
| 402 | QUOTA_EXHAUSTED |
The included allowance for this capability is used up for the current period. |
| 403 | CAPABILITY_NOT_ENABLED |
This capability is not enabled for your account. See :doc to enable it. |
| 403 | CAPABILITY_NOT_GRANTED_TO_KEY |
Your account has this capability, but this API key was not granted it. |
| 403 | OPEN_API_DISABLED |
Open Platform access is not enabled for this account. |
| 422 | SOLVE_INFEASIBLE |
No plan satisfies every constraint. Check time windows, capacities and skills. |
| 422 | VALIDATION_FAILED |
The request failed validation. See details. |
| 429 | CONCURRENCY_LIMIT |
Too many solves are already running for this account. Retry when one finishes. |
| 429 | RATE_LIMITED |
Too many requests. Please retry after the indicated delay. |
| 500 | INTERNAL_ERROR |
An unexpected error occurred. Quote the request_id when contacting support. |