Packing API
Kirimkan kargo, dapatkan rencana muatan yang optimal dan valid secara fisik — mencakup penempatan, loading meter, linear feet, dan posisi palet yang ditagih. Mesin yang sama dengan aplikasi, terus divalidasi berdasarkan tata letak dispatcher nyata. Akses sandbox tersedia di setiap paket; akses produksi di Enterprise.
Mulai cepat
- Masuk → klik nama Anda → API → buat kunci.
- Kirimkan pekerjaan packing (contoh ini berjalan di sandbox — gratis di setiap paket):
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-..."
}Pantau status_url (dengan header autentikasi yang sama) hingga status menjadi "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/..."
}
}Endpoint
POST /api/v1/pack
Memvalidasi dan mengantrekan pekerjaan packing. Mengembalikan 202 dengan job_id. Mendukung header Idempotency-Key — pengulangan dengan kunci yang sama akan mengembalikan pekerjaan asli alih-alih memproses ulang.
GET /api/v1/jobs/{id}
Status pekerjaan dan, jika selesai, hasil lengkap. Hasil disimpan selama 30 hari; paket produksi tersimpan permanen di workspace Anda.
GET /api/v1/openapi.json
Kontrak OpenAPI 3.1 yang dapat dibaca mesin — impor ke Postman, generator kode, atau arahkan alat coding AI Anda. Kode kendaraan diambil dari mesin aktif, sehingga selalu terbaru. Buka spesifikasi ↗
Field respons
Objek result pada pekerjaan yang selesai:
| Field | Tipe | Deskripsi |
|---|---|---|
| placed_count / unplaced_count | integer | Jumlah item yang muat / tidak muat. |
| units | "metric" | "imperial" | Satuan yang digunakan untuk semua angka di bawah (mengikuti permintaan). |
| metrics.ldm_m | number | Loading meter — panjang blok kargo (akhir maks − awal min). |
| metrics.linear_ft | number | Panjang yang sama dalam linear feet (US LTL). |
| metrics.span_mm | integer | Panjang dalam mm, selalu metrik. |
| metrics.pallet_positions_eur | integer | null | Posisi palet EUR yang ditagih. null jika tata letak terlalu besar untuk diukur. |
| metrics.total_weight_kg | number | Berat muatan, selalu dalam kg. |
| metrics.overlaps | integer | Pasangan yang saling tumpang tindih — selalu 0 untuk tata letak yang valid. |
| items[].placed | boolean | Apakah item masuk ke dalam tata letak. |
| items[].x / y / z | number | null | Posisi dalam satuan permintaan: x dari ujung pintu, y dari dinding kiri, z dari lantai. Ketiganya null jika placed bernilai false. |
| items[].rotation_deg / tilt_deg | 0 | 90 | Orientasi: rotasi terhadap sumbu vertikal; tilt = diletakkan miring. |
| items[].length / width / height / weight | number | Item seperti yang dikirimkan, dalam satuan permintaan. |
| plan_url | string | null | Rencana yang dibuat di aplikasi. null untuk pekerjaan sandbox. |
Versi & stabilitas
Kontrak diberi versi dalam path (/api/v1/). Dalam v1, perubahan hanya bersifat penambahan — field permintaan opsional baru, field respons baru, kode kendaraan baru, dan kode kesalahan baru dapat muncul, dan klien harus mengabaikan field yang tidak dikenali. Field yang ada tidak pernah mengubah arti atau tipe, dan tidak ada yang dihapus. Perubahan yang memutus kompatibilitas berarti path versi baru, dengan v1 dipertahankan secara paralel setidaknya selama 12 bulan dan pemberitahuan penghentian melalui email ke setiap workspace dengan kunci aktif.
Field permintaan
| Field | Tipe | Deskripsi |
|---|---|---|
| vehicle | string | Kode kendaraan dari tabel di bawah. Atau gunakan custom_vehicle_id (kendaraan dari armada workspace Anda). |
| objective | "ldm" | "pallets" | Meminimalkan loading meter, atau meminimalkan posisi palet yang ditagih. Default "ldm". |
| units | "metric" | "imperial" | Cara membaca DAN mengembalikan dimensi dan berat item: mm/kg (default) atau in/lb. Posisi dalam respons mengikuti satuan yang sama. |
| items | array, required | Daftar kargo (field di bawah). |
| sandbox | boolean | Mode uji: hasil lengkap, tidak disimpan. Tersedia di setiap paket. |
| name | string | Nama rencana (mode produksi). |
| ldm_limit_m | number | Batasi muatan hingga N loading meter pertama (truk). |
| budget_ms | number | Batas waktu optimasi (produksi; default 30000, maks 300000). |
| callback_url | https URL | Dikirimkan hasilnya via POST saat pekerjaan selesai, dengan tanda tangan (lihat Webhook). |
Field item
| Field | Tipe | Deskripsi |
|---|---|---|
| length / width / height | number, required | Dimensi item, dibaca dalam satuan permintaan (mm secara default, inci dengan "units": "imperial"). |
| weight | number, required | Berat item (kg secara default, lb dengan "units": "imperial"). |
| quantity | integer, default 1 | Diuraikan menjadi unit individual. |
| name | string, optional | Ditampilkan dalam rencana dan respons. |
| stackable | boolean, default true | Item lain dapat diletakkan di atas item ini. |
| max_stack | number, optional | Berat maksimum yang dapat ditopang item ini (satuan sama dengan berat). |
| fragile | boolean, default false | Item rapuh hanya ditempatkan di lapisan atas. |
| tiltable | boolean, default true | Apakah item boleh diletakkan miring. |
| destination_stop | integer, default 1 | Titik pengiriman untuk pemuatan LIFO multi-stop. |
Kode kendaraan
Dihasilkan dari spesifikasi mesin aktif. Kendaraan khusus dari armada workspace Anda dapat digunakan melalui custom_vehicle_id.
Truk & trailer
| Kode | Kendaraan | Interior (P×L×T) | Muatan |
|---|---|---|---|
| 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 |
Kontainer
| Kode | Kontainer | Interior (P×L×T) | Muatan |
|---|---|---|---|
| 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 |
Tingkat akses & batasan
| Sandbox (setiap paket) | Produksi (Enterprise) | |
|---|---|---|
| Panggilan | 25 berhasil / bulan | 5.000 pengemasan berhasil / bulan |
| Item per manifes | 20 | 5,000 |
| Pekerjaan bersamaan | 1 | 10 |
| Batas waktu optimasi | 10 s | 30 s default, hingga 300 s |
| Penyimpanan | Tidak ada yang disimpan | Setiap packing membuat rencana nyata di workspace Anda |
Hanya pengemasan yang berhasil dihitung — validasi gagal dan pekerjaan yang gagal tidak mengurangi kuota. Kedua penghitung akan direset pada tanggal 1 (UTC). Hasil sandbox lengkap dan tidak dibatasi — batasannya adalah gerbang, bukan keluaran. Butuh lebih dari 5.000 pengemasan per bulan? Hubungi kami untuk diskusi mengenai volume dan harga OEM.
Webhook
Sertakan callback_url untuk menerima hasil via POST saat pekerjaan selesai. Setiap callback membawa X-Hansatic-Signature: HMAC-SHA256 dari body mentah dengan rahasia webhook kunci Anda (ditampilkan sekali saat pembuatan kunci). Verifikasi:
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));
}Pengiriman dilakukan satu kali dengan batas waktu 5s — status_url tetap menjadi sumber kebenaran.
Kesalahan
Semua kesalahan berbentuk { "error": { "code", "message", ... } } — kode yang dapat dibaca mesin, pesan yang dapat dibaca manusia, dan field jika input tertentu bermasalah.
| Kode | HTTP | Arti |
|---|---|---|
| invalid_key | 401 | Kunci API hilang, salah format, atau dicabut. |
| invalid_json | 400 | Body bukan JSON yang valid. |
| invalid_vehicle | 400 | Kode kendaraan / custom_vehicle_id tidak dikenal. |
| invalid_items | 400 | Field item hilang, bukan angka, atau di luar rentang. |
| suspicious_dimensions | 400 | Semua dimensi di bawah 100mm — kemungkinan inci dikirim sebagai mm. Gunakan "units": "imperial". |
| invalid_units | 400 | units harus "metric" atau "imperial". |
| invalid_objective | 400 | objective harus "ldm" atau "pallets". |
| invalid_callback | 400 | callback_url harus https. |
| too_many_items | 400 | Manifes melebihi batas item untuk tingkat akses Anda. |
| upgrade_required | 402 | Mode produksi memerlukan paket Enterprise. Gunakan sandbox, atau tingkatkan paket. |
| sandbox_limit_reached | 402 | Kuota sandbox bulanan habis — akan direset pada tanggal 1. |
| quota_exceeded | 402 | Kuota produksi bulanan sebesar 5.000 pengemasan telah terpakai — akan direset pada tanggal 1. Untuk volume lebih besar: hubungi kami. |
| too_many_jobs | 429 | Batas pekerjaan bersamaan tercapai. Pantau pekerjaan yang berjalan dan coba lagi. |
| not_found | 404 | Tidak ada pekerjaan seperti itu untuk workspace ini. |
Pertanyaan, batasan lebih tinggi, atau konektor yang Anda butuhkan (Zapier, Excel, MCP)? hello@hansatic.com