Packnings-API
Skicka gods, få tillbaka en optimerad och fysiskt giltig lastplan — placeringar, lastmeter, löpmeter och fakturerade pallpositioner. Samma motor som i appen, kontinuerligt validerad mot verkliga dispatcherlayouter. Sandbox-åtkomst på varje plan; produktionsåtkomst på Enterprise.
Kom igång snabbt
- Logga in → klicka på ditt namn → API → generera en nyckel.
- Skicka en packningsuppgift (den här körs i sandbox — gratis på alla 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-..."
}Poll:a status_url (samma autentiseringsheader) tills status är "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/..."
}
}Slutpunkter
POST /api/v1/pack
Validerar och köar en packningsuppgift. Returnerar 202 med ett job_id. Stöder en Idempotency-Key-header — upprepade anrop med samma nyckel returnerar den ursprungliga uppgiften istället för att packa två gånger.
GET /api/v1/jobs/{id}
Uppgiftsstatus och, när den är klar, hela resultatet. Resultat sparas i 30 dagar; produktionsplaner finns kvar permanent i ditt workspace.
GET /api/v1/openapi.json
Det maskinläsbara OpenAPI 3.1-kontraktet — importera det i Postman, kodgeneratorer eller peka ditt AI-kodverktyg mot det. Fordonskoder hämtas från den aktiva motorn, så det är alltid aktuellt. Öppna specifikationen ↗
Svarsfält
result-objektet för en avslutad uppgift:
| Fält | Typ | Beskrivning |
|---|---|---|
| placed_count / unplaced_count | integer | Hur många artiklar som fick plats / inte fick plats. |
| units | "metric" | "imperial" | Enheterna som alla nedanstående värden anges i (återger förfrågan). |
| metrics.ldm_m | number | Lastmeter — godsets utsträckning (max slut − min start). |
| metrics.linear_ft | number | Samma utsträckning i löpmeter (US LTL). |
| metrics.span_mm | integer | Utsträckningen i mm, alltid metriskt. |
| metrics.pallet_positions_eur | integer | null | Fakturerade EUR-pallpositioner. null när layouten är för stor för att mätas. |
| metrics.total_weight_kg | number | Placerad vikt, alltid i kg. |
| metrics.overlaps | integer | Överlappande par — alltid 0 för en giltig layout. |
| items[].placed | boolean | Om artikeln kom med i layouten. |
| items[].x / y / z | number | null | Position i förfrågans enheter: x från dörränden, y från vänster vägg, z från golvet. Alla tre är null när placed är false. |
| items[].rotation_deg / tilt_deg | 0 | 90 | Orientering: rotation kring vertikalaxeln; tilt = liggande på sidan. |
| items[].length / width / height / weight | number | Artikeln som skickades, återgiven i förfrågans enheter. |
| plan_url | string | null | Den skapade planen i appen. null för sandbox-uppgifter. |
Versionshantering och stabilitet
Kontraktet är versionshanterat i sökvägen (/api/v1/). Inom v1 är ändringar endast tillägg — nya valfria fält i förfrågan, nya svarsfält, nya fordonskoder och felkoder kan tillkomma, och klienter bör ignorera fält de inte känner igen. Befintliga fält ändrar aldrig betydelse eller typ, och inget tas bort. En brytande ändring innebär en ny versionssökväg, med v1 som underhålls parallellt i minst 12 månader och avvecklingsmeddelande via e-post till varje workspace med en aktiv nyckel.
Förfrågningsfält
| Fält | Typ | Beskrivning |
|---|---|---|
| vehicle | string | En fordonskod från tabellerna nedan. Eller ange {customVehicleId} (ett fordon från din workspace-flotta). |
| objective | "ldm" | "pallets" | Minimera lastmeter eller fakturerade pallpositioner. Standard "ldm". |
| units | "metric" | "imperial" | Hur artikeldimensioner och vikter tolkas OCH returneras: mm/kg (standard) eller tum/lbs. Positioner i svaret följer samma enheter. |
| items | array, required | Godsmanifestet (fält nedan). |
| sandbox | boolean | Testläge: fullständigt resultat, inget sparas. Tillgängligt på alla plan. |
| name | string | Plannamn (produktionsläge). |
| ldm_limit_m | number | Begränsa lasten till de första N lastmetrarna (lastbilar). |
| budget_ms | number | Tidsbudget för optimering (produktion; standard 30000, max 300000). |
| callback_url | https URL | POST:as med resultatet när uppgiften är klar, signerat (se Webhooks). |
Artikelfält
| Fält | Typ | Beskrivning |
|---|---|---|
| length / width / height | number, required | Artikelns dimensioner, tolkade i förfrågans enheter (mm som standard, tum med "units": "imperial"). |
| weight | number, required | Artikelns vikt (kg som standard, lbs med "units": "imperial"). |
| quantity | integer, default 1 | Expanderas till enskilda enheter. |
| name | string, optional | Visas i planen och svaret. |
| stackable | boolean, default true | Andra gods kan placeras ovanpå denna artikel. |
| max_stack | number, optional | Maximal vikt som artikeln tål ovanpå (samma enheter som vikt). |
| fragile | boolean, default false | Ömtåliga artiklar placeras endast i de översta lagren. |
| tiltable | boolean, default true | Artikeln får läggas på sidan. |
| destination_stop | integer, default 1 | Leveransstopp för flerstoppad LIFO-lastning. |
Fordonskoder
Genererade från den aktiva motorns specifikationer. Anpassade fordon från din workspace-flotta fungerar via custom_vehicle_id.
Lastbilar och släp
| Kod | Fordon | Invändigt (L×B×H) | Lastkapacitet |
|---|---|---|---|
| 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 |
Containrar
| Kod | Container | Invändigt (L×B×H) | Lastkapacitet |
|---|---|---|---|
| 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 |
Åtkomstnivåer och gränser
| Sandbox (alla plan) | Produktion (Enterprise) | |
|---|---|---|
| Anrop | 25 lyckade / månad | 5 000 lyckade / månad |
| Artiklar per manifest | 20 | 5,000 |
| Samtidiga uppgifter | 1 | 10 |
| Optimeringsbudget | 10 s | 30 s som standard, upp till 300 s |
| Lagring | Ingenting sparas | Varje packning skapar en verklig plan i ditt workspace |
Endast lyckade packningar räknas — misslyckad validering och misslyckade jobb debiteras aldrig mot kvoten. Båda räknarna nollställs den 1:a (UTC). Sandbox-resultat är fullständiga och utan begränsningar — gränserna gäller åtkomst, inte resultat. Behöver du mer än 5 000 packningar per månad? Kontakta oss för volym- och OEM-priser.
Webhooks
Ange callback_url för att ta emot resultatet via POST när uppgiften är klar. Varje callback innehåller X-Hansatic-Signature: en HMAC-SHA256 av den råa brödtexten med din nyckels webhook-hemlighet (visas en gång vid nyckelgenerering). Verifiera 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));
}Leverans sker i ett försök med 5s timeout — status_url är alltid den giltiga källan.
Fel
Alla fel har { "error": { "code", "message", ... } } — maskinläsbar kod, läsbar beskrivning och field när ett specifikt inmatningsfält är felaktigt.
| Kod | HTTP | Betydelse |
|---|---|---|
| invalid_key | 401 | Saknad, felaktig eller återkallad API-nyckel. |
| invalid_json | 400 | Brödtexten är inte giltig JSON. |
| invalid_vehicle | 400 | Okänd fordonskod / {customVehicleId}. |
| invalid_items | 400 | Ett artikelfält saknas, är icke-numeriskt eller utanför giltigt intervall. |
| suspicious_dimensions | 400 | Alla dimensioner under 100 mm — troligen tum skickade som mm. Ange "units": "imperial". |
| invalid_units | 400 | units måste vara "metric" eller "imperial". |
| invalid_objective | 400 | objective måste vara "ldm" eller "pallets". |
| invalid_callback | 400 | callback_url måste vara https. |
| too_many_items | 400 | Manifestet överskrider artikelgränsen för din åtkomstnivå. |
| upgrade_required | 402 | Produktionsläge kräver Enterprise-planen. Använd sandbox eller uppgradera. |
| sandbox_limit_reached | 402 | Månadens sandbox-kvot är förbrukad — återställs den 1:a. |
| quota_exceeded | 402 | Månadskvoten på 5 000 packningar är förbrukad — nollställs den 1:a. För högre volymer: kontakta oss. |
| too_many_jobs | 429 | Gränsen för samtidiga uppgifter är nådd. Poll:a pågående uppgifter och försök igen. |
| not_found | 404 | Ingen sådan uppgift för detta workspace. |
Frågor, högre gränser eller en koppling du behöver (Zapier, Excel, MCP)? hello@hansatic.com