CBM & Container Loading API
CBM and chargeable weight (air 1:6000, express 1:5000, sea 1 CBM = 1000 kg) and how many cartons fit a 20GP, 40GP, 40HC, 45HC container or a pallet.
Give the carton size (length, width, height in unit cm, mm, m or in), weight per carton and quantity, or a list of carton types in cartons. The API returns the volume (CBM) per carton and in total, gross weight and chargeable weight for air (cm³ / 6000, air_divisor), express couriers (cm³ / 5000, express_divisor), sea LCL (freight tons, 1 CBM = 1000 kg) and road (1 CBM = 333 kg), each with whether volume or weight decides.
Add container (20gp, 40gp, 40hc, 45hc or all) or pallet (eur 1200 × 800, standard 1200 × 1000, us, asia; max_height incl. the pallet, default 180 cm, max_weight) to plan the loading. For one carton type it tries the six orientations (two with upright=true, limited by max_stack), fills the leftover length at the door with the best other orientation, and returns the maximum count, whether space or payload limits it, cartons per layer, the layer plan, volume and weight utilisation, and how many containers / pallets the quantity needs. Several carton types are packed with a first-fit-decreasing layer heuristic, marked estimate: true.
Container internal sizes and payloads are typical published values; real boxes vary by maker and leave gaps, so keep a margin of 5–10 %.
Parameters
| Name | In | Type | Required | Default | |
|---|---|---|---|---|---|
length | query|body | number | yes | Carton length (outer). | |
width | query|body | number | yes | Carton width. | |
height | query|body | number | yes | Carton height. | |
weight | query|body | number | no | Gross weight per carton (weight_unit kg, g, lb). | |
quantity | query|body | number | no | Number of cartons. | |
cartons | body | array | no | Several carton types: [{name, length, width, height, weight, quantity, upright, max_stack}]. | |
unit | query|body | string | no | cm | mm, cm, m or in. |
container | query|body | string | no | 20gp, 40gp, 40hc, 45hc or all. | |
pallet | query|body | string | no | eur, standard, us or asia (with max_height, max_weight, overhang). | |
upright | query|body | boolean | no | false | Keep cartons upright (no tipping). |
air_divisor | query|body | number | no | 6000 | Air volumetric divisor (cm³/kg). |
Example
curl "https://apibox.io.vn/v1/cargo-load?length=60&width=40&height=40&weight=12&quantity=300&container=20gp" \
-H "Authorization: Bearer YOUR_API_KEY"const res = await fetch('https://apibox.io.vn/v1/cargo-load?length=60&width=40&height=40&weight=12&quantity=300&container=20gp', {
method: 'GET',
headers: {
Authorization: 'Bearer YOUR_API_KEY',
},
});
const data = await res.json();
console.log(data);import requests
res = requests.get(
"https://apibox.io.vn/v1/cargo-load?length=60&width=40&height=40&weight=12&quantity=300&container=20gp",
headers={"Authorization": "Bearer YOUR_API_KEY"},
timeout=30,
)
print(res.json())<?php
$ch = curl_init('https://apibox.io.vn/v1/cargo-load?length=60&width=40&height=40&weight=12&quantity=300&container=20gp');
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => ['Authorization: Bearer YOUR_API_KEY'],
]);
$response = curl_exec($ch);
print_r(json_decode($response, true));Response
{
"total_cbm": 28.8,
"total_gross_weight_kg": 3600,
"cartons": [
{
"name": "carton 1",
"quantity": 300,
"cbm_each": 0.096,
"cbm_total": 28.8,
"weight_total_kg": 3600,
"volumetric_air_kg_each": 16,
"volumetric_express_kg_each": 19.2
}
],
"chargeable": {
"air": {
"divisor": 6000,
"volumetric_kg": 4800,
"chargeable_kg": 4800,
"basis": "volume",
"rule": "cm³ / 6000 (IATA 1:6000 = 167 kg/m³)"
},
"express": {
"divisor": 5000,
"volumetric_kg": 5760,
"chargeable_kg": 5760,
"basis": "volume"
},
"sea_lcl": {
"kg_per_cbm": 1000,
"revenue_tons": 28.8,
"basis": "volume"
},
"road": {
"kg_per_cbm": 333,
"chargeable_kg": 9590.4
}
},
"loading": {
"id": "20gp",
"name": "20' standard (20GP / 20DC)",
"kind": "container",
"internal_mm": [
5898,
2352,
2393
],
"volume_cbm": 33.2,
"max_payload_kg": 28200,
"max_cartons": 240,
"limited_by": "space",
"max_by_space": 240,
"max_by_weight": 2350,
"per_layer": 48,
"layer_plan": [
{
"orientation": "L×W×H",
"box_mm": [
600,
400,
400
],
"along_length": 9,
"across_width": 5,
"layers": 5,
"count": 225
},
{
"orientation": "W×L×H",
"box_mm": [
400,
600,
400
],
"along_length": 1,
"across_width": 3,
"layers": 5,
"count": 15,
"note": "fills the remaining length at the door end"
}
],
"quantity": 300,
"loaded": 240,
"remaining": 60,
"units_needed": 2,
"utilisation_volume_pct": 69.41,
"utilisation_weight_pct": 10.21,
"loaded_weight_kg": 2880,
"estimate": false
}
}
Use cases
- Quote how many cartons fit in a 40HC before booking
- Compare air, express and sea chargeable weight for a shipment
- Plan pallet layers within a 1.8 m height limit
- Check whether a heavy load hits the container payload first
FAQ
Which volumetric divisors are used?
Air 6000 (IATA, 167 kg/m³), express 5000 (200 kg/m³), sea LCL 1 CBM = 1000 kg, road 1 CBM = 333 kg. All can be changed with parameters.
Is the loading plan optimal?
For one carton type it is the best layer-by-layer block over the six orientations plus a filler block. Mixed cartons use a heuristic and are marked as an estimate.
Can cartons be kept upright?
Yes: upright=true allows only rotations around the vertical axis, and max_stack limits the number of layers.
Related APIs
JSON Validator
Check JSON syntax with exact line and column of errors, and validate data against a JSON Schema (draft 4, 7, 2019-09 or 2020-12).
{ }JSON Formatter
Pretty print JSON with 0-8 spaces or tabs, minify it, or sort object keys recursively. Syntax errors are reported with line and column.
CSVCSV to JSON
Convert CSV into an array of JSON objects using the header row, with delimiter auto-detection, number and boolean typing, and row-level errors.