パッキング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 | 同じ長さをリニアフィートで表したもの(米国LTL)。 |
| metrics.span_mm | integer | 長さをミリメートルで表したもの(常にメートル法)。 |
| metrics.pallet_positions_eur | integer | null | 請求対象のEURパレット位置数。レイアウトが大きすぎて測定できない場合はnull。 |
| metrics.total_weight_kg | number | 積載重量(常にkg)。 |
| 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 | アプリで作成されたプランのURL。サンドボックスジョブの場合はnull。 |
バージョニングと安定性
API仕様はパス(/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で送信(署名付き、Webhookを参照)。 |
アイテムフィールド
| フィールド | 型 | 説明 |
|---|---|---|
| length / width / height | number, required | アイテムの寸法。リクエストの単位(デフォルトはmm、「units」:「imperial」の場合はインチ)で読み取られます。 |
| weight | number, required | アイテムの重量(デフォルトはkg、「units」:「imperial」の場合はlb)。 |
| 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 で利用可能。
トラック・トレーラー
| コード | 車両 | 内寸 (L×W×H) | 積載量 |
|---|---|---|---|
| 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 |
コンテナ
| コード | コンテナ | 内寸 (L×W×H) | 積載量 |
|---|---|---|---|
| 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価格についてはお問い合わせください。
Webhook
ジョブ完了時に結果をPOSTで受け取るには、callback_url を指定します。すべてのコールバックには 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秒のタイムアウトで1回のみ試行されます — 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 | すべての寸法が100mm未満 — おそらくインチをmmとして送信しています。「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