מבוא
API בגרסה קודמת
זהו ה-API בגרסה קודמת, v1. הוא מתוחזק עבור אינטגרציות התוספים הקיימות של WooCommerce, Shopify ו-Wix שכבר תלויות בו, ומבני הבקשה והתגובה שלו לא ישתנו. אינטגרציות חדשות צריכות להשתמש ב-API v2, שבו פרטי גישה מבוססי-כותרות, מעטפת מתוּעדת גרסה עם קודי שגיאה קריאים-מכונה, מפתחות אידמפוטנטיות, עימוד ו-webhooks. שום דבר בעמודי v1 האלה אינו מורחב.
ה-ShipOS API v1 הוא משטח יצירת המשלוחים המקורי. זהו API שטוח בסגנון RPC, עם פעולה לכל נתיב: כל קריאה שולחת גוף JSON שנושא גם את הפרמטרים שלה וגם את פרטי הגישה שלה, וכל תגובה חוזרת באותה מעטפת בעלת ארבעה מפתחות, ללא תלות בפעולה.
כתובת בסיס (Base URL)
https://app.shipos.co.il/apiכל הנתיבים במדריך זה יחסיים לכתובת הבסיס הזו — נתיבי v1 רשומים תחת ה-prefix הפשוט api (POST /api/shipping/open_new_order, וכן הלאה). ה-API של v2 נמצא תחת api/v2 ואינו חולק שום קוד עם v1.
מוסכמות
פורמט — JSON בלבד. שלחו
Accept: application/jsonבכל בקשה, ו-Content-Type: application/jsonכששולחים גוף. בליAccept: application/json, כשל ולידציה מוצג כהפניית HTTP (redirect) במקום כ-JSON.מתודה (Verb) — נקודות הקצה של
shippingהןPOSTגם כשהן רק קוראות (get_order_details,get_shipping_status,pickup_locations). ארבע מהן הןGETומקבלות את הפרמטרים שלהן כערכי query string. אין פרמטרים בנתיב ואין כתובות משאב.פרטי הגישה נשלחים בגוף הבקשה —
license_keyו-domainהם שדות בקשה רגילים, לא כותרות. ראו אימות.מעטפת אחת לכל דבר — הצלחה וכשל חולקים את אותם ארבעה מפתחות:
json{ "data": { "...": "..." }, "message": "", "success": true, "warning": "" }Key סוג תיאור dataobject/array המידע (payload). מערך JSON ריק ( []), ולא{}, כאשר לנקודת הקצה אין מה להחזיר — לדוגמה בכל תגובת שגיאה.messagestring טקסט קריא-אנוש, לעיתים קרובות הטקסט של חברת השילוח עצמה. ריק בהצלחות רבות. חלק מההודעות מתורגמות, לכן אל תסתעפו לפי המחרוזת. successbool האם הפעולה הצליחה. זה — ולא הסטטוס של HTTP — האות המחייב. warningstring הערה שאינה קריטית. תמיד קיימת; ריקה ( "") בנקודות הקצה של השילוח ב-v1.אין שדה
codeלהסתעף לפיו. v1 קדם לקודי השגיאה הקריאים-מכונה שהוכנסו ב-v2; קורא מבדיל בין כשלים לפי סטטוס HTTP בתוספתsuccess. ראו שגיאות.success: falseיכול להגיע עם HTTP 200 — חלק ממסלולי הכשל (בעיקרchange_order_statusשאינו מוצא את המשלוח) מחזירים את המעטפת בסטטוס ברירת המחדל200. קראו תמיד אתsuccessלפני שאתם קוראים אתdata.data.codeהוא תמיד string — התגובה של כל נקודת קצה בקבוצת השילוח עוברת דרך שכבת נורמליזציה שממירה אתdata.codeל-string, מפני שחברות השילוח מחזירות את מזהה המעקב בצורה לא עקבית (חלקן כמספר שלם). פענחו אותו כ-string.יצירות חוזרות (replay) מסומנות — תגובת
open_new_orderמוצלחת נשמרת במטמון לשעה תחת מפתח הרישיון בתוספת מזהה ההזמנה. קריאה חוזרת בתוך החלון הזה מחזירה את התגובה המקורית כפי שהיא, בתוספתdata.idempotent: true, במקום ליצור משלוח שני. הדגל הזה הוא ההבדל היחיד בין הקריאה החוזרת למקורית.מזהים — משלוח מזוהה לפי קוד המעקב של חברת השילוח, שנשלח כ-
shipping_id. חשבון חברת השילוח מזוהה לפי ה-license_keyשלו.הגבלת קצב — 500 בקשות לדקה, לפי כתובת ה-IP של הקורא (או לפי המשתמש המאומת כששולחים
token). חריגה מחזירה HTTP429.
אימות בשורה אחת
כל בקשה לנקודת קצה shipping/* נושאת את פרטי הגישה שלה בגוף הבקשה:
{ "license_key": "{license_key}", "domain": "your-store.example.com" }שני השדות חובה. המודל המלא — מה נבדק, השדה האופציונלי token של Sanctum, ותגובות הכשל המדויקות — נמצא בעמוד אימות.
התחלה מהירה
הציגו את נקודות האיסוף של חברת השילוח הזמינות לרישיון. זו הקריאה הזולה ביותר שמפעילה את כל המסלול: פרטי גישה, פענוח הרישיון והמעטפת.
curl --location 'https://app.shipos.co.il/api/shipping/pickup_locations' \
--header 'Content-Type: application/json' \
--header 'Accept: application/json' \
--data '{
"license_key": "{license_key}",
"domain": "your-store.example.com"
}'// Node.js 18+ / דפדפנים — בלי תלויות
const response = await fetch('https://app.shipos.co.il/api/shipping/pickup_locations', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
Accept: 'application/json',
},
body: JSON.stringify({
license_key: process.env.SHIPOS_LICENSE_KEY,
domain: process.env.SHIPOS_DOMAIN,
}),
})
const body = await response.json()
if (!response.ok || !body.success) {
throw new Error(`ShipOS v1: ${body.message}`) // 403 כשבדיקת הרישיון נכשלת
}
// שימו לב לקינון: המערך נמצא ב-data.locations.spots.spot_detail.
for (const location of body.data.locations.spots.spot_detail) {
console.log(location.name, location.city, location.n_code)
}<?php
use Illuminate\Support\Facades\Http;
$body = Http::acceptJson()
->post('https://app.shipos.co.il/api/shipping/pickup_locations', [
'license_key' => config('services.shipos.license_key'),
'domain' => config('services.shipos.domain'),
])
->json();
if (! ($body['success'] ?? false)) {
throw new RuntimeException('ShipOS v1: '.$body['message']);
}
// שימו לב לקינון: המערך נמצא ב-data.locations.spots.spot_detail.
$points = $body['data']['locations']['spots']['spot_detail'];
logger()->info('Pickup locations', ['count' => count($points)]);הצלחה מחזירה את רשימת הנקודות של חברת השילוח מקוננת תחת data.locations.spots.spot_detail, ולא ישירות על data.locations. ה-transformer של כל חברת שילוח עוטף את המערך כך:
{
"data": {
"locations": {
"spots": {
"spot_detail": [
{
"name": "נקודה לדוגמה",
"city": "תל אביב",
"street": "דיזנגוף",
"house": "50",
"n_code": "1234",
"street_code": "",
"latitude": "32.0809",
"longitude": "34.7736",
"remarks": ""
}
]
}
}
},
"message": "",
"success": true,
"warning": ""
}ערכים חסרים הם מחרוזות ריקות ולא null. ראו נקודות איסוף לתוספות הייחודיות לכל חברת שילוח ולמסלול הכשל המפתיע כשלחברת שילוח אין רשת נקודות איסוף.
אם לא ניתן לפענח את הרישיון, אותה קריאה מחזירה HTTP 403 ואת:
{
"data": [],
"message": "Invalid License Key",
"success": false,
"warning": ""
}איך להתמצא
- אימות — מודל ה-payload של
license_key/domain/token, מה נבדק בפועל, ותגובות הכשל. - שגיאות — המעטפת במסלול הכשל, סטטוסי ה-HTTP שקורא חייב לטפל בהם, ושלושת המבנים השונים שכשל ולידציה יכול לקבל.
- נקודות קצה — התיעוד לכל נתיב של v1, עם פרמטרים ומבני תגובה.
- API v2 — המקום שבו אינטגרציות חדשות צריכות להתחיל.