Skip to main content

Intelligent Packing API

The Intelligent Packing API provides AI-enhanced 3D bin packing built on a three-layer hybrid architecture. It combines a deterministic rule engine, an AI matching/pre-screening layer, and an OR-Tools mathematical solver.

Overview​

The service processes each request through three layers:

  • Layer 1 — Rule Engine: handles pre-assigned pallets and filters out unavailable / unfit pallet types.
  • Layer 2 — AI Model: SKU–pallet matching, pallet pre-screening, and solution recommendations.
  • Layer 3 — OR-Tools: mathematically guaranteed bin-packing solve.

Additional capabilities:

  • AI pallet pre-screening (reduce a large pallet catalog to an optimal subset)
  • Parallel and batch processing for large item counts
  • Dynamic entropy tuning
  • LDM (Loading Meter) output for logistics billing

Base URL:

https://api.alaikis.com

All endpoints are mounted under both /api/intelligent-packing and /api/v1/intelligent-packing (v1 alias), and require authentication.

Endpoints​

MethodPathDescription
POST/api/intelligent-packing/packRun intelligent packing (three-layer solve)
POST/api/intelligent-packing/pack/previewPreview a plan without solving
POST/api/intelligent-packing/filter-palletsFilter unavailable / unfit pallet types
POST/api/intelligent-packing/prescreen-palletsAI pallet pre-screening (top-K subset)
GET/api/intelligent-packing/healthHealth check

Pack​

Run the full three-layer intelligent packing solve.

Endpoint:

POST /api/intelligent-packing/pack

Request Body:

{
"skus": [
{
"id": "SKU001",
"weight": 5.5,
"weight_unit": "kg",
"length": 50,
"width": 30,
"height": 20,
"length_unit": "cm",
"quantity": 10,
"is_dangerous": false,
"is_stackable": true
}
],
"pallets": [
{
"id": "PALLET_A",
"length": 120,
"width": 100,
"height": 150,
"weight": 20,
"max_weight": 500,
"length_unit": "cm",
"weight_unit": "kg",
"cost": 5.0
}
],
"use_ai": true,
"entropy_factor": 1.0,
"time_limit_ms": 60000,
"ldm_width": 2.44,
"ldm_mode": "projection"
}

SKU Fields (skus[])​

FieldTypeRequiredDefaultDescription
idstringYes—SKU identifier
weightfloatYes—Item weight
weight_unitstringNo"kg"Weight unit
length / width / heightfloatYes—Item dimensions
length_unitstringNo"cm"Dimension unit
quantityintegerNo1Number of items
is_dangerousbooleanNofalseDangerous goods flag (isolated during packing)
is_stackablebooleanNotrueWhether the item can be stacked

Pallet Fields (pallets[])​

FieldTypeRequiredDefaultDescription
idstringYes—Pallet type identifier
length / width / heightfloatYes—Pallet dimensions
weightfloatNo0.0Pallet tare weight
max_weightfloatYes—Maximum load weight
length_unitstringNo"cm"Dimension unit
weight_unitstringNo"kg"Weight unit
costfloatNo0.0Pallet cost

Request Options​

ParameterTypeDefaultRangeDescription
use_aibooleantrue—Enable AI enhancement
entropy_factorfloat1.00.8–2.0Packing entropy factor
time_limit_msinteger600001000–300000Solver time limit (ms)
enable_parallelbooleantrue—Enable parallel processing
prescreen_palletsbooleantrue—Enable AI pallet pre-screening
top_k_palletsinteger155–100Pallet subset size after pre-screening
max_workersinteger81–16Max parallel worker threads
pre_assigned_palletsarraynull—Pre-assigned pallets (see below)
unavailable_pallet_typesstring[]null—Pallet type IDs to exclude
ldm_widthfloatnull> 0LDM normalization vehicle width (m); defaults to 2.4
ldm_modestring"projection"—LDM mode: "projection" or "arrangement"

::: tip Pre-assigned pallets pre_assigned_pallets[] items use the shape: \{ "pallet_type_id": "PALLET_A", "pallet_id": "P-1", "items": [\{ "sku_id": "SKU001", "quantity": 4 }], "used_volume": 0.0, "used_weight": 0.0 }. :::

Response:

{
"pallets": [
{
"id": "pallet_1",
"pallet_id": "pallet_1",
"pallet_type": "PALLET_A",
"items": [
{ "sku_id": "SKU001", "quantity": 10 }
],
"total_weight": 75.0,
"total_volume": 0.347,
"utilization": 19.3,
"source": "computed",
"ldm": 0.492
}
],
"total_pallets": 1,
"total_weight": 75.0,
"total_volume": 0.347,
"processing_time_ms": 12.3,
"layers_used": ["L1_RULE_ENGINE", "L2_AI_MODEL", "L3_OR_TOOLS"],
"ai_recommendations": null,
"stats": {
"total_pallets": 1,
"total_weight": 75.0,
"total_volume": 0.347,
"total_ldm": 0.492,
"ldm_mode": "projection",
"ldm_width_used": 2.44
},
"prescreen_stats": null,
"performance_stats": {},
"errors": [],
"warnings": [],
"success": true,
"message": "装托成功",
"total_ldm": 0.492,
"ldm_mode": "projection",
"ldm_width_used": 2.44
}

Response Fields​

FieldTypeDescription
pallets[]arraySolved pallets
pallets[].id / pallet_idstringPallet instance ID (kept in sync)
pallets[].pallet_typestringSource pallet type ID
pallets[].itemsarray\{ sku_id, quantity } placed on the pallet
pallets[].total_weightfloatLoaded weight (kg)
pallets[].total_volumefloatLoaded volume (m³)
pallets[].utilizationfloatVolume utilization (%)
pallets[].sourcestring"computed" or "pre_assigned"
pallets[].ldmfloatPer-pallet loading meter
total_palletsintegerNumber of pallets used
layers_usedstring[]Processing layers applied
statsobjectAggregated statistics (weights, volumes, LDM, etc.)
total_ldmfloatTotal loading meters for the solution
ldm_modestringLDM mode used
ldm_width_usedfloatActual vehicle width used (m)
successbooleanWhether the solve succeeded
messagestringHuman-readable status

LDM (Loading Meter)​

LDM (Loading Meter) measures the equivalent floor length a solution occupies in a vehicle — the standard billing metric for European road freight.

Request Parameters (top-level, alongside skus / pallets)

ParameterTypeDefaultDescription
ldm_widthfloatnullVehicle width in meters. When omitted, defaults to 2.4.
ldm_modestring"projection"Calculation mode: "projection" or "arrangement"

::: warning Vehicle width on this endpoint The /pack request has no vehicle field. Vehicle width therefore resolves as ldm_width (if provided) otherwise the 2.4 m default. Pass ldm_width explicitly to override. :::

Response Fields

FieldTypeDescription
total_ldmfloatTotal loading meters for the solution
ldm_modestringMode used for calculation
ldm_width_usedfloatActual vehicle width used (meters)
pallets[].ldmfloatPer-pallet loading meter

projection Mode

ldm = (pallet_length_m * pallet_width_m) / ldm_width_m
total_ldm = Σ ldm

Example: a 1.2 m × 1.0 m pallet with ldm_width = 2.44 yields ldm = 1.2 * 1.0 / 2.44 = 0.492.

arrangement Mode

per_row = max(1, floor(ldm_width_m / pallet_width_m))
rows = ceil(total_pallets / per_row)
total_ldm = rows * pallet_length_m / ldm_width_m

arrangement assumes pallets are placed side-by-side along the vehicle width.

Example Request with LDM

payload = {
"skus": [
{"id": "SKU001", "weight": 5.5, "length": 50, "width": 30, "height": 20, "quantity": 10}
],
"pallets": [
{"id": "PALLET_A", "length": 120, "width": 100, "height": 150, "max_weight": 500}
],
"ldm_width": 2.44,
"ldm_mode": "projection"
}

Preview​

Preview a packing plan without running the full solve. Returns valid SKU / available pallet counts, AI recommendations, and an estimated pallet count.

Endpoint:

POST /api/intelligent-packing/pack/preview

The request body is the same shape as /pack.

Response:

{
"valid_skus": 1,
"available_pallets": 1,
"pre_assigned_pallets": 0,
"ai_recommendations": null,
"estimated_pallets": 2,
"warnings": [],
"preview": true
}

Filter Pallets​

Filter out pallet types that are marked unavailable or that no SKU can fit into.

Endpoint:

POST /api/intelligent-packing/filter-pallets

Request Body:

{
"skus": [
{"id": "SKU001", "weight": 5.5, "length": 50, "width": 30, "height": 20, "quantity": 10}
],
"pallets": [
{"id": "PALLET_A", "length": 120, "width": 100, "height": 150, "max_weight": 500}
],
"unavailable_pallet_types": ["PALLET_X"]
}

Response:

{
"available_pallets": [
{"id": "PALLET_A", "length": 120, "width": 100, "height": 150, "max_weight": 500}
],
"filtered_count": 0,
"total_count": 1,
"filter_reasons": []
}

filter_reasons[] entries carry a pallet_id and a reason of "marked_unavailable" or "no_sku_fits".


Prescreen Pallets​

AI pallet pre-screening — reduce a large pallet catalog to an optimal top-K subset before solving.

Endpoint:

POST /api/intelligent-packing/prescreen-pallets?top_k=20&use_ai=true
Query ParameterTypeDefaultDescription
top_kinteger20Number of pallet types to keep
use_aibooleantrueEnable AI scoring

The request body uses the same skus / pallets / unavailable_pallet_types shape as Filter Pallets.

Response:

{
"original_pallets": [ /* PalletType[] */ ],
"filtered_pallets": [ /* PalletType[] */ ],
"prescreen_stats": {},
"performance_stats": {}
}

Health​

Endpoint:

GET /api/intelligent-packing/health

Response:

{
"status": "healthy",
"service": "intelligent-packing",
"version": "2.1.0",
"layers": ["L1_RULE_ENGINE", "L2_AI_MODEL", "L3_OR_TOOLS"],
"features": ["ai_prescreen", "parallel_processing", "performance_stats"]
}

Example Workflow​

import requests

headers = {"Authorization": "Bearer <your-jwt-token>"}
base = "https://api.alaikis.com/api/intelligent-packing"

skus = [
{"id": "SKU001", "weight": 5.5, "length": 50, "width": 30, "height": 20, "quantity": 10}
]
pallets = [
{"id": "PALLET_A", "length": 120, "width": 100, "height": 150, "max_weight": 500}
]

# 1) Preview to estimate pallet count
preview = requests.post(f"{base}/pack/preview",
json={"skus": skus, "pallets": pallets},
headers=headers).json()
print("Estimated pallets:", preview["estimated_pallets"])

# 2) Run the full solve with LDM
result = requests.post(f"{base}/pack",
json={
"skus": skus,
"pallets": pallets,
"ldm_width": 2.44,
"ldm_mode": "projection"
},
headers=headers).json()

print("Pallets used:", result["total_pallets"])
print("Total LDM:", result["total_ldm"])
for pallet in result["pallets"]:
print(pallet["pallet_type"], "->", pallet["utilization"], "% | ldm", pallet["ldm"])

Performance Notes​

  • Large item counts automatically switch to batch mode; medium counts use parallel processing.
  • Pre-screening (prescreen_pallets) is applied automatically when the pallet catalog exceeds top_k_pallets.
  • Use time_limit_ms to cap solver time for real-time scenarios.