Packing 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, מחוללי קוד או הפנו אליו כלי קידוד מבוססי בינה מלאכותית. קודי הרכב מוזרקים ממנוע החי, כך שהוא תמיד מעודכן. פתחו את המפרט ↗
שדות תגובה
האובייקט 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 מהרצפה. כל השלושה יהיו null כאשר placed הוא false. |
| 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 | קוד רכב מהטבלאות להלן. או העבירו {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 |
רמות גישה ומגבלות
| סנדבוקס (בכל תוכנית) | ייצור (Enterprise) | |
|---|---|---|
| קריאות | 25 מוצלחות / חודש | 5,000 אריזות מוצלחות / חודש |
| פריטים במניפסט | 20 | 5,000 |
| משימות בו-זמניות | 1 | 10 |
| תקציב אופטימיזציה | 10 שניות | 30 שניות כברירת מחדל, עד 300 שניות |
| שמירה | לא נשמר דבר | כל אריזה יוצרת תוכנית אמיתית במרחב העבודה שלכם |
רק אריזות מוצלחות נספרות — ניסיונות כושלים בוולידציה או עבודות שנכשלו אינם מחויבים כנגד המכסה. שני המונים מתאפסים ב-1 לחודש (UTC). תוצאות הסנדבוקס מלאות וללא הגבלות — המגבלה היא השער, לא התוצאה. צריכים יותר מ-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 | מצב ייצור דורש את תוכנית 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