Pakke-API
Send last, få tilbake en optimalisert og fysisk gyldig lastplan — plasseringer, laste-meter, lineære fot og fakturerte pallposisjoner. Samme motor som i appen, kontinuerlig validert mot reelle dispatchers oppsett. Sandbox-tilgang på alle abonnementer; produksjonstilgang på Enterprise.
Kom i gang
- Logg inn → klikk på navnet ditt → API → generer en nøkkel.
- Send en pakkejobb (denne kjører i sandbox — gratis på alle abonnementer):
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-..."
}Poll status_url (samme autentiseringsheader) til status er "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/..."
}
}Endepunkter
POST /api/v1/pack
Validerer og setter en pakkejobb i kø. Returnerer 202 med en job_id. Støtter en Idempotency-Key-header — gjentatte forespørsler med samme nøkkel returnerer den opprinnelige jobben i stedet for å pakke på nytt.
GET /api/v1/jobs/{id}
Jobbstatus og, når ferdig, hele resultatet. Resultater lagres i 30 dager; produksjonsplaner lagres permanent i arbeidsområdet ditt.
GET /api/v1/openapi.json
Den maskinlesbare OpenAPI 3.1-kontrakten — importer den i Postman, kodegeneratorer eller pek AI-kodeverktøyet ditt mot den. Kjøretøykoder hentes fra den aktive motoren, så den er alltid oppdatert. Åpne spesifikasjonen ↗
Svarsfelt
result-objektet for en fullført jobb:
| Felt | Type | Beskrivelse |
|---|---|---|
| placed_count / unplaced_count | integer | Hvor mange enheter som passet / ikke passet. |
| units | "metric" | "imperial" | Enhetene alle tall nedenfor er uttrykt i (gjentar forespørselen). |
| metrics.ldm_m | number | Laste-meter — utstrekningen av lastblokken (maks slutt − min start). |
| metrics.linear_ft | number | Samme utstrekning i lineære fot (US LTL). |
| metrics.span_mm | integer | Utstrekningen i mm, alltid metrisk. |
| metrics.pallet_positions_eur | integer | null | Fakturerte EUR-pallposisjoner. null når oppsettet er for stort til å måle. |
| metrics.total_weight_kg | number | Plassert vekt, alltid kg. |
| metrics.overlaps | integer | Gjennomtrengende par — alltid 0 for et gyldig oppsett. |
| items[].placed | boolean | Om enheten kom med i oppsettet. |
| items[].x / y / z | number | null | Posisjon i forespurte enheter: x fra dørsiden, y fra venstre vegg, z fra gulvet. Alle tre er null når placed er false. |
| items[].rotation_deg / tilt_deg | 0 | 90 | Orientering: rotasjon om vertikal akse; tilt = lagt på siden. |
| items[].length / width / height / weight | number | Enheten slik den ble sendt inn, gjentatt i forespurte enheter. |
| plan_url | string | null | Den opprettede planen i appen. null for sandbox-jobber. |
Versjonering og stabilitet
Kontrakten er versjonert i stien (/api/v1/). Innen v1 er endringer kun additive — nye valgfrie forespørselsfelt, nye svarsfelt, nye kjøretøykoder og feilkoder kan dukke opp, og klienter bør ignorere felt de ikke kjenner igjen. Eksisterende felt endrer aldri betydning eller type, og ingenting fjernes. En brytende endring medfører en ny versjonssti, med v1 vedlikeholdt parallelt i minst 12 måneder og varsel om utfasing sendt på e-post til alle arbeidsområder med en aktiv nøkkel.
Forespørselsfelt
| Felt | Type | Beskrivelse |
|---|---|---|
| vehicle | string | En kjøretøykode fra tabellene nedenfor. Eller angi {customVehicleId} (et kjøretøy fra flåten i arbeidsområdet ditt). |
| objective | "ldm" | "pallets" | Minimer laste-meter eller fakturerte pallposisjoner. Standard "ldm". |
| units | "metric" | "imperial" | Hvordan enhetsdimensjoner og vekter leses OG returneres: mm/kg (standard) eller in/lb. Posisjoner i svaret følger samme enheter. |
| items | array, required | Lastemanifestet (feltene nedenfor). |
| sandbox | boolean | Testmodus: fullt resultat, ingenting lagres. Tilgjengelig på alle abonnementer. |
| name | string | Plannavn (produksjonsmodus). |
| ldm_limit_m | number | Begrens lasten til de første N laste-meterne (lastebiler). |
| budget_ms | number | Optimaliseringstidsbudsjett (produksjon; standard 30000, maks 300000). |
| callback_url | https URL | POSTes resultatet når jobben er ferdig, signert (se Webhooks). |
Enhetsfelt
| Felt | Type | Beskrivelse |
|---|---|---|
| length / width / height | number, required | Enhetens dimensjoner, lest i forespørselens enheter (mm som standard, tommer med "units": "imperial"). |
| weight | number, required | Enhetens vekt (kg som standard, lb med "units": "imperial"). |
| quantity | integer, default 1 | Utvides til individuelle enheter. |
| name | string, optional | Vises i planen og svaret. |
| stackable | boolean, default true | Andre enheter kan stables på toppen av denne. |
| max_stack | number, optional | Maks vekt denne enheten tåler på toppen (samme enheter som vekt). |
| fragile | boolean, default false | Skjøre enheter plasseres kun i de øverste lagene. |
| tiltable | boolean, default true | Om enheten kan legges på siden. |
| destination_stop | integer, default 1 | Leveringsstopp for lasting med LIFO-prinsipp (flere stopp). |
Kjøretøykoder
Generert fra de aktive motorspesifikasjonene. Egendefinerte kjøretøy fra flåten i arbeidsområdet ditt fungerer via custom_vehicle_id.
Lastebiler og tilhengere
| Kode | Kjøretøy | Interiør (L×B×H) | Lastekapasitet |
|---|---|---|---|
| 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
| Kode | Container | Interiør (L×B×H) | Lastekapasitet |
|---|---|---|---|
| 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 |
Tilgangsnivåer og grenser
| Sandbox (alle abonnementer) | Produksjon (Enterprise) | |
|---|---|---|
| Forespørsler | 25 vellykkede / måned | 5 000 vellykkede / måned |
| Enheter per manifest | 20 | 5,000 |
| Samtidige jobber | 1 | 10 |
| Optimaliseringsbudsjett | 10 s | 30 s standard, opptil 300 s |
| Lagring | Ingenting lagres | Hver pakking oppretter en reell plan i arbeidsområdet ditt |
Bare vellykkede pakkinger telles — mislykkede valideringer og mislykkede jobber belaster aldri en kvote. Begge tellerne nullstilles den 1. (UTC). Sandbox-resultater er komplette og ubegrensede — grensene gjelder tilgangen, ikke resultatet. Trenger du mer enn 5 000 pakkinger i måneden? Ta kontakt for volum- og OEM-priser.
Webhooks
Angi callback_url for å motta resultatet via POST når jobben er ferdig. Hver callback inneholder X-Hansatic-Signature: en HMAC-SHA256 av rådataene med webhook-hemmeligheten din (vises én gang ved nøkkelopprettelse). Verifiser den:
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));
}Levering er ett forsøk med 5s timeout — status_url forblir alltid den endelige sannhetskilden.
Feil
Alle feil er { "error": { "code", "message", ... } } — maskinlesbar kode, menneskelig lesbar melding, og field når et bestemt inndatafelt er feil.
| Kode | HTTP | Betydning |
|---|---|---|
| invalid_key | 401 | Manglende, feilformet eller tilbakekalt API-nøkkel. |
| invalid_json | 400 | Innholdet er ikke gyldig JSON. |
| invalid_vehicle | 400 | Ukjent kjøretøykode / {customVehicleId}. |
| invalid_items | 400 | Et enhetsfelt mangler, er ikke numerisk eller utenfor gyldig område. |
| suspicious_dimensions | 400 | Alle dimensjoner under 100 mm — sannsynligvis tommer sendt som mm. Angi "units": "imperial". |
| invalid_units | 400 | units må være "metric" eller "imperial". |
| invalid_objective | 400 | objective må være "ldm" eller "pallets". |
| invalid_callback | 400 | callback_url må være https. |
| too_many_items | 400 | Manifestet overskrider enhetsgrensen for ditt tilgangsnivå. |
| upgrade_required | 402 | Produksjonsmodus krever Enterprise-abonnement. Bruk sandbox eller oppgrader. |
| sandbox_limit_reached | 402 | Månedlig sandbox-kvote brukt — tilbakestilles den 1. |
| quota_exceeded | 402 | Månedlig produksjonskvote på 5 000 pakkinger er brukt — nullstilles den 1. Ønsker du høyere volum: ta kontakt. |
| too_many_jobs | 429 | Grensen for samtidige jobber er nådd. Poll pågående jobber og prøv igjen. |
| not_found | 404 | Ingen slik jobb for dette arbeidsområdet. |
Spørsmål, høyere grenser eller en tilkobling du trenger (Zapier, Excel, MCP)? hello@hansatic.com