裝載規劃 API
提交貨物資訊,即可取得經最佳化且物理驗證的裝載計畫 — 包含貨物擺放位置、裝載公尺、線性英尺及計費棧板位置。此為應用程式背後的相同引擎,持續透過實際調度配置驗證。每個方案均提供沙盒存取;正式環境僅限企業方案。
快速入門
- 登入 → 點擊您的名稱 → 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 為距離地板高度。若 placed 為 false,則三者均為 null。 |
| items[].rotation_deg / tilt_deg | 0 | 90 | 方向:旋轉為垂直軸旋轉角度;tilt 表示平放。 |
| items[].length / width / height / weight | number | 提交的貨物尺寸,以請求單位回應。 |
| plan_url | string | null | 應用程式中建立的配置連結。沙盒任務為 null。 |
版本控制與穩定性
API 規範透過路徑 (/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 傳送結果,並附加簽名(詳見 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 |
存取層級與限制
| 沙盒環境(每個方案適用) | 正式環境(企業方案) | |
|---|---|---|
| 呼叫次數 | 每月 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 | 未知的車輛代碼或 {customVehicleId}。 |
| invalid_items | 400 | 貨物欄位缺失、非數值或超出範圍。 |
| suspicious_dimensions | 400 | 所有尺寸均小於 100mm — 可能為英寸誤傳為毫米。請傳入 "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 | 正式環境模式需企業方案。請使用沙盒環境或升級方案。 |
| sandbox_limit_reached | 402 | 本月沙盒額度已用完 — 將於每月 1 日重置。 |
| quota_exceeded | 402 | 已用罄每月 5,000 次打包配額 — 將於 1 日重置。需更高配額:請與我們聯繫。 |
| too_many_jobs | 429 | 同時執行任務數已達上限。請輪詢執行中的任務後重試。 |
| not_found | 404 | 此工作區無此任務。 |
有任何問題、需要提高限制,或需要特定連接器(如 Zapier、Excel、MCP)? hello@hansatic.com