V4
Version 4 covers everything Version 3 does, over 16 endpoints, and organizes them by the answer you want rather than by the shape of the request.
This API version is experimental and can change at any time. It stays experimental for the whole 3.0.x line. Use Version 3 for anything you keep.
π Learn more:
π Contents
- πΊοΈ Choosing an Endpoint
- π Presets
- π§© Fit
- π¦ Pack
- βοΈ Parameters
- π§ Algorithm
- π¦ Result Values
- β Errors
πΊοΈ Choosing an Endpoint
Every fit and pack route ends in bin or bins, and the plural says what comes back.
| You want | Route | Returns |
|---|---|---|
| One bin, one answer | fit/bin, pack/bin |
one result |
| The smallest bin that works | fit/smallest-bin, pack/smallest-bin |
one result |
| The bin the items fill most | pack/best-bin |
one result |
| An answer for every bin | fit/compare-bins, pack/compare-bins |
one result per bin, in the order the bins were sent |
Each route comes in two forms: custom, where you send the bins in the body, and preset, where the bins come from your configured presets and the preset name is in the path.
- Custom:
POST /api/v4/pack/smallest-bin - Preset:
POST /api/v4/pack/smallest-bin/{preset} - One named bin from a preset:
POST /api/v4/pack/bin/{preset}/{bin}
smallest-bin takes the least roomy bin the items fit in; best-bin takes the bin they fill the most. The two
agree whenever some bin packs fully, and differ only when nothing does.
There is no fit/best-bin. A fit check stops as soon as it can, so on a bin that fails, the fill
percentage records how far the run got and not how well the items fill the bin - ranking on it would be
misleading. When a fit succeeds, fit/smallest-bin already gives the same answer.
The full list
| Method | Route | What it does |
|---|---|---|
| GET | /api/v4/presets |
List every preset with its bins |
| GET | /api/v4/presets/{preset} |
Get one preset |
| POST | /api/v4/fit/bin |
Fit-check a custom bin |
| POST | /api/v4/fit/bin/{preset}/{bin} |
Fit-check one bin from a preset |
| POST | /api/v4/fit/smallest-bin |
Smallest custom bin the items fit in |
| POST | /api/v4/fit/smallest-bin/{preset} |
Smallest bin in a preset the items fit in |
| POST | /api/v4/fit/compare-bins |
Fit-check every custom bin |
| POST | /api/v4/fit/compare-bins/{preset} |
Fit-check every bin in a preset |
| POST | /api/v4/pack/bin |
Pack a custom bin |
| POST | /api/v4/pack/bin/{preset}/{bin} |
Pack one bin from a preset |
| POST | /api/v4/pack/smallest-bin |
Pack the smallest custom bin that works |
| POST | /api/v4/pack/smallest-bin/{preset} |
Pack the smallest bin in a preset that works |
| POST | /api/v4/pack/best-bin |
Pack the custom bin the items fill most |
| POST | /api/v4/pack/best-bin/{preset} |
Pack the bin in a preset the items fill most |
| POST | /api/v4/pack/compare-bins |
Pack every custom bin |
| POST | /api/v4/pack/compare-bins/{preset} |
Pack every bin in a preset |
π Presets
GET /api/v4/presets
Returns every configured preset with its bins.
Response Example
{
"presets": {
"preset1": [
{ "id": "preset1_bin1", "length": 10, "width": 10, "height": 10 },
{ "id": "preset1_bin2", "length": 20, "width": 20, "height": 20 },
{ "id": "preset1_bin3", "length": 30, "width": 30, "height": 30 }
],
"preset2": [
{ "id": "preset2_bin1", "length": 10, "width": 20, "height": 30 },
{ "id": "preset2_bin2", "length": 30, "width": 60, "height": 60 }
]
}
}
GET /api/v4/presets/{preset}
Returns one preset. Responds 404 when the preset does not exist.
Response Example
{
"name": "preset1",
"bins": [
{ "id": "preset1_bin1", "length": 10, "width": 10, "height": 10 },
{ "id": "preset1_bin2", "length": 20, "width": 20, "height": 20 },
{ "id": "preset1_bin3", "length": 30, "width": 30, "height": 30 }
]
}
π§© Fit
Fitting answers whether the items go in. V4 fit results also carry the placement of every item that was packed before the check finished.
POST /api/v4/fit/bin takes one bin in bin. fit/smallest-bin and fit/compare-bins take a list in bins
instead. The preset forms take no bins at all - the path supplies them.
Request Example (POST /api/v4/fit/bin)
{
"parameters": {
"algorithm": "Best",
"includeViPaqData": true
},
"bin": { "id": "custom_bin", "length": 10, "width": 40, "height": 60 },
"items": [
{ "id": "box_1", "quantity": 2, "length": 2, "width": 5, "height": 10 },
{ "id": "box_2", "quantity": 1, "length": 12, "width": 15, "height": 10 },
{ "id": "box_3", "quantity": 1, "length": 12, "width": 10, "height": 15 }
]
}
Response Example
{
"status": "Fits",
"bin": { "id": "custom_bin", "length": 10, "width": 40, "height": 60 },
"algorithmUsed": "FFD",
"packedItems": [
{ "id": "box_2", "length": 10, "width": 12, "height": 15, "x": 0, "y": 0, "z": 0 },
{ "id": "box_3", "length": 10, "width": 12, "height": 15, "x": 0, "y": 12, "z": 0 },
{ "id": "box_1", "length": 2, "width": 5, "height": 10, "x": 0, "y": 0, "z": 15 },
{ "id": "box_1", "length": 2, "width": 5, "height": 10, "x": 0, "y": 24, "z": 0 }
],
"unpackedItems": [],
"packedItemsVolumePercentage": 100,
"packedBinVolumePercentage": 15.83,
"viPaqData": "AAAEAAooPAoMDwAAAAoMDwAMAAIFCgAADwIFCgAYAA==",
"earlyExitReason": "None"
}
A check that stopped before placing anything reports why:
{
"status": "EarlyExit",
"bin": { "id": "custom_bin", "length": 10, "width": 40, "height": 60 },
"algorithmUsed": "FFD",
"packedItems": [],
"unpackedItems": [ { "id": "large_box", "quantity": 1 } ],
"packedItemsVolumePercentage": 0,
"packedBinVolumePercentage": 0,
"earlyExitReason": "ContainerDimensionExceeded"
}
fit/compare-bins returns one such result per bin, wrapped in a results array, in the order the bins were
sent.
π¦ Pack
Packing places the items and returns where each one went.
Request Example (POST /api/v4/pack/smallest-bin)
{
"parameters": {
"algorithm": "Best",
"includeViPaqData": true
},
"bins": [
{ "id": "custom_bin_1", "length": 10, "width": 40, "height": 60 },
{ "id": "custom_bin_2", "length": 20, "width": 40, "height": 60 },
{ "id": "custom_bin_3", "length": 30, "width": 40, "height": 60 }
],
"items": [
{ "id": "box_1", "quantity": 2, "length": 2, "width": 5, "height": 10 },
{ "id": "box_2", "quantity": 1, "length": 12, "width": 15, "height": 10 },
{ "id": "box_3", "quantity": 1, "length": 12, "width": 10, "height": 15 }
]
}
Response Example
{
"status": "FullyPacked",
"bin": { "id": "custom_bin_1", "length": 10, "width": 40, "height": 60 },
"algorithmUsed": "FFD",
"packedItems": [
{ "id": "box_2", "length": 10, "width": 12, "height": 15, "x": 0, "y": 0, "z": 0 },
{ "id": "box_3", "length": 10, "width": 12, "height": 15, "x": 0, "y": 12, "z": 0 },
{ "id": "box_1", "length": 2, "width": 5, "height": 10, "x": 0, "y": 0, "z": 15 },
{ "id": "box_1", "length": 2, "width": 5, "height": 10, "x": 0, "y": 24, "z": 0 }
],
"unpackedItems": [],
"packedItemsVolumePercentage": 100,
"packedBinVolumePercentage": 15.83,
"viPaqData": "AAAEAAooPAoMDwAAAAoMDwAMAAIFCgAADwIFCgAYAA=="
}
When some items are left over, status is PartiallyPacked and they are listed with their quantity:
{
"status": "PartiallyPacked",
"bin": { "id": "custom_bin", "length": 10, "width": 40, "height": 60 },
"algorithmUsed": "FFD",
"packedItems": [
{ "id": "box_2", "length": 10, "width": 12, "height": 15, "x": 0, "y": 0, "z": 0 },
{ "id": "box_3", "length": 10, "width": 12, "height": 15, "x": 0, "y": 12, "z": 0 }
],
"unpackedItems": [ { "id": "box_1", "quantity": 2 } ],
"packedItemsVolumePercentage": 94.74,
"packedBinVolumePercentage": 15.0,
"viPaqData": "AAACAAooPAoMDwAAAAoMDwAMAA=="
}
pack/compare-bins wraps one such result per bin in a results array, in the order the bins were sent.
βοΈ Parameters
Every fit and pack request carries a parameters object.
algorithm(required):FFD,WFD,BFDorBest. It cannot be omitted.includeViPaqData(optional): whentrue, the result carries aviPaqDatafield holding the arrangement encoded with the ViPaq protocol. Fit results carry it too.
Bins and items are integers of at least 1, in whatever unit you use, as long as it is the same one everywhere.
Every id you send is echoed back on the matching result.
π§ Algorithm
FFD, WFD and BFD are the individual heuristics, described in
Core Concepts.
Best runs more than one and keeps the best result. It does not run the same set on every route:
fit/binandpack/bin, including their preset forms: all three heuristics.- Every other route:
FFDandBFDonly.
The responseβs algorithmUsed says which heuristic produced the result you got.
Bestthe algorithm andbest-binthe route are different things. The route picks a bin;Bestpicks a heuristic.BFDis Best Fit Decreasing, which is a third thing again.
π¦ Result Values
Fitting (status)
Fits: every item fits in the bin.DoesNotFit: at least one item was left over.EarlyExit: the check stopped before placing anything.earlyExitReasonsays why:ContainerVolumeExceededorContainerDimensionExceeded.Unknown: the operation produced no usable answer.
earlyExitReason is None on a check that ran to completion.
Packing (status)
FullyPacked: every item was placed.PartiallyPacked: some items were placed, some were not.NotPacked: nothing was placed.Unknown: the operation produced no usable answer.
β Errors
Errors are returned in RFC 7807 problem-details form.
| Status | When |
|---|---|
400 |
The request body is missing or is not valid JSON. |
404 |
The preset, or the bin within it, does not exist. |
422 |
The request was read but failed validation. errors lists the fields. |
429 |
Rate limited. Only when the Service Module is enabled. |
500 |
An unhandled error. |
The two presets endpoints are not rate limited.