Packing API
Gửi danh sách hàng hóa, nhận lại kế hoạch xếp hàng đã tối ưu và hợp lệ về mặt vật lý — bao gồm vị trí đặt hàng, số mét xếp hàng, feet tuyến tính và số pallet tính phí. Đây là cùng một công cụ được sử dụng trong ứng dụng, liên tục được xác thực dựa trên các kế hoạch thực tế của điều phối viên. Truy cập môi trường thử nghiệm trên mọi gói dịch vụ; truy cập sản phẩm trên gói Enterprise.
Bắt đầu nhanh
- Đăng nhập → nhấp vào tên của bạn → API → tạo khóa.
- Gửi một yêu cầu xếp hàng (yêu cầu này chạy trong môi trường thử nghiệm — miễn phí trên mọi gói dịch vụ):
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-..."
}Kiểm tra liên tục status_url (với cùng tiêu đề xác thực) cho đến khi status là "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/..."
}
}Điểm cuối API
POST /api/v1/pack
Xác thực và đưa yêu cầu xếp hàng vào hàng đợi. Trả về 202 cùng với job_id. Hỗ trợ tiêu đề Idempotency-Key — các yêu cầu lặp lại với cùng khóa sẽ trả về công việc gốc thay vì xếp hàng lại.
GET /api/v1/jobs/{id}
Trạng thái công việc và kết quả đầy đủ khi hoàn thành. Kết quả được lưu giữ trong 30 ngày; các gói sản phẩm sẽ tồn tại vĩnh viễn trong không gian làm việc của bạn.
GET /api/v1/openapi.json
Hợp đồng OpenAPI 3.1 có thể đọc được bằng máy — nhập vào Postman, công cụ tạo mã hoặc cung cấp cho công cụ lập trình AI của bạn. Mã phương tiện được cập nhật từ công cụ hoạt động, vì vậy luôn được cập nhật mới nhất. Xem thông số kỹ thuật ↗
Các trường trong phản hồi
Đối tượng result của một công việc đã hoàn thành:
| Trường | Kiểu | Mô tả |
|---|---|---|
| placed_count / unplaced_count | integer | Số lượng mặt hàng vừa khít / không vừa khít. |
| units | "metric" | "imperial" | Đơn vị đo lường cho tất cả các số liệu dưới đây (phản ánh yêu cầu). |
| metrics.ldm_m | number | Số mét xếp hàng — độ dài khối hàng (điểm cuối tối đa − điểm đầu tối thiểu). |
| metrics.linear_ft | number | Độ dài tương đương tính bằng feet tuyến tính (vận tải đường bộ Mỹ). |
| metrics.span_mm | integer | Độ dài tính bằng mm, luôn theo hệ mét. |
| metrics.pallet_positions_eur | integer | null | Số vị trí pallet EUR tính phí. null khi bố trí quá lớn để đo lường. |
| metrics.total_weight_kg | number | Trọng lượng đã xếp, luôn tính bằng kg. |
| metrics.overlaps | integer | Các cặp chồng lấn — luôn bằng 0 đối với bố trí hợp lệ. |
| items[].placed | boolean | Mặt hàng có được xếp vào bố trí hay không. |
| items[].x / y / z | number | null | Vị trí theo đơn vị yêu cầu: x tính từ đầu cửa, y tính từ tường trái, z tính từ sàn. Cả ba đều là null khi placed là false. |
| items[].rotation_deg / tilt_deg | 0 | 90 | Hướng: xoay quanh trục dọc; tilt = đặt nằm ngang. |
| items[].length / width / height / weight | number | Kích thước mặt hàng như đã gửi, phản ánh theo đơn vị yêu cầu. |
| plan_url | string | null | Kế hoạch đã tạo trong ứng dụng. null đối với công việc trong môi trường thử nghiệm. |
Phiên bản & tính ổn định
Hợp đồng được đánh phiên bản trong đường dẫn (/api/v1/). Trong v1, các thay đổi chỉ mang tính bổ sung — các trường yêu cầu tùy chọn mới, trường phản hồi mới, mã phương tiện mới và mã lỗi mới có thể xuất hiện, và khách hàng nên bỏ qua các trường không nhận biết. Các trường hiện có không bao giờ thay đổi ý nghĩa hoặc kiểu dữ liệu, và không có gì bị loại bỏ. Thay đổi phá vỡ sẽ dẫn đến một đường dẫn phiên bản mới, với v1 được duy trì song song trong ít nhất 12 tháng và thông báo ngừng hỗ trợ qua email đến mọi không gian làm việc có khóa hoạt động.
Các trường trong yêu cầu
| Trường | Kiểu | Mô tả |
|---|---|---|
| vehicle | string | Mã phương tiện từ các bảng dưới đây. Hoặc truyền {customVehicleId} (một phương tiện từ đội xe của không gian làm việc của bạn). |
| objective | "ldm" | "pallets" | Tối thiểu hóa số mét xếp hàng hoặc số vị trí pallet tính phí. Mặc định là "ldm". |
| units | "metric" | "imperial" | Cách đọc và trả về kích thước và trọng lượng mặt hàng: mm/kg (mặc định) hoặc in/lb. Vị trí trong phản hồi sẽ theo cùng đơn vị. |
| items | array, required | Danh sách hàng hóa (các trường bên dưới). |
| sandbox | boolean | Chế độ thử nghiệm: kết quả đầy đủ, không lưu trữ. Có sẵn trên mọi gói dịch vụ. |
| name | string | Tên kế hoạch (chế độ sản phẩm). |
| ldm_limit_m | number | Giới hạn xếp hàng trong N mét xếp hàng đầu tiên (xe tải). |
| budget_ms | number | Ngân sách thời gian tối ưu hóa (chế độ sản phẩm; mặc định 30000, tối đa 300000). |
| callback_url | https URL | Gửi kết quả qua POST khi công việc hoàn thành, có chữ ký (xem Webhook). |
Các trường của mặt hàng
| Trường | Kiểu | Mô tả |
|---|---|---|
| length / width / height | number, required | Kích thước mặt hàng, đọc theo đơn vị yêu cầu (mm theo mặc định, inch nếu "units": "imperial"). |
| weight | number, required | Trọng lượng mặt hàng (kg theo mặc định, lb nếu "units": "imperial"). |
| quantity | integer, default 1 | Mở rộng thành các đơn vị riêng lẻ. |
| name | string, optional | Hiển thị trong kế hoạch và phản hồi. |
| stackable | boolean, default true | Cho phép hàng hóa khác đặt lên trên mặt hàng này. |
| max_stack | number, optional | Trọng lượng tối đa mặt hàng này có thể chịu được (theo cùng đơn vị với weight). |
| fragile | boolean, default false | Mặt hàng dễ vỡ chỉ được xếp ở các lớp trên cùng. |
| tiltable | boolean, default true | Cho phép mặt hàng được đặt nằm ngang. |
| destination_stop | integer, default 1 | Điểm dừng giao hàng cho xếp hàng LIFO nhiều điểm dừng. |
Mã phương tiện
Được tạo từ thông số kỹ thuật của công cụ hoạt động. Phương tiện tùy chỉnh từ đội xe của không gian làm việc của bạn hoạt động thông qua custom_vehicle_id.
Xe tải & rơ moóc
| Mã | Phương tiện | Kích thước trong (D×R×C) | Tải trọng |
|---|---|---|---|
| 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 |
Container
| Mã | Container | Kích thước trong (D×R×C) | Tải trọng |
|---|---|---|---|
| 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 |
Cấp độ truy cập & giới hạn
| Môi trường thử nghiệm (mọi gói dịch vụ) | Sản phẩm (Enterprise) | |
|---|---|---|
| Số yêu cầu | 25 yêu cầu thành công / tháng | 5.000 gói thành công / tháng |
| Số mặt hàng mỗi danh sách | 20 | 5,000 |
| Công việc đồng thời | 1 | 10 |
| Ngân sách tối ưu hóa | 10 giây | 30 giây mặc định, tối đa 300 giây |
| Lưu trữ | Không lưu trữ gì | Mỗi yêu cầu xếp hàng tạo một kế hoạch thực trong không gian làm việc của bạn |
Chỉ các gói thành công mới được tính — các gói thất bại do kiểm tra hợp lệ hoặc công việc không thành công sẽ không trừ vào hạn mức. Cả hai bộ đếm sẽ được đặt lại vào ngày 1 (UTC). Kết quả trong môi trường Sandbox là đầy đủ và không bị giới hạn — hạn mức chỉ là cổng kiểm soát, không phải đầu ra. Cần hơn 5.000 gói mỗi tháng? Hãy liên hệ với chúng tôi để thảo luận về giá theo khối lượng và OEM.
Webhook
Truyền callback_url để nhận kết quả qua POST khi công việc hoàn thành. Mỗi callback đều kèm theo X-Hansatic-Signature: HMAC-SHA256 của nội dung thô với khóa bí mật webhook của bạn (hiển thị một lần khi tạo khóa). Hãy xác minh nó:
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));
}Gửi một lần với thời gian chờ 5 giây — status_url luôn là nguồn thông tin chính xác nhất.
Lỗi
Tất cả lỗi đều có định dạng { "error": { "code", "message", ... } } — mã có thể đọc được bằng máy, thông báo dễ hiểu và field khi một trường đầu vào cụ thể có lỗi.
| Mã | HTTP | Ý nghĩa |
|---|---|---|
| invalid_key | 401 | Khóa API bị thiếu, sai định dạng hoặc đã bị thu hồi. |
| invalid_json | 400 | Nội dung không phải là JSON hợp lệ. |
| invalid_vehicle | 400 | Mã phương tiện / {customVehicleId} không xác định. |
| invalid_items | 400 | Một trường của mặt hàng bị thiếu, không phải số hoặc vượt quá phạm vi cho phép. |
| suspicious_dimensions | 400 | Tất cả kích thước dưới 100mm — có thể inch được gửi dưới dạng mm. Hãy truyền "units": "imperial". |
| invalid_units | 400 | units phải là "metric" hoặc "imperial". |
| invalid_objective | 400 | objective phải là "ldm" hoặc "pallets". |
| invalid_callback | 400 | callback_url phải là https. |
| too_many_items | 400 | Danh sách hàng hóa vượt quá giới hạn mặt hàng cho cấp độ truy cập của bạn. |
| upgrade_required | 402 | Chế độ sản phẩm yêu cầu gói Enterprise. Hãy sử dụng môi trường thử nghiệm hoặc nâng cấp. |
| sandbox_limit_reached | 402 | Đã sử dụng hết hạn mức môi trường thử nghiệm hàng tháng — đặt lại vào ngày 1. |
| quota_exceeded | 402 | Hạn mức sản xuất hàng tháng là 5.000 gói đã được sử dụng — sẽ đặt lại vào ngày 1. Nhu cầu lớn hơn: vui lòng liên hệ với chúng tôi. |
| too_many_jobs | 429 | Đã đạt giới hạn công việc đồng thời. Hãy kiểm tra các công việc đang chạy và thử lại. |
| not_found | 404 | Không tìm thấy công việc nào cho không gian làm việc này. |
Câu hỏi, yêu cầu giới hạn cao hơn hoặc cần kết nối (Zapier, Excel, MCP)? hello@hansatic.com