装箱 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 | 相同长度的线性英尺(美国零担运输)。 |
| 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 为距地面高度。当 placed 为 false 时,三者均为 null。 |
| 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 | 下方表格中的车辆代码,或传入 custom_vehicle_id(您工作空间车队中的车辆)。 |
| 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 发送结果,并附带签名(详见 Webhooks)。 |
货物字段
| 字段 | 类型 | 说明 |
|---|---|---|
| length / width / height | number, required | 货物尺寸,单位与请求一致(默认毫米,使用 "units": "imperial" 时为英寸)。 |
| weight | number, required | 货物重量(默认千克,使用 "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 秒 | 默认 30 秒,最多 300 秒 |
| 持久化 | 不保存任何数据 | 每次装箱任务均在您的工作空间中生成实际计划 |
仅成功打包计入配额——验证失败或作业失败不计费。两项计数器于每月 1 日(UTC)重置。沙盒环境结果完整且不受限制——限制仅作为门槛,而非输出限制。 每月需求超过 5,000 次打包?请联系我们了解批量及 OEM 定价。
Webhooks
传入 callback_url 以在任务完成时通过 POST 接收结果。每次回调均包含 X-Hansatic-Signature:使用您密钥的 webhook 密钥(仅在创建密钥时显示一次)对原始请求体进行 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));
}回调仅尝试一次,超时时间为 5 秒 — status_url 始终为真实数据源。
错误
所有错误均为 { "error": { "code", "message", ... } } 格式 — 包含机器可读的错误代码、人类可读的错误信息,以及在特定输入有误时的 field 字段。
| 代码 | HTTP | 含义 |
|---|---|---|
| invalid_key | 401 | 缺少、格式错误或已撤销的 API 密钥。 |
| invalid_json | 400 | 请求体不是有效的 JSON。 |
| invalid_vehicle | 400 | 未知的车辆代码或 custom_vehicle_id。 |
| invalid_items | 400 | 货物字段缺失、非数字或超出范围。 |
| suspicious_dimensions | 400 | 所有尺寸均小于 100 毫米 — 可能将英寸误传为毫米。请传入 "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