API de Planificare a Încărcăturii
Trimiteți marfă și primiți înapoi un plan de încărcare optimizat, valid din punct de vedere fizic — poziționări, metri de încărcare, picioare liniare și poziții de paleți facturabile. Același motor din spatele aplicației, validat continuu în raport cu planurile reale ale dispecerilor. Acces sandbox pe fiecare plan; acces în producție pe planul Enterprise.
Începeți rapid
- Autentificați-vă → faceți clic pe numele dvs. → API → generați o cheie.
- Trimiteți o cerere de planificare (aceasta rulează în sandbox — gratuit pe fiecare plan):
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-..."
}Interogați status_url (cu același antet de autentificare) până când status este "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/..."
}
}Endpoint-uri
POST /api/v1/pack
Validează și pune în coadă o cerere de planificare. Returnează 202 cu un job_id. Suportă antetul Idempotency-Key — reluările cu aceeași cheie returnează cererea originală în loc să planifice de două ori.
GET /api/v1/jobs/{id}
Starea cererii și, la finalizare, rezultatul complet. Rezultatele sunt păstrate timp de 30 de zile; planurile de producție rămân permanent în spațiul dvs. de lucru.
GET /api/v1/openapi.json
Contractul OpenAPI 3.1, citibil de mașină — importați-l în Postman, generatoare de cod sau direcționați instrumentul dvs. de codare AI către el. Codurile de vehicule sunt injectate din motorul live, astfel încât este mereu actualizat. Deschideți specificația ↗
Câmpuri de răspuns
Obiectul result pentru o cerere finalizată:
| Câmp | Tip | Descriere |
|---|---|---|
| placed_count / unplaced_count | integer | Câte articole au încăput / nu au încăput. |
| units | "metric" | "imperial" | Unitățile în care sunt exprimate toate valorile numerice de mai jos (repetă cererea). |
| metrics.ldm_m | number | Metri de încărcare — lungimea blocului de marfă (max. capăt − min. început). |
| metrics.linear_ft | number | Aceeași lungime în picioare liniare (US LTL). |
| metrics.span_mm | integer | Lungimea în mm, întotdeauna metric. |
| metrics.pallet_positions_eur | integer | null | Poziții de paleți EUR facturabile. null dacă planul este prea mare pentru a fi măsurat. |
| metrics.total_weight_kg | number | Greutatea încărcată, întotdeauna în kg. |
| metrics.overlaps | integer | Perechi care se suprapun — întotdeauna 0 pentru un plan valid. |
| items[].placed | boolean | Dacă articolul a fost inclus în plan. |
| items[].x / y / z | number | null | Poziție în unitățile cererii: x de la capătul ușii, y de la peretele stâng, z de la podea. Toate trei sunt null dacă placed este false. |
| items[].rotation_deg / tilt_deg | 0 | 90 | Orientare: rotație în jurul axei verticale; tilt = așezat pe o parte. |
| items[].length / width / height / weight | number | Articolul așa cum a fost trimis, repetat în unitățile cererii. |
| plan_url | string | null | Planul creat în aplicație. null pentru cererile în sandbox. |
Versiuni și stabilitate
Contractul este versionat în calea (/api/v1/). În cadrul v1, modificările sunt doar aditive — noi câmpuri opționale în cerere, noi câmpuri în răspuns, noi coduri de vehicule și coduri de eroare pot apărea, iar clienții trebuie să ignore câmpurile pe care nu le recunosc. Câmpurile existente nu își schimbă niciodată semnificația sau tipul, iar nimic nu este eliminat. O modificare incompatibilă înseamnă o nouă cale de versiune, cu v1 menținut în paralel timp de cel puțin 12 luni și notificare de depreciere prin e-mail către fiecare spațiu de lucru cu o cheie activă.
Câmpuri de cerere
| Câmp | Tip | Descriere |
|---|---|---|
| vehicle | string | Un cod de vehicul din tabelele de mai jos. Sau trimiteți {customVehicleId} (un vehicul din flota spațiului dvs. de lucru). |
| objective | "ldm" | "pallets" | Minimizați metrii de încărcare sau pozițiile de paleți facturabile. Valoare implicită: "ldm". |
| units | "metric" | "imperial" | Cum sunt interpretate și returnate dimensiunile și greutățile articolelor: mm/kg (implicit) sau in/lb. Pozițiile din răspuns folosesc aceleași unități. |
| items | array, required | Lista de marfă (câmpurile de mai jos). |
| sandbox | boolean | Mod de test: rezultat complet, nimic nu este salvat. Disponibil pe fiecare plan. |
| name | string | Numele planului (mod producție). |
| ldm_limit_m | number | Restricționați încărcarea la primii N metri de încărcare (camioane). |
| budget_ms | number | Buget de timp pentru optimizare (producție; implicit 30000, maxim 300000). |
| callback_url | https URL | Adresa URL la care se trimite rezultatul prin POST la finalizarea cererii, semnat (vezi Webhook-uri). |
Câmpuri pentru articole
| Câmp | Tip | Descriere |
|---|---|---|
| length / width / height | number, required | Dimensiunile articolului, interpretate în unitățile cererii (mm implicit, țoli cu "units": "imperial"). |
| weight | number, required | Greutatea articolului (kg implicit, lb cu "units": "imperial"). |
| quantity | integer, default 1 | Se extinde în unități individuale. |
| name | string, optional | Afișat în plan și în răspuns. |
| stackable | boolean, default true | Permite plasarea altor articole deasupra acestuia. |
| max_stack | number, optional | Greutatea maximă pe care o poate suporta deasupra (aceleași unități ca greutatea). |
| fragile | boolean, default false | Articolele fragile sunt plasate doar în straturile superioare. |
| tiltable | boolean, default true | Dacă articolul poate fi așezat pe o parte. |
| destination_stop | integer, default 1 | Oprirea de livrare pentru încărcarea LIFO cu mai multe opriri. |
Coduri de vehicule
Generate din specificațiile motorului live. Vehiculele personalizate din flota spațiului dvs. de lucru funcționează prin custom_vehicle_id.
Camioane și remorci
| Cod | Vehicul | Interior (L×l×H) | Capacitate de încărcare |
|---|---|---|---|
| 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 |
Containere
| Cod | Container | Interior (L×l×H) | Capacitate de încărcare |
|---|---|---|---|
| 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 |
Nivele de acces și limite
| Sandbox (pe fiecare plan) | Producție (Enterprise) | |
|---|---|---|
| Apeluri | 25 reușite / lună | 5.000 de planificări reușite / lună |
| Articole per listă de marfă | 20 | 5,000 |
| Cereri concurente | 1 | 10 |
| Buget de optimizare | 10 s | 30 s implicit, până la 300 s |
| Persistență | Nimic stocat | Fiecare planificare creează un plan real în spațiul dvs. de lucru |
Sunt luate în calcul doar planificările reușite — validările eșuate și sarcinile nereușite nu sunt facturate la cota lunară. Ambele contoare se resetează pe data de 1 (UTC). Rezultatele din mediul Sandbox sunt complete și nealterate — limitele reprezintă pragul de acces, nu calitatea ieșirii. Aveți nevoie de peste 5.000 de planificări pe lună? Discutați cu noi despre tarifele pentru volume mari și parteneriate OEM.
Webhook-uri
Trimiteți callback_url pentru a primi rezultatul prin POST la finalizarea cererii. Fiecare callback include X-Hansatic-Signature: un HMAC-SHA256 al corpului brut cu secretul webhook-ului cheii dvs. (afișat o singură dată la crearea cheii). Verificați-l:
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));
}Livrarea se face într-o singură încercare cu timeout de 5s — status_url rămâne întotdeauna sursa de adevăr.
Erori
Toate erorile sunt de forma { "error": { "code", "message", ... } } — cod citibil de mașină, mesaj lizibil pentru om și field când un anumit câmp de intrare este defect.
| Cod | HTTP | Semnificație |
|---|---|---|
| invalid_key | 401 | Cheie API lipsă, formatată greșit sau revocată. |
| invalid_json | 400 | Corpul nu este un JSON valid. |
| invalid_vehicle | 400 | Cod de vehicul / {customVehicleId} necunoscut. |
| invalid_items | 400 | Un câmp al articolului lipsește, nu este numeric sau este în afara intervalului. |
| suspicious_dimensions | 400 | Toate dimensiunile sub 100mm — probabil țoli trimiși ca mm. Trimiteți "units": "imperial". |
| invalid_units | 400 | units trebuie să fie "metric" sau "imperial". |
| invalid_objective | 400 | objective trebuie să fie "ldm" sau "pallets". |
| invalid_callback | 400 | callback_url trebuie să fie https. |
| too_many_items | 400 | Lista de marfă depășește limita de articole pentru nivelul dvs. de acces. |
| upgrade_required | 402 | Modul producție necesită planul Enterprise. Folosiți sandbox sau faceți upgrade. |
| sandbox_limit_reached | 402 | Alocația lunară de sandbox a fost consumată — se reînnoiește la 1. |
| quota_exceeded | 402 | Cota lunară de 5.000 de planificări a fost epuizată — se resetează pe data de 1. Pentru volume mai mari: contactați-ne. |
| too_many_jobs | 429 | Limita de cereri concurente a fost atinsă. Interogați cererile în curs și încercați din nou. |
| not_found | 404 | Nu există o astfel de cerere pentru acest spațiu de lucru. |
Întrebări, limite mai mari sau un conector de care aveți nevoie (Zapier, Excel, MCP)? hello@hansatic.com