Packing API
Изпратете товар и получете оптимизиран, физически валиден план за натоварване — разположение, товарни метри, линейни футове и платени позиции на палети. Същият алгоритъм, който задвижва приложението, непрекъснато валидиран спрямо реални планове на диспечери. Достъп до сандбокс във всеки план; производствен достъп в Enterprise.
Бърз старт
- Влезте в профила си → кликнете върху името си → API → генерирайте ключ.
- Изпратете заявка за пакетиране (тази работи в сандбокс — безплатно във всеки план):
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-..."
}Проверете status_url (със същия хедър за автентикация), докато status стане "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/..."
}
}Ендпойнти
POST /api/v1/pack
Валидира и поставя в опашка заявка за пакетиране. Връща 202 с job_id. Поддържа хедър Idempotency-Key — повторни заявки със същия ключ връщат оригиналната заявка вместо да пакетират отново.
GET /api/v1/jobs/{id}
Статус на заявката и, при завършване, пълният резултат. Резултатите се съхраняват 30 дни; производствените планове остават трайно във вашия работен профил.
GET /api/v1/openapi.json
Машиночетим OpenAPI 3.1 договор — импортирайте го в Postman, генератори на код или насочете към него вашия AI инструмент за програмиране. Кодовете на превозните средства се зареждат от актуалния алгоритъм, така че спецификацията винаги е актуална. Отворете спецификацията ↗
Полета в отговора
Обектът result при завършена заявка:
| Поле | Тип | Описание |
|---|---|---|
| placed_count / unplaced_count | integer | Колко артикула са вместени / не са вместени. |
| units | "metric" | "imperial" | Мерните единици, в които са изразени всички числа по-долу (повтарят заявката). |
| metrics.ldm_m | number | Товарни метри — дължината на товарния блок (максимален край − минимално начало). |
| metrics.linear_ft | number | Същата дължина в линейни футове (за американски LTL). |
| metrics.span_mm | integer | Дължината в милиметри, винаги метрична. |
| metrics.pallet_positions_eur | integer | null | Платени EUR палетни позиции. null, ако планът е твърде голям за измерване. |
| metrics.total_weight_kg | number | Общо тегло на вместените артикули, винаги в кг. |
| metrics.overlaps | integer | Двойки с припокриване — винаги 0 за валиден план. |
| items[].placed | boolean | Дали артикулът е вместен в плана. |
| items[].x / y / z | number | null | Позиция в мерните единици от заявката: x откъм вратата, y от лявата стена, z от пода. И трите са null, ако placed е false. |
| items[].rotation_deg / tilt_deg | 0 | 90 | Ориентация: завъртане около вертикалната ос; tilt = поставен на една страна. |
| items[].length / width / height / weight | number | Артикулът, както е подаден, в мерните единици от заявката. |
| plan_url | string | null | Създаденият план в приложението. null за заявки в сандбокс. |
Версиониране и стабилност
Договорът е версиониран в пътя (/api/v1/). В рамките на v1 промените са само добавящи — нови незадължителни полета в заявката, нови полета в отговора, нови кодове на превозни средства и грешки, като клиентите трябва да игнорират полета, които не разпознават. Съществуващите полета никога не променят значение или тип, и нищо не се премахва. Разрушаваща промяна означава нов път за версията, като v1 се поддържа паралелно поне 12 месеца и се изпраща известие за отпадане по имейл до всеки работен профил с активен ключ.
Полета в заявката
| Поле | Тип | Описание |
|---|---|---|
| vehicle | string | Код на превозно средство от таблиците по-долу. Или използвайте {customVehicleId} (превозно средство от вашия флот в работния профил). |
| objective | "ldm" | "pallets" | Минимизиране на товарните метри или на платените палетни позиции. По подразбиране „ldm“. |
| units | "metric" | "imperial" | Как се интерпретират и връщат размерите и теглата на артикулите: mm/kg (по подразбиране) или in/lb. Позициите в отговора следват същите мерни единици. |
| items | array, required | Манифест на товара (полетата по-долу). |
| sandbox | boolean | Тестов режим: пълен резултат, без съхранение. Достъпен във всеки план. |
| name | string | Име на плана (в производствен режим). |
| ldm_limit_m | number | Ограничаване на товара до първите N товарни метри (камиони). |
| budget_ms | number | Бюджет за време на оптимизация (производствен режим; по подразбиране 30000, максимум 300000). |
| callback_url | https URL | Изпраща се POST с резултата при завършване на заявката, подписан (вижте Уебхук). |
Полета за артикули
| Поле | Тип | Описание |
|---|---|---|
| length / width / height | number, required | Размери на артикула, интерпретирани в мерните единици от заявката (mm по подразбиране, инчове при „units“: „imperial“). |
| weight | number, required | Тегло на артикула (kg по подразбиране, lb при „units“: „imperial“). |
| quantity | integer, default 1 | Разгъва се в отделни единици. |
| name | string, optional | Показва се в плана и в отговора. |
| stackable | boolean, default true | Дали друг товар може да се поставя върху този артикул. |
| max_stack | number, optional | Максимално тегло, което артикулът може да издържи отгоре (в същите мерни единици като теглото). |
| fragile | boolean, default false | Чупливи артикули се поставят само в горните слоеве. |
| tiltable | boolean, default true | Дали артикулът може да се поставя на една страна. |
| destination_stop | integer, default 1 | Спирка за доставка при многоетапно LIFO натоварване. |
Кодове на превозни средства
Генерирани от актуалните спецификации на алгоритъма. Персонализирани превозни средства от вашия флот работят чрез custom_vehicle_id.
Камиони и ремаркета
| Код | Превозно средство | Вътрешни размери (Д×Ш×В) | Товароподемност |
|---|---|---|---|
| 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 |
Контейнери
| Код | Контейнер | Вътрешни размери (Д×Ш×В) | Товароподемност |
|---|---|---|---|
| 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 |
Нива на достъп и ограничения
| Сандбокс (всеки план) | Производствен режим (Enterprise) | |
|---|---|---|
| Заявки | 25 успешни / месец | 5 000 успешни опаковки / месец |
| Артикули на манифест | 20 | 5,000 |
| Едновременни заявки | 1 | 10 |
| Бюджет за оптимизация | 10 s | 30 s по подразбиране, до 300 s |
| Трайност | Нищо не се съхранява | Всяка заявка създава реален план във вашия работен профил |
Броят се само успешни опаковки — неуспешни валидации и провалени задачи не се отчитат към квотата. И двата брояча се нулират на 1-во число (UTC). Резултатите в тестовата среда са пълни и без ограничения — лимитите са само за контрол, а не за изходните данни. Нужен ви капацитет над 5 000 опаковки месечно? Свържете се с нас за обемни и OEM оферти.
Уебхук
Подайте callback_url, за да получите резултата чрез POST при завършване на заявката. Всеки уебхук съдържа X-Hansatic-Signature: HMAC-SHA256 на необработеното тяло с уебхук секрета на вашия ключ (показва се веднъж при създаване на ключа). Проверете го:
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));
}Доставката е с един опит и таймаут 5s — status_url винаги остава източник на истината.
Грешки
Всички грешки са с { "error": { "code", "message", ... } } — машиночетим код, човешки четимно съобщение и field, когато проблемът е в конкретно входно поле.
| Код | HTTP | Значение |
|---|---|---|
| invalid_key | 401 | Липсващ, неправилно форматиран или отменен API ключ. |
| invalid_json | 400 | Тялото не е валиден JSON. |
| invalid_vehicle | 400 | Непознат код на превозно средство / {customVehicleId}. |
| invalid_items | 400 | Поле за артикул липсва, не е числово или е извън допустимия обхват. |
| suspicious_dimensions | 400 | Всички размери под 100 mm — вероятно инчове, изпратени като милиметри. Подайте „units“: „imperial“. |
| invalid_units | 400 | units трябва да бъде „metric“ или „imperial“. |
| invalid_objective | 400 | objective трябва да бъде „ldm“ или „pallets“. |
| invalid_callback | 400 | callback_url трябва да е https. |
| too_many_items | 400 | Манифестът надвишава лимита за артикули за вашето ниво на достъп. |
| upgrade_required | 402 | Производственият режим изисква Enterprise план. Използвайте сандбокс или надстройте плана си. |
| sandbox_limit_reached | 402 | Месечният лимит за сандбокс е изчерпан — възстановява се на 1-во число. |
| quota_exceeded | 402 | Изчерпана е месечната квота от 5 000 опаковки — нулира се на 1-во число. За по-голям обем: свържете се с нас. |
| too_many_jobs | 429 | Достигнат е лимитът за едновременни заявки. Проверете текущите заявки и опитайте отново. |
| not_found | 404 | Няма такава заявка за този работен профил. |
Въпроси, по-високи лимити или нужда от конектор (Zapier, Excel, MCP)? hello@hansatic.com