Packing API
ส่งข้อมูลสินค้าและรับแผนการบรรทุกที่เหมาะสมและผ่านการตรวจสอบทางกายภาพ — รวมถึงตำแหน่งการจัดวาง ค่า Loading Meter ความยาวเป็นฟุต และตำแหน่งพาเลทที่เรียกเก็บเงิน แอปพลิเคชันใช้เครื่องมือเดียวกันกับที่ได้รับการตรวจสอบอย่างต่อเนื่องกับแผนการจัดวางจริงจากผู้จัดการขนส่ง เข้าถึง Sandbox ได้ในทุกแผน และเข้าถึง Production สำหรับแผน Enterprise
เริ่มต้นใช้งานอย่างรวดเร็ว
- เข้าสู่ระบบ → คลิกที่ชื่อของคุณ → API → สร้างคีย์
- ส่งงานบรรทุก (ตัวอย่างนี้ทำงานใน Sandbox — ฟรีในทุกแผน):
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 (ใช้ Header การยืนยันตัวตนเดียวกัน) จนกว่า 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/..."
}
}Endpoints
POST /api/v1/pack
ตรวจสอบและจัดคิวงานบรรทุก ส่งคืน 202 พร้อม job_id รองรับ Header Idempotency-Key — การส่งซ้ำด้วยคีย์เดิมจะคืนค่างานเดิมแทนที่จะบรรทุกซ้ำ
GET /api/v1/jobs/{id}
สถานะงานและผลลัพธ์เมื่อเสร็จสมบูรณ์ ผลลัพธ์จะถูกเก็บไว้เป็นเวลา 30 วัน สำหรับแผน Production จะถูกเก็บไว้ในพื้นที่ทำงานของคุณอย่างถาวร
GET /api/v1/openapi.json
สัญญา OpenAPI 3.1 ที่อ่านได้ด้วยเครื่อง — นำเข้าไปใช้ใน Postman, เครื่องมือสร้างโค้ด หรือเชื่อมต่อกับเครื่องมือเขียนโค้ด AI รหัสยานพาหนะจะถูกดึงมาจากเครื่องมือจริง ทำให้ข้อมูลเป็นปัจจุบันเสมอ เปิดสเปค ↗
ฟิลด์การตอบกลับ
ออบเจกต์ result เมื่องานเสร็จสมบูรณ์:
| ฟิลด์ | ประเภท | คำอธิบาย |
|---|---|---|
| placed_count / unplaced_count | integer | จำนวนสินค้าที่บรรทุกได้ / ไม่ได้บรรทุก |
| units | "metric" | "imperial" | หน่วยที่ใช้ในการแสดงค่าต่าง ๆ (สอดคล้องกับคำขอ) |
| metrics.ldm_m | number | Loading Meter — ความยาวของกลุ่มสินค้า (ตำแหน่งสิ้นสุดสูงสุด − ตำแหน่งเริ่มต้นต่ำสุด) |
| 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 จากพื้น ทั้งสามค่าจะเป็น null หาก placed เป็น false |
| items[].rotation_deg / tilt_deg | 0 | 90 | การวางแนว: การหมุนรอบแกนแนวตั้ง; tilt = วางนอนตะแคง |
| items[].length / width / height / weight | number | ขนาดสินค้าตามที่ส่งมา สอดคล้องกับหน่วยที่ระบุในคำขอ |
| plan_url | string | null | แผนการบรรทุกที่สร้างในแอป หากเป็นงาน Sandbox จะเป็น null |
การกำหนดเวอร์ชันและความเสถียร
สัญญาจะถูกกำหนดเวอร์ชันในพาธ (/api/v1/) ภายใน v1 การเปลี่ยนแปลงจะเป็นการเพิ่มเติมเท่านั้น — ฟิลด์คำขอใหม่ที่ไม่บังคับ ฟิลด์การตอบกลับใหม่ รหัสยานพาหนะใหม่ และรหัสข้อผิดพลาดใหม่ อาจปรากฏขึ้น และไคลเอนต์ควรละเว้นฟิลด์ที่ไม่รู้จัก ความหมายและประเภทของฟิลด์ที่มีอยู่จะไม่มีการเปลี่ยนแปลง และจะไม่มีการลบฟิลด์ใด ๆ การเปลี่ยนแปลงที่ส่งผลกระทบจะหมายถึงพาธเวอร์ชันใหม่ โดย v1 จะยังคงได้รับการดูแลควบคู่กันไปอย่างน้อย 12 เดือน และจะมีการแจ้งเตือนการเลิกใช้งานทางอีเมลไปยังพื้นที่ทำงานทุกแห่งที่มีคีย์ใช้งานอยู่
ฟิลด์คำขอ
| ฟิลด์ | ประเภท | คำอธิบาย |
|---|---|---|
| vehicle | string | รหัสยานพาหนะจากตารางด้านล่าง หรือส่ง {customVehicleId} (ยานพาหนะจากฝูงรถในพื้นที่ทำงานของคุณ) |
| objective | "ldm" | "pallets" | ลด Loading Meter หรือลดจำนวนตำแหน่งพาเลทที่เรียกเก็บเงิน ค่าเริ่มต้นคือ "ldm" |
| units | "metric" | "imperial" | หน่วยที่ใช้ในการอ่านและส่งคืนขนาดและน้ำหนักสินค้า: mm/kg (ค่าเริ่มต้น) หรือ in/lb ตำแหน่งในการตอบกลับจะใช้หน่วยเดียวกัน |
| items | array, required | รายการสินค้า (ฟิลด์ด้านล่าง) |
| sandbox | boolean | โหมดทดสอบ: ได้ผลลัพธ์เต็มรูปแบบโดยไม่มีการบันทึกข้อมูล พร้อมใช้งานในทุกแผน |
| name | string | ชื่อแผนการบรรทุก (โหมด Production) |
| ldm_limit_m | number | จำกัดการบรรทุกให้อยู่ใน N Loading Meter แรก (สำหรับรถบรรทุก) |
| budget_ms | number | งบประมาณเวลาการปรับปรุง (โหมด Production; ค่าเริ่มต้น 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 |
ระดับการเข้าถึงและขีดจำกัด
| Sandbox (ทุกแผน) | Production (Enterprise) | |
|---|---|---|
| การเรียกใช้งาน | 25 ครั้งที่สำเร็จ / เดือน | 5,000 แพ็กที่สำเร็จ / เดือน |
| สินค้าต่อรายการ | 20 | 5,000 |
| งานพร้อมกัน | 1 | 10 |
| งบประมาณการปรับปรุง | 10 วินาที | ค่าเริ่มต้น 30 วินาที สูงสุด 300 วินาที |
| การเก็บข้อมูล | ไม่มีการเก็บข้อมูล | ทุกการบรรทุกจะสร้างแผนจริงในพื้นที่ทำงานของคุณ |
นับเฉพาะแพ็กที่สำเร็จเท่านั้น — การตรวจสอบความถูกต้องที่ล้มเหลวและงานที่ล้มเหลวจะไม่ถูกนับเป็นโควต้า ทั้งสองตัวนับจะรีเซ็ตในวันที่ 1 (UTC) ผลลัพธ์ใน Sandbox มีความสมบูรณ์และไม่ถูกจำกัด — ขีดจำกัดเป็นเพียงเกณฑ์ ไม่ใช่ผลลัพธ์ ต้องการมากกว่า 5,000 แพ็กต่อเดือนหรือไม่? ติดต่อเราเพื่อหารือเกี่ยวกับราคาสำหรับปริมาณมากและ OEM
Webhooks
ส่ง callback_url เพื่อรับผลลัพธ์ผ่าน POST เมื่องานเสร็จสมบูรณ์ ทุกการเรียกกลับจะมี X-Hansatic-Signature: HMAC-SHA256 ของเนื้อหาดิบด้วยคีย์ลับของ Webhook ของคุณ (แสดงครั้งเดียวเมื่อสร้างคีย์) ตรวจสอบลายเซ็นดังนี้:
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 | ขนาดทั้งหมดต่ำกว่า 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 | โหมด Production ต้องใช้แผน Enterprise ให้ใช้ Sandbox หรืออัปเกรดแผน |
| sandbox_limit_reached | 402 | ใช้โควต้า Sandbox รายเดือนครบแล้ว — รีเซ็ตในวันที่ 1 |
| quota_exceeded | 402 | ใช้โควต้าแพ็กสำหรับเดือนนี้ครบ 5,000 แล้ว — รีเซ็ตในวันที่ 1 ปริมาณมากขึ้น: ติดต่อเรา |
| too_many_jobs | 429 | ถึงขีดจำกัดงานพร้อมกันแล้ว ตรวจสอบงานที่กำลังดำเนินการและลองใหม่ |
| not_found | 404 | ไม่พบงานดังกล่าวในพื้นที่ทำงานนี้ |
มีคำถาม ต้องการขีดจำกัดที่สูงขึ้น หรือต้องการตัวเชื่อมต่อที่คุณต้องการ (Zapier, Excel, MCP)? hello@hansatic.com