Packing API

Изпратете товар и получете оптимизиран, физически валиден план за натоварване — разположение, товарни метри, линейни футове и платени позиции на палети. Същият алгоритъм, който задвижва приложението, непрекъснато валидиран спрямо реални планове на диспечери. Достъп до сандбокс във всеки план; производствен достъп в Enterprise.

Бърз старт

  1. Влезте в профила си → кликнете върху името си → API → генерирайте ключ.
  2. Изпратете заявка за пакетиране (тази работи в сандбокс — безплатно във всеки план):
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_countintegerКолко артикула са вместени / не са вместени.
units"metric" | "imperial"Мерните единици, в които са изразени всички числа по-долу (повтарят заявката).
metrics.ldm_mnumberТоварни метри — дължината на товарния блок (максимален край − минимално начало).
metrics.linear_ftnumberСъщата дължина в линейни футове (за американски LTL).
metrics.span_mmintegerДължината в милиметри, винаги метрична.
metrics.pallet_positions_eurinteger | nullПлатени EUR палетни позиции. null, ако планът е твърде голям за измерване.
metrics.total_weight_kgnumberОбщо тегло на вместените артикули, винаги в кг.
metrics.overlapsintegerДвойки с припокриване — винаги 0 за валиден план.
items[].placedbooleanДали артикулът е вместен в плана.
items[].x / y / znumber | nullПозиция в мерните единици от заявката: x откъм вратата, y от лявата стена, z от пода. И трите са null, ако placed е false.
items[].rotation_deg / tilt_deg0 | 90Ориентация: завъртане около вертикалната ос; tilt = поставен на една страна.
items[].length / width / height / weightnumberАртикулът, както е подаден, в мерните единици от заявката.
plan_urlstring | nullСъздаденият план в приложението. null за заявки в сандбокс.

Версиониране и стабилност

Договорът е версиониран в пътя (/api/v1/). В рамките на v1 промените са само добавящи — нови незадължителни полета в заявката, нови полета в отговора, нови кодове на превозни средства и грешки, като клиентите трябва да игнорират полета, които не разпознават. Съществуващите полета никога не променят значение или тип, и нищо не се премахва. Разрушаваща промяна означава нов път за версията, като v1 се поддържа паралелно поне 12 месеца и се изпраща известие за отпадане по имейл до всеки работен профил с активен ключ.

Полета в заявката

ПолеТипОписание
vehiclestringКод на превозно средство от таблиците по-долу. Или използвайте {customVehicleId} (превозно средство от вашия флот в работния профил).
objective"ldm" | "pallets"Минимизиране на товарните метри или на платените палетни позиции. По подразбиране „ldm“.
units"metric" | "imperial"Как се интерпретират и връщат размерите и теглата на артикулите: mm/kg (по подразбиране) или in/lb. Позициите в отговора следват същите мерни единици.
itemsarray, requiredМанифест на товара (полетата по-долу).
sandboxbooleanТестов режим: пълен резултат, без съхранение. Достъпен във всеки план.
namestringИме на плана (в производствен режим).
ldm_limit_mnumberОграничаване на товара до първите N товарни метри (камиони).
budget_msnumberБюджет за време на оптимизация (производствен режим; по подразбиране 30000, максимум 300000).
callback_urlhttps URLИзпраща се POST с резултата при завършване на заявката, подписан (вижте Уебхук).

Полета за артикули

ПолеТипОписание
length / width / heightnumber, requiredРазмери на артикула, интерпретирани в мерните единици от заявката (mm по подразбиране, инчове при „units“: „imperial“).
weightnumber, requiredТегло на артикула (kg по подразбиране, lb при „units“: „imperial“).
quantityinteger, default 1Разгъва се в отделни единици.
namestring, optionalПоказва се в плана и в отговора.
stackableboolean, default trueДали друг товар може да се поставя върху този артикул.
max_stacknumber, optionalМаксимално тегло, което артикулът може да издържи отгоре (в същите мерни единици като теглото).
fragileboolean, default falseЧупливи артикули се поставят само в горните слоеве.
tiltableboolean, default trueДали артикулът може да се поставя на една страна.
destination_stopinteger, default 1Спирка за доставка при многоетапно LIFO натоварване.

Кодове на превозни средства

Генерирани от актуалните спецификации на алгоритъма. Персонализирани превозни средства от вашия флот работят чрез custom_vehicle_id.

Камиони и ремаркета

КодПревозно средствоВътрешни размери (Д×Ш×В)Товароподемност
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

Контейнери

КодКонтейнерВътрешни размери (Д×Ш×В)Товароподемност
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

Нива на достъп и ограничения

Сандбокс (всеки план)Производствен режим (Enterprise)
Заявки25 успешни / месец5 000 успешни опаковки / месец
Артикули на манифест205,000
Едновременни заявки110
Бюджет за оптимизация10 s30 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_key401Липсващ, неправилно форматиран или отменен API ключ.
invalid_json400Тялото не е валиден JSON.
invalid_vehicle400Непознат код на превозно средство / {customVehicleId}.
invalid_items400Поле за артикул липсва, не е числово или е извън допустимия обхват.
suspicious_dimensions400Всички размери под 100 mm — вероятно инчове, изпратени като милиметри. Подайте „units“: „imperial“.
invalid_units400units трябва да бъде „metric“ или „imperial“.
invalid_objective400objective трябва да бъде „ldm“ или „pallets“.
invalid_callback400callback_url трябва да е https.
too_many_items400Манифестът надвишава лимита за артикули за вашето ниво на достъп.
upgrade_required402Производственият режим изисква Enterprise план. Използвайте сандбокс или надстройте плана си.
sandbox_limit_reached402Месечният лимит за сандбокс е изчерпан — възстановява се на 1-во число.
quota_exceeded402Изчерпана е месечната квота от 5 000 опаковки — нулира се на 1-во число. За по-голям обем: свържете се с нас.
too_many_jobs429Достигнат е лимитът за едновременни заявки. Проверете текущите заявки и опитайте отново.
not_found404Няма такава заявка за този работен профил.

Въпроси, по-високи лимити или нужда от конектор (Zapier, Excel, MCP)? hello@hansatic.com