API Pakowania
Prześlij ładunek, a otrzymasz zoptymalizowany, fizycznie poprawny plan załadunku — pozycje, metry ładunkowe, stopy liniowe i rozliczane pozycje palet. Ten sam silnik, który napędza aplikację, stale weryfikowany na podstawie rzeczywistych układów dyspozytorów. Dostęp do sandboxa w każdym planie; dostęp produkcyjny w planie Enterprise.
Szybki start
- Zaloguj się → kliknij swoją nazwę → API → wygeneruj klucz.
- Wyślij zadanie pakowania (to działa w sandboxie — bezpłatnie w każdym planie):
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-..."
}Odpytaj status_url (z tym samym nagłówkiem autoryzacyjnym), aż status będzie "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/..."
}
}Punkty końcowe
POST /api/v1/pack
Weryfikuje i kolejkuje zadanie pakowania. Zwraca 202 z job_id. Obsługuje nagłówek Idempotency-Key — ponowne próby z tym samym kluczem zwracają oryginalne zadanie zamiast ponownego pakowania.
GET /api/v1/jobs/{id}
Status zadania oraz, po zakończeniu, pełny wynik. Wyniki są przechowywane przez 30 dni; plany produkcyjne są trwale zapisywane w Twojej przestrzeni roboczej.
GET /api/v1/openapi.json
Zgodny z OpenAPI 3.1 kontrakt w formacie maszynowym — zaimportuj go do Postmana, generatorów kodu lub skieruj na niego narzędzie AI do kodowania. Kody pojazdów są pobierane z działającego silnika, więc specyfikacja jest zawsze aktualna. Otwórz specyfikację ↗
Pola odpowiedzi
Obiekt result dla zakończonego zadania:
| Pole | Typ | Opis |
|---|---|---|
| placed_count / unplaced_count | integer | Ile przedmiotów zmieściło się / nie zmieściło się. |
| units | "metric" | "imperial" | Jednostki, w których wyrażone są wszystkie poniższe wartości (odzwierciedlenie żądania). |
| metrics.ldm_m | number | Metry ładunkowe — długość bloku ładunku (maksymalny koniec − minimalny początek). |
| metrics.linear_ft | number | Ta sama długość w stopach liniowych (US LTL). |
| metrics.span_mm | integer | Długość w mm, zawsze metrycznie. |
| metrics.pallet_positions_eur | integer | null | Rozliczane pozycje palet EUR. null, gdy układ jest zbyt duży do pomiaru. |
| metrics.total_weight_kg | number | Całkowita masa załadunku, zawsze w kg. |
| metrics.overlaps | integer | Pary nakładających się elementów — zawsze 0 dla poprawnego układu. |
| items[].placed | boolean | Czy przedmiot trafił do układu. |
| items[].x / y / z | number | null | Pozycja w jednostkach żądania: x od strony drzwi, y od lewej ściany, z od podłogi. Wszystkie trzy mają wartość null, gdy placed jest false. |
| items[].rotation_deg / tilt_deg | 0 | 90 | Orientacja: obrót wokół osi pionowej; tilt = położony na boku. |
| items[].length / width / height / weight | number | Przedmiot zgodnie z danymi wejściowymi, w jednostkach żądania. |
| plan_url | string | null | Utworzony plan w aplikacji. null dla zadań w sandboxie. |
Wersjonowanie i stabilność
Kontrakt jest wersjonowany w ścieżce (/api/v1/). W ramach v1 zmiany są tylko dodawane — nowe opcjonalne pola żądania, nowe pola odpowiedzi, nowe kody pojazdów i kody błędów mogą się pojawić, a klienci powinni ignorować pola, których nie rozpoznają. Istniejące pola nigdy nie zmieniają znaczenia ani typu, a nic nie jest usuwane. Zmiana łamiąca oznacza nową ścieżkę wersji, przy czym v1 jest utrzymywana równolegle przez co najmniej 12 miesięcy, a o wycofaniu powiadamiamy e-mailem każdą przestrzeń roboczą z aktywnym kluczem.
Pola żądania
| Pole | Typ | Opis |
|---|---|---|
| vehicle | string | Kod pojazdu z poniższych tabel. Można też przekazać {customVehicleId} (pojazd z floty w Twojej przestrzeni roboczej). |
| objective | "ldm" | "pallets" | Minimalizacja metrów ładunkowych lub rozliczanych pozycji palet. Domyślnie „ldm”. |
| units | "metric" | "imperial" | Jednostki, w jakich podawane i zwracane są wymiary oraz wagi przedmiotów: mm/kg (domyślnie) lub in/lb. Pozycje w odpowiedzi są w tych samych jednostkach. |
| items | array, required | Lista ładunku (pola poniżej). |
| sandbox | boolean | Tryb testowy: pełny wynik, nic nie jest zapisywane. Dostępny w każdym planie. |
| name | string | Nazwa planu (tryb produkcyjny). |
| ldm_limit_m | number | Ograniczenie załadunku do pierwszych N metrów ładunkowych (ciężarówki). |
| budget_ms | number | Limit czasu optymalizacji (tryb produkcyjny; domyślnie 30000, maksymalnie 300000). |
| callback_url | https URL | Adres URL, na który zostanie wysłany wynik POST po zakończeniu zadania, podpisany (zob. Webhooki). |
Pola przedmiotów
| Pole | Typ | Opis |
|---|---|---|
| length / width / height | number, required | Wymiary przedmiotu, odczytywane w jednostkach żądania (domyślnie mm, cale przy „units”: „imperial”). |
| weight | number, required | Masa przedmiotu (domyślnie kg, funty przy „units”: „imperial”). |
| quantity | integer, default 1 | Rozwija się na pojedyncze jednostki. |
| name | string, optional | Wyświetlane w planie i odpowiedzi. |
| stackable | boolean, default true | Czy na tym przedmiocie może spoczywać inny ładunek. |
| max_stack | number, optional | Maksymalna masa, jaką ten przedmiot może udźwignąć (w tych samych jednostkach co waga). |
| fragile | boolean, default false | Przedmioty kruche są umieszczane tylko w górnych warstwach. |
| tiltable | boolean, default true | Czy przedmiot może być położony na boku. |
| destination_stop | integer, default 1 | Przystanek dostawy w przypadku załadunku LIFO z wieloma przystankami. |
Kody pojazdów
Generowane na podstawie specyfikacji działającego silnika. Pojazdy niestandardowe z floty w Twojej przestrzeni roboczej działają poprzez custom_vehicle_id.
Ciężarówki i naczepy
| Kod | Pojazd | Wymiary wewnętrzne (D×S×W) | Ładowność |
|---|---|---|---|
| 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 |
Kontenery
| Kod | Kontener | Wymiary wewnętrzne (D×S×W) | Ładowność |
|---|---|---|---|
| 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 |
Poziomy dostępu i limity
| Sandbox (każdy plan) | Produkcja (Enterprise) | |
|---|---|---|
| Wywołania | 25 udanych / miesiąc | 5 000 udanych pakowań / miesiąc |
| Przedmiotów na listę | 20 | 5,000 |
| Zadań równoczesnych | 1 | 10 |
| Limit optymalizacji | 10 s | 30 s domyślnie, do 300 s |
| Trwałość | Nic nie jest zapisywane | Każde pakowanie tworzy rzeczywisty plan w Twojej przestrzeni roboczej |
Liczone są tylko udane pakowania — nieudane walidacje i nieudane zadania nigdy nie są wliczane do limitu. Liczniki są resetowane 1. dnia miesiąca (UTC). Wyniki w środowisku sandbox są kompletne i nieograniczone — limity dotyczą jedynie dostępu, a nie funkcjonalności. Potrzebujesz więcej niż 5 000 pakowań miesięcznie? Skontaktuj się z nami w sprawie oferty dla dużych wolumenów i licencji OEM.
Webhooki
Przekaż callback_url, aby otrzymać wynik POST po zakończeniu zadania. Każde wywołanie zawiera X-Hansatic-Signature: HMAC-SHA256 treści surowego ciała z użyciem tajnego klucza webhooka (wyświetlanego jednokrotnie przy tworzeniu klucza). Zweryfikuj go:
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));
}Dostarczenie odbywa się w jednej próbie z limitem czasu 5 s — status_url zawsze pozostaje źródłem prawdy.
Błędy
Wszystkie błędy mają kształt { "error": { "code", "message", ... } } — czytelny dla maszyn kod, czytelna dla człowieka wiadomość oraz field, gdy winne jest konkretne pole wejściowe.
| Kod | HTTP | Znaczenie |
|---|---|---|
| invalid_key | 401 | Brak, nieprawidłowy lub unieważniony klucz API. |
| invalid_json | 400 | Treść nie jest poprawnym JSON. |
| invalid_vehicle | 400 | Nieznany kod pojazdu / {customVehicleId}. |
| invalid_items | 400 | Pole przedmiotu jest brakujące, nienumeryczne lub poza zakresem. |
| suspicious_dimensions | 400 | Wszystkie wymiary poniżej 100 mm — prawdopodobnie cale wysłane jako mm. Przekaż „units”: „imperial”. |
| invalid_units | 400 | units musi być „metric” lub „imperial”. |
| invalid_objective | 400 | objective musi być „ldm” lub „pallets”. |
| invalid_callback | 400 | callback_url musi być https. |
| too_many_items | 400 | Lista ładunku przekracza limit przedmiotów dla Twojego poziomu dostępu. |
| upgrade_required | 402 | Tryb produkcyjny wymaga planu Enterprise. Użyj sandboxa lub uaktualnij plan. |
| sandbox_limit_reached | 402 | Miesięczny limit sandboxa wyczerpany — resetuje się 1. dnia miesiąca. |
| quota_exceeded | 402 | Wykorzystano miesięczny limit 5 000 pakowań — licznik zostanie zresetowany 1. dnia miesiąca. W przypadku większych wolumenów: skontaktuj się z nami. |
| too_many_jobs | 429 | Osiągnięto limit zadań równoczesnych. Odpytaj uruchomione zadania i spróbuj ponownie. |
| not_found | 404 | Brak takiego zadania dla tej przestrzeni roboczej. |
Pytania, wyższe limity lub potrzebny konektor (Zapier, Excel, MCP)? hello@hansatic.com