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

  1. Autentificați-vă → faceți clic pe numele dvs. → API → generați o cheie.
  2. 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âmpTipDescriere
placed_count / unplaced_countintegerCâ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_mnumberMetri de încărcare — lungimea blocului de marfă (max. capăt − min. început).
metrics.linear_ftnumberAceeași lungime în picioare liniare (US LTL).
metrics.span_mmintegerLungimea în mm, întotdeauna metric.
metrics.pallet_positions_eurinteger | nullPoziții de paleți EUR facturabile. null dacă planul este prea mare pentru a fi măsurat.
metrics.total_weight_kgnumberGreutatea încărcată, întotdeauna în kg.
metrics.overlapsintegerPerechi care se suprapun — întotdeauna 0 pentru un plan valid.
items[].placedbooleanDacă articolul a fost inclus în plan.
items[].x / y / znumber | nullPoziț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_deg0 | 90Orientare: rotație în jurul axei verticale; tilt = așezat pe o parte.
items[].length / width / height / weightnumberArticolul așa cum a fost trimis, repetat în unitățile cererii.
plan_urlstring | nullPlanul 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âmpTipDescriere
vehiclestringUn 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.
itemsarray, requiredLista de marfă (câmpurile de mai jos).
sandboxbooleanMod de test: rezultat complet, nimic nu este salvat. Disponibil pe fiecare plan.
namestringNumele planului (mod producție).
ldm_limit_mnumberRestricționați încărcarea la primii N metri de încărcare (camioane).
budget_msnumberBuget de timp pentru optimizare (producție; implicit 30000, maxim 300000).
callback_urlhttps URLAdresa URL la care se trimite rezultatul prin POST la finalizarea cererii, semnat (vezi Webhook-uri).

Câmpuri pentru articole

CâmpTipDescriere
length / width / heightnumber, requiredDimensiunile articolului, interpretate în unitățile cererii (mm implicit, țoli cu "units": "imperial").
weightnumber, requiredGreutatea articolului (kg implicit, lb cu "units": "imperial").
quantityinteger, default 1Se extinde în unități individuale.
namestring, optionalAfișat în plan și în răspuns.
stackableboolean, default truePermite plasarea altor articole deasupra acestuia.
max_stacknumber, optionalGreutatea maximă pe care o poate suporta deasupra (aceleași unități ca greutatea).
fragileboolean, default falseArticolele fragile sunt plasate doar în straturile superioare.
tiltableboolean, default trueDacă articolul poate fi așezat pe o parte.
destination_stopinteger, default 1Oprirea 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

CodVehiculInterior (L×l×H)Capacitate de încărcare
CURTAINSIDER_13613.6m Curtainsider13.62 × 2.48 × 2.70 m24 t
BOX_13613.6m Box Trailer13.62 × 2.46 × 2.68 m24 t
MEGA_13613.6m Mega Trailer13.62 × 2.48 × 3.00 m22.5 t
MEGA_CURTAIN_13613.6m Mega Curtainsider13.62 × 2.48 × 3.00 m22 t
FLATBED_13613.6m Flatbed13.62 × 2.48 × 3.00 m25 t
REEFER_13613.6m Reefer13.32 × 2.44 × 2.54 m22 t
CURTAINSIDER_757.5m City Curtainsider7.50 × 2.48 × 2.70 m12 t
SWAPBODY_7157.15m Swap Body7.15 × 2.48 × 2.70 m12 t
SWAPBODY_7457.45m Swap Body7.45 × 2.48 × 2.70 m12 t
DRY_VAN_5353ft Dry Van16.15 × 2.59 × 2.74 m20 t
FLATBED_5353ft Flatbed16.15 × 2.59 × 3.66 m22 t
REEFER_5353ft Reefer15.85 × 2.46 × 2.59 m18.5 t
CURTAINSIDER_125_CN12.5m Curtainsider (CN)12.50 × 2.50 × 2.80 m27 t
FLATBED_40_IN40ft Flatbed (IN)12.19 × 2.50 × 3.50 m26 t
BOX_138_BR13.8m Box Van (BR)13.80 × 2.50 × 2.90 m28 t
CURTAINSIDER_12_ZA12m Curtainsider (ZA)12.00 × 2.48 × 2.70 m28 t

Containere

CodContainerInterior (L×l×H)Capacitate de încărcare
20DC20' Dry Container5.89 × 2.35 × 2.39 m21.727 t
20HC20' High Cube5.89 × 2.35 × 2.70 m21.58 t
40DC40' Dry Container12.03 × 2.35 × 2.39 m26.63 t
40HC40' High Cube12.03 × 2.35 × 2.70 m26.58 t
45HC45' High Cube13.56 × 2.35 × 2.70 m25.68 t
20OT20' Open Top5.89 × 2.35 × 2.39 m21.64 t
40OT40' Open Top12.03 × 2.35 × 2.39 m26.58 t
20RF20' Reefer5.44 × 2.29 × 2.27 m21 t
40RF40' Reefer11.58 × 2.29 × 2.21 m25.6 t
40RFHC40' Reefer High Cube11.58 × 2.29 × 2.54 m25.88 t
53DC53' Domestic16.15 × 2.59 × 2.90 m26 t

Nivele de acces și limite

Sandbox (pe fiecare plan)Producție (Enterprise)
Apeluri25 reușite / lună5.000 de planificări reușite / lună
Articole per listă de marfă205,000
Cereri concurente110
Buget de optimizare10 s30 s implicit, până la 300 s
PersistențăNimic stocatFiecare 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.

CodHTTPSemnificație
invalid_key401Cheie API lipsă, formatată greșit sau revocată.
invalid_json400Corpul nu este un JSON valid.
invalid_vehicle400Cod de vehicul / {customVehicleId} necunoscut.
invalid_items400Un câmp al articolului lipsește, nu este numeric sau este în afara intervalului.
suspicious_dimensions400Toate dimensiunile sub 100mm — probabil țoli trimiși ca mm. Trimiteți "units": "imperial".
invalid_units400units trebuie să fie "metric" sau "imperial".
invalid_objective400objective trebuie să fie "ldm" sau "pallets".
invalid_callback400callback_url trebuie să fie https.
too_many_items400Lista de marfă depășește limita de articole pentru nivelul dvs. de acces.
upgrade_required402Modul producție necesită planul Enterprise. Folosiți sandbox sau faceți upgrade.
sandbox_limit_reached402Alocația lunară de sandbox a fost consumată — se reînnoiește la 1.
quota_exceeded402Cota 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_jobs429Limita de cereri concurente a fost atinsă. Interogați cererile în curs și încercați din nou.
not_found404Nu 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