Packing API
Magsumite ng kargamento, makakuha ng optimisado at pisikal na wastong plano ng pagkarga — mga posisyon, loading meters, linear feet, at bilang ng mga pallet na siningil. Parehong engine na ginagamit sa app, patuloy na napatunayan laban sa mga aktwal na layout ng mga dispatcher. Available ang access sa sandbox sa bawat plano; production access sa Enterprise.
Mabilis na pagsisimula
- Mag-sign in → i-click ang iyong pangalan → API → bumuo ng key.
- Magsumite ng pack job (ito ay tumatakbo sa sandbox — libre sa bawat plano):
curl -X POST https://hansatic.com/api/v1/pack \
-H "Authorization: Bearer hk_live_..." \
-H "Content-Type: application/json" \
-d '{
"vehicle": "CURTAINSIDER_136",
"objective": "ldm",
"sandbox": true,
"items": [{
"name": "Machine crate",
"length": 2300, "width": 750, "height": 1400,
"weight": 300, "quantity": 7,
"stackable": false, "tiltable": false
}]
}'{
"job_id": "5e3617d1-abe4-4549-b7e6-d18c6baf814f",
"status": "queued",
"sandbox": true,
"status_url": "https://hansatic.com/api/v1/jobs/5e3617d1-..."
}Suriin ang status_url (gamit ang parehong auth header) hanggang ang status ay "done":
{
"job_id": "5e3617d1-...",
"status": "done",
"result": {
"placed_count": 7,
"unplaced_count": 0,
"units": "metric",
"metrics": {
"ldm_m": 5.25,
"span_mm": 5250,
"linear_ft": 17.2,
"pallet_positions_eur": 14,
"total_weight_kg": 2100,
"overlaps": 0
},
"items": [
{ "id": "...", "name": "Machine crate", "placed": true,
"x": 8370, "y": 0, "z": 0,
"rotation_deg": 90, "tilt_deg": 0, "...": "..." }
],
"plan_url": "https://hansatic.com/en/app/plans/..."
}
}Mga endpoint
POST /api/v1/pack
Nagpapatunay at nag-i-queue ng packing job. Bumabalik ng 202 kasama ang job_id. Sinusuportahan ang Idempotency-Key header — ang mga retry na may parehong key ay ibabalik ang orihinal na job sa halip na mag-pack nang dalawang beses.
GET /api/v1/jobs/{id}
Katayuan ng job at, kapag natapos na, ang buong resulta. Inaabot ang mga resulta sa loob ng 30 araw; permanente ang mga production plan sa iyong workspace.
GET /api/v1/openapi.json
Ang machine-readable na OpenAPI 3.1 contract — i-import ito sa Postman, code generators, o ituro ang iyong AI coding tool dito. Ininject ang mga vehicle code mula sa live engine, kaya laging napapanahon ito. Buksan ang spec ↗
Mga field ng tugon
Ang result object sa isang natapos na job:
| Field | Uri | Paglalarawan |
|---|---|---|
| placed_count / unplaced_count | integer | Ilang item ang nakasya / hindi nakasya. |
| units | "metric" | "imperial" | Ang mga yunit na ginagamit sa bawat numero sa ibaba (echo ng kahilingan). |
| metrics.ldm_m | number | Loading meters — ang lawak ng bloke ng kargamento (max end − min start). |
| metrics.linear_ft | number | Ang parehong lawak sa linear feet (US LTL). |
| metrics.span_mm | integer | Ang lawak sa mm, laging metric. |
| metrics.pallet_positions_eur | integer | null | Bilang ng mga siningil na EUR pallet positions. null kapag masyadong malaki ang layout para masukat. |
| metrics.total_weight_kg | number | Bigat ng mga nakasang item, laging kg. |
| metrics.overlaps | integer | Mga pares na nagtatalunan — laging 0 para sa wastong layout. |
| items[].placed | boolean | Kung nakapasok ang item sa layout. |
| items[].x / y / z | number | null | Posisyon sa mga yunit ng kahilingan: x mula sa dulo ng pinto, y mula sa kaliwang pader, z mula sa sahig. Lahat ng tatlo ay null kapag ang placed ay false. |
| items[].rotation_deg / tilt_deg | 0 | 90 | Oriyentasyon: pag-ikot sa vertical axis; tilt = nakahiga sa gilid nito. |
| items[].length / width / height / weight | number | Ang item gaya ng isinumite, echo sa mga yunit ng kahilingan. |
| plan_url | string | null | Ang ginawang plano sa app. null para sa mga sandbox job. |
Bersyon at katatagan
Ang kontrata ay naka-versyon sa path (/api/v1/). Sa loob ng v1, ang mga pagbabago ay additive lamang — bagong opsyonal na field sa kahilingan, bagong field sa tugon, bagong vehicle code at error code ay maaaring lumitaw, at dapat balewalain ng mga kliyente ang mga field na hindi nila nakikilala. Hindi kailanman nagbabago ang kahulugan o uri ng mga umiiral na field, at walang anumang inaalis. Ang isang breaking change ay nangangahulugan ng bagong version path, na may v1 na pinapanatili nang magkatabi sa loob ng hindi bababa sa 12 buwan at abiso ng deprecation sa email sa bawat workspace na may aktibong key.
Mga field ng kahilingan
| Field | Uri | Paglalarawan |
|---|---|---|
| vehicle | string | Isang vehicle code mula sa mga talahanayan sa ibaba. O ipasa ang {customVehicleId} (isang sasakyan mula sa iyong workspace fleet). |
| objective | "ldm" | "pallets" | Paliitin ang loading meters, o paliitin ang bilang ng mga siningil na pallet positions. Default "ldm". |
| units | "metric" | "imperial" | Paano binabasa AT ibinabalik ang mga dimensyon at timbang ng item: mm/kg (default) o in/lb. Sumusunod ang mga posisyon sa tugon sa parehong yunit. |
| items | array, required | Ang manifest ng kargamento (mga field sa ibaba). |
| sandbox | boolean | Test mode: buong resulta, walang naitala. Available sa bawat plano. |
| name | string | Pangalan ng plano (production mode). |
| ldm_limit_m | number | Limitahan ang pagkarga sa unang N loading meters (mga trak). |
| budget_ms | number | Budget ng oras ng optimisasyon (production; default 30000, max 300000). |
| callback_url | https URL | I-POST ang resulta kapag natapos na ang job, naka-sign (tingnan ang Webhooks). |
Mga field ng item
| Field | Uri | Paglalarawan |
|---|---|---|
| length / width / height | number, required | Mga dimensyon ng item, binabasa sa mga yunit ng kahilingan (mm bilang default, pulgada kapag "units": "imperial"). |
| weight | number, required | Timbang ng item (kg bilang default, lb kapag "units": "imperial"). |
| quantity | integer, default 1 | Pinalalawak sa mga indibidwal na yunit. |
| name | string, optional | Ipapakita sa plano at sa tugon. |
| stackable | boolean, default true | Maaaring maglagay ng ibang kargamento sa ibabaw ng item na ito. |
| max_stack | number, optional | Pinakamataas na timbang na maaaring dalhin ng item na ito sa ibabaw (parehong yunit sa weight). |
| fragile | boolean, default false | Ang mga marupok na item ay inilalagay lamang sa mga itaas na layer. |
| tiltable | boolean, default true | Maaaring ihiga ang item sa gilid nito. |
| destination_stop | integer, default 1 | Paradahan ng paghahatid para sa multi-stop LIFO loading. |
Mga vehicle code
Nagmumula sa mga spec ng live engine. Gumagana ang mga custom na sasakyan mula sa iyong workspace fleet sa pamamagitan ng custom_vehicle_id.
Mga trak at trailer
| Code | Sasakyan | Loob (L×W×H) | Dadalahin |
|---|---|---|---|
| CURTAINSIDER_136 | 13.6m Curtainsider | 13.62 × 2.48 × 2.70 m | 24 t |
| BOX_136 | 13.6m Box Trailer | 13.62 × 2.46 × 2.68 m | 24 t |
| MEGA_136 | 13.6m Mega Trailer | 13.62 × 2.48 × 3.00 m | 22.5 t |
| MEGA_CURTAIN_136 | 13.6m Mega Curtainsider | 13.62 × 2.48 × 3.00 m | 22 t |
| FLATBED_136 | 13.6m Flatbed | 13.62 × 2.48 × 3.00 m | 25 t |
| REEFER_136 | 13.6m Reefer | 13.32 × 2.44 × 2.54 m | 22 t |
| CURTAINSIDER_75 | 7.5m City Curtainsider | 7.50 × 2.48 × 2.70 m | 12 t |
| SWAPBODY_715 | 7.15m Swap Body | 7.15 × 2.48 × 2.70 m | 12 t |
| SWAPBODY_745 | 7.45m Swap Body | 7.45 × 2.48 × 2.70 m | 12 t |
| DRY_VAN_53 | 53ft Dry Van | 16.15 × 2.59 × 2.74 m | 20 t |
| FLATBED_53 | 53ft Flatbed | 16.15 × 2.59 × 3.66 m | 22 t |
| REEFER_53 | 53ft Reefer | 15.85 × 2.46 × 2.59 m | 18.5 t |
| CURTAINSIDER_125_CN | 12.5m Curtainsider (CN) | 12.50 × 2.50 × 2.80 m | 27 t |
| FLATBED_40_IN | 40ft Flatbed (IN) | 12.19 × 2.50 × 3.50 m | 26 t |
| BOX_138_BR | 13.8m Box Van (BR) | 13.80 × 2.50 × 2.90 m | 28 t |
| CURTAINSIDER_12_ZA | 12m Curtainsider (ZA) | 12.00 × 2.48 × 2.70 m | 28 t |
Mga container
| Code | Container | Loob (L×W×H) | Dadalahin |
|---|---|---|---|
| 20DC | 20' Dry Container | 5.89 × 2.35 × 2.39 m | 21.727 t |
| 20HC | 20' High Cube | 5.89 × 2.35 × 2.70 m | 21.58 t |
| 40DC | 40' Dry Container | 12.03 × 2.35 × 2.39 m | 26.63 t |
| 40HC | 40' High Cube | 12.03 × 2.35 × 2.70 m | 26.58 t |
| 45HC | 45' High Cube | 13.56 × 2.35 × 2.70 m | 25.68 t |
| 20OT | 20' Open Top | 5.89 × 2.35 × 2.39 m | 21.64 t |
| 40OT | 40' Open Top | 12.03 × 2.35 × 2.39 m | 26.58 t |
| 20RF | 20' Reefer | 5.44 × 2.29 × 2.27 m | 21 t |
| 40RF | 40' Reefer | 11.58 × 2.29 × 2.21 m | 25.6 t |
| 40RFHC | 40' Reefer High Cube | 11.58 × 2.29 × 2.54 m | 25.88 t |
| 53DC | 53' Domestic | 16.15 × 2.59 × 2.90 m | 26 t |
Mga antas ng access at limitasyon
| Sandbox (bawat plano) | Production (Enterprise) | |
|---|---|---|
| Mga tawag | 25 matagumpay / buwan | 5,000 matagumpay / buwan |
| Mga item sa bawat manifest | 20 | 5,000 |
| Magkakasabay na mga job | 1 | 10 |
| Budget ng optimisasyon | 10 s | 30 s default, hanggang 300 s |
| Pagpapanatili | Walang naitala | Bawat pack ay lumilikha ng tunay na plano sa iyong workspace |
Tanging matagumpay na pag-iimpake lamang ang binibilang — nabigong pagpapatunay at nabigong trabaho ay hindi ibinabawas sa quota. Ang parehong counter ay nagre-reset sa ika-1 (UTC). Ang mga resulta sa sandbox ay kumpleto at walang limitasyon — ang mga limitasyon ang hadlang, hindi ang output. Kailangan mo ba ng higit sa 5,000 pag-iimpake sa isang buwan? Makipag-ugnayan sa amin tungkol sa volume at presyong OEM.
Webhooks
I-pasa ang callback_url para matanggap ang resulta sa pamamagitan ng POST kapag natapos na ang job. Bawat callback ay may kasamang X-Hansatic-Signature: isang HMAC-SHA256 ng raw body gamit ang webhook secret ng iyong key (ipinapakita nang isang beses sa paggawa ng key). Patunayan ito:
const crypto = require('crypto');
function verify(rawBody, signatureHeader, webhookSecret) {
const expected = crypto.createHmac('sha256', webhookSecret)
.update(rawBody).digest('hex');
return crypto.timingSafeEqual(
Buffer.from(expected), Buffer.from(signatureHeader));
}Isang pagtatangka lamang ang paghahatid na may 5s timeout — ang status_url ay laging nananatiling pinagmulan ng katotohanan.
Mga error
Lahat ng error ay { "error": { "code", "message", ... } } — machine-readable na code, mababasang mensahe, at field kapag may partikular na input na may problema.
| Code | HTTP | Kahulugan |
|---|---|---|
| invalid_key | 401 | Nawawala, may mali, o kinanselang API key. |
| invalid_json | 400 | Hindi validong JSON ang body. |
| invalid_vehicle | 400 | Hindi kilalang vehicle code / {customVehicleId}. |
| invalid_items | 400 | May nawawalang field ang isang item, hindi numeriko, o wala sa saklaw. |
| suspicious_dimensions | 400 | Lahat ng dimensyon ay mas mababa sa 100mm — malamang na pulgada ang ipinadala bilang mm. I-pasa ang "units": "imperial". |
| invalid_units | 400 | Ang units ay dapat na "metric" o "imperial". |
| invalid_objective | 400 | Ang objective ay dapat na "ldm" o "pallets". |
| invalid_callback | 400 | Ang callback_url ay dapat na https. |
| too_many_items | 400 | Ang manifest ay lumampas sa limitasyon ng item para sa iyong antas ng access. |
| upgrade_required | 402 | Kailangan ang Enterprise plan para sa production mode. Gumamit ng sandbox, o mag-upgrade. |
| sandbox_limit_reached | 402 | Nagamit na ang buwanang allowance sa sandbox — magre-reset sa ika-1. |
| quota_exceeded | 402 | Nagamit na ang buwanang quota ng produksyon na 5,000 pag-iimpake — nagre-reset sa ika-1. Para sa mas mataas na volume: makipag-ugnayan sa amin. |
| too_many_jobs | 429 | Naabot na ang limitasyon ng magkakasabay na job. Suriin ang mga tumatakbong job at subukang muli. |
| not_found | 404 | Walang ganoong job para sa workspace na ito. |
Mga tanong, mas mataas na limitasyon, o connector na kailangan mo (Zapier, Excel, MCP)? hello@hansatic.com