توثيق API
كل ما تحتاجه لدمج منصة التوصيل الخاصة بك مع RouteMate.
المحتويات
البدء
تتيح لك واجهة RouteMate Integration API استيراد مهام التوصيل برمجيا، وتحسين المسارات تلقائيا، والاستعلام عن حالة المهام من أنظمتك الحالية.
عنوان URL الأساسي
https://api.routemate.app/v1كيف يعمل
- أنشئ تكاملا — في تطبيق RouteMate على الويب، انتقل إلى التكاملات واضغط على إنشاء تكامل. ستحصل على client_id و client_secret.
- احصل على رمز وصول — بدّل بيانات الاعتماد الخاصة بك برمز bearer مؤقت صالح لمدة ساعة واحدة.
- استورد مهمة — أرسل نقاط التوقف الخاصة بالتوصيل عبر POST. سيقوم RouteMate بترميز العناوين جغرافيا وتحسين ترتيب المسار وتعيين المهمة لسائق.
- تحقق من الحالة — راقب تقدم المهمة في أي وقت لمعرفة نقاط التوقف التي اكتملت.
المتطلبات
- حساب RouteMate على خطة Team أو Enterprise
- مؤسسة تم إنشاؤها داخل تطبيق RouteMate على الويب
- تكامل نشط مع بيانات client credentials
تدفق بيانات اعتماد العميل
تستخدم الواجهة OAuth2 client credentials. لا يتم حفظ secret الخاص بك نصا صريحا، بل نحتفظ فقط ببصمة SHA-256 على خوادمنا.
نموذج الأمان
- يتم عمل hash لبيانات client secret باستخدام SHA-256 ولا يتم حفظها كنص صريح
- رموز الوصول opaque وليست JWT وصالحة لمدة ساعة واحدة
- الرموز أحادية الاستخدام ومقيدة بتكاملك فقط
- يجب إرسال جميع الطلبات عبر HTTPS
- أرسل الرمز في كل طلب: Authorization: Bearer <token>
مهم: يتم عرض client_secret مرة واحدة فقط عند إنشاء التكامل. احتفظ به بشكل آمن، مثل متغيرات البيئة أو مدير الأسرار. إذا فقدته، فستحتاج إلى إعادة توليده من لوحة RouteMate.
الحصول على رمز الوصول
/v1/integration-tokenنص الطلب
| Field | Type | Required | Description |
|---|---|---|---|
| client_id | string | Yes | معرّف client ID الخاص بتكاملك (يبدأ بـ rm_ci_) |
| client_secret | string | Yes | قيمة client secret الخاصة بتكاملك (تبدأ بـ rm_cs_) |
مثال على الطلب
curl -X POST https://api.routemate.app/v1/integration-token \
-H "Content-Type: application/json" \
-d '{
"client_id": "rm_ci_abc123...",
"client_secret": "rm_cs_xyz789..."
}'استجابة النجاح 200
{
"access_token": "rm_at_e5988dd1b91a4ff3827c5d2ed416ccbe37ae227a",
"token_type": "Bearer",
"expires_in": 3600
}استجابات الأخطاء
400client_id أو client_secret مفقود
401بيانات الاعتماد غير صالحة (secret خاطئ أو client_id غير معروف)
403تم تعطيل هذا التكامل
استيراد المهمة ونقاط التوقف
/v1/integration-importترويسات الطلب
| Field | Type | Required | Description |
|---|---|---|---|
| Authorization | string | Yes | Bearer <access_token> |
| Content-Type | string | Yes | application/json |
| Idempotency-Key | string | No | مفتاح فريد لمنع تكرار الاستيراد (صالح لمدة 24 ساعة) |
نص الطلب — حقول المهمة
| Field | Type | Required | Description |
|---|---|---|---|
| external_job_id | string | Yes | المعرف الفريد الخاص بك لهذه المهمة (يجب أن يكون فريدا لكل تكامل) |
| title | string | Yes | عنوان المهمة (مثال: Morning Deliveries - Zone A) |
| driver_email | string | Yes | البريد الإلكتروني للسائق الذي سيتم تعيينه. إذا كان لديه حساب RouteMate فسيرى المسار في التطبيق، وإلا سيتم إنشاء دعوة له. |
| scheduled_date | string | No | التاريخ المجدول بصيغة ISO (YYYY-MM-DD) |
| timezone | string | No | المنطقة الزمنية وفق IANA (مثل Australia/Brisbane أو America/New_York) |
| metadata | object | No | بيانات مخصصة بصيغة مفتاح-قيمة مرتبطة بالمهمة |
| stops | array | Yes | مصفوفة من كائنات نقاط التوقف (راجع حقول نقطة التوقف أدناه) |
مثال على الطلب
curl -X POST https://api.routemate.app/v1/integration-import \
-H "Authorization: Bearer rm_at_your_token_here" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: order-batch-2026-03-09-001" \
-d '{
"external_job_id": "BATCH-2026-03-09-A",
"title": "Morning Deliveries - Zone A",
"driver_email": "driver@example.com",
"scheduled_date": "2026-03-09",
"timezone": "Australia/Brisbane",
"stops": [
{
"external_stop_id": "ORD-1001",
"address": "1 George St, Brisbane QLD 4000, Australia",
"label": "John Smith",
"notes": "Leave at front door",
"priority": 1,
"parcel_count": 2
},
{
"external_stop_id": "ORD-1002",
"address": "100 Queen St, Brisbane QLD 4000, Australia",
"label": "Jane Doe",
"notes": "Ring doorbell",
"priority": 2
},
{
"external_stop_id": "ORD-1003",
"address": "South Bank Parklands, Brisbane QLD 4101, Australia",
"label": "Bob Wilson",
"priority": 3,
"parcel_count": 1
}
]
}'استجابة النجاح 200
{
"job_id": "e7ad097b-bc51-4d01-9b04-0e372d80613a",
"external_job_id": "BATCH-2026-03-09-A",
"route_id": "1c2a8c0b-1b69-4a04-85b1-608b2ebe3878",
"driver_email": "driver@example.com",
"driver_resolved": true,
"driver_user_id": "573b6bee-aa3d-4cb0-af87-620bba0db049",
"stops_imported": 3,
"stops_geocoded": 3,
"stops_geocode_failed": 0,
"optimization": {
"total_distance_km": 12.4,
"total_duration_minutes": 25,
"encoded_polyline": "fvmfDqmfe\\bPtA..."
},
"stops": [
{
"external_stop_id": "ORD-1001",
"address": "1 George St, Brisbane QLD 4000, Australia",
"latitude": -27.4710,
"longitude": 153.0234,
"label": "John Smith",
"notes": "Leave at front door",
"sort_order": 0,
"priority": 1,
"parcel_count": 2,
"status": "pending"
},
{
"external_stop_id": "ORD-1003",
"address": "South Bank Parklands, Brisbane QLD 4101, Australia",
"latitude": -27.4753,
"longitude": 153.0208,
"label": "Bob Wilson",
"notes": null,
"sort_order": 1,
"priority": 3,
"parcel_count": 1,
"status": "pending"
},
{
"external_stop_id": "ORD-1002",
"address": "100 Queen St, Brisbane QLD 4000, Australia",
"latitude": -27.4688,
"longitude": 153.0281,
"label": "Jane Doe",
"notes": "Ring doorbell",
"sort_order": 2,
"priority": 2,
"parcel_count": 1,
"status": "pending"
}
],
"deep_link": "https://app.routemate.app/app/jobs/e7ad097b-...",
"warnings": [
{ "code": "ADDRESS_GEOCODED", "message": "3 stop(s) were geocoded from address text" },
{ "code": "ROUTE_OPTIMIZED", "message": "Route optimized: 12.4 km, 25 min" }
]
}ملاحظة: ملاحظة: يتم إرجاع مصفوفة stops بترتيب التوصيل المحسن حسب sort_order، وليس حسب ترتيب الإرسال.
رموز التحذير
| Field | Type | Required | Description |
|---|---|---|---|
| ROUTE_OPTIMIZED | info | No | تم تحسين المسار بنجاح مع احتساب المسافة والمدة |
| ADDRESS_GEOCODED | info | No | تم ترميز عنوان نقطة توقف واحدة أو أكثر جغرافيا من نص العنوان |
| DRIVER_AUTO_ADDED | info | No | كان لدى السائق حساب RouteMate وتمت إضافته تلقائيا إلى مؤسستك |
| DRIVER_NOT_FOUND | warning | No | لم يتم العثور على حساب RouteMate لهذا البريد الإلكتروني. تم إنشاء دعوة. |
| GEOCODE_FAILED | warning | No | تعذر ترميز عنوان نقطة التوقف جغرافيا. قدّم latitude/longitude بدلا من ذلك. |
الاستعلام عن حالة المهمة
/v1/integration-jobsمعلمات الاستعلام
| Field | Type | Required | Description |
|---|---|---|---|
| external_job_id | string | No | معرف المهمة الخارجي الذي زودتنا به أثناء الاستيراد |
| job_id | string | No | معرّف UUID الداخلي للمهمة في RouteMate |
يجب توفير external_job_id أو job_id على الأقل.
مثال على الطلب
curl "https://api.routemate.app/v1/integration-jobs?external_job_id=BATCH-2026-03-09-A" \
-H "Authorization: Bearer rm_at_your_token_here"استجابة النجاح 200
{
"job_id": "e7ad097b-bc51-4d01-9b04-0e372d80613a",
"external_job_id": "BATCH-2026-03-09-A",
"title": "Morning Deliveries - Zone A",
"status": "assigned",
"driver_email": "driver@example.com",
"driver_resolved": true,
"driver_user_id": "573b6bee-...",
"route_id": "1c2a8c0b-...",
"scheduled_date": "2026-03-09",
"timezone": "Australia/Brisbane",
"metadata": {},
"stop_count": 3,
"status_counts": {
"pending": 2,
"completed": 1
},
"deep_link": "https://app.routemate.app/app/jobs/e7ad097b-...",
"stops": [
{
"external_stop_id": "ORD-1001",
"address": "1 George St, Brisbane QLD 4000",
"latitude": -27.4710,
"longitude": 153.0234,
"label": "John Smith",
"notes": "Leave at front door",
"status": "completed",
"priority": 1,
"parcel_count": 2
},
...
],
"created_at": "2026-03-09T08:30:00.000Z",
"updated_at": "2026-03-09T10:15:00.000Z"
}حالات المهمة
| Field | Type | Required | Description |
|---|---|---|---|
| pending | status | No | تم إنشاء المهمة لكن لم يتم بعد تعيين السائق أو حله |
| assigned | status | No | تم تعيين السائق ويمكنه رؤية المسار في التطبيق |
| in_progress | status | No | بدأ السائق المسار |
| completed | status | No | تم تسليم جميع نقاط التوقف |
حقول نقطة التوقف
القائمة الكاملة للحقول المتاحة لكل نقطة توقف في طلب الاستيراد.
| Field | Type | Required | Description |
|---|---|---|---|
| external_stop_id | string | Yes | المعرف الفريد الخاص بك لهذه النقطة (يجب أن يكون فريدا داخل المهمة) |
| address | string | Yes | العنوان الكامل. سيتم ترميزه جغرافيا إذا لم يتم توفير latitude/longitude. |
| latitude | number | No | خط العرض بالدرجات العشرية. يتجاوز الترميز الجغرافي إذا تم إرساله مع longitude. |
| longitude | number | No | خط الطول بالدرجات العشرية. يتجاوز الترميز الجغرافي إذا تم إرساله مع latitude. |
| label | string | No | تسمية ظاهرة للمستخدم (مثل اسم العميل أو رقم الطلب) |
| notes | string | No | تعليمات التوصيل للسائق |
| service_type | string | No | نوع الخدمة (مثل delivery أو pickup أو service_call) |
| duration_minutes | number | No | المدة المتوقعة للخدمة في هذه النقطة بالدقائق |
| time_window_start | string | No | أقرب وقت للتسليم (ISO 8601 datetime) |
| time_window_end | string | No | آخر وقت للتسليم (ISO 8601 datetime) |
| priority | number | No | مستوى الأولوية (كلما كان الرقم أقل كانت الأولوية أعلى). الافتراضي: 0 |
| parcel_count | number | No | عدد الطرود لهذه النقطة. الافتراضي: 1 |
| metadata | object | No | بيانات مخصصة بصيغة مفتاح-قيمة مرتبطة بنقطة التوقف هذه |
نصيحة: نصيحة: توفير latitude و longitude مباشرة أسرع وأكثر موثوقية من الترميز الجغرافي.
تحسين المسار
كل عملية استيراد تعمل تلقائيا على تحسين ترتيب التوصيل لتقليل المسافة والوقت.
كيف يعمل التحسين
- يتم ترميز جميع نقاط التوقف التي لا تحتوي على إحداثيات جغرافيا بالاعتماد على نص العنوان
- تُعامل نقطة التوقف الأولى كنقطة انطلاق والأخيرة كوجهة نهائية
- يتم تحسين جميع نقاط التوقف الوسطية للحصول على أقصر مسار قيادة باستخدام Google Routes API
- يتم تحديث حقل sort_order في كل نقطة توقف ليعكس الترتيب المحسن
- يتم احتساب خط المسار والمسافة الإجمالية والمدة التقديرية
حقول الاستجابة
| Field | Type | Required | Description |
|---|---|---|---|
| optimization.total_distance_km | number | No | إجمالي مسافة المسار بالكيلومترات |
| optimization.total_duration_minutes | number | No | إجمالي وقت القيادة التقديري بالدقائق |
| optimization.encoded_polyline | string | No | Google Encoded Polyline لعرض المسار على الخريطة |
ملاحظة: ملاحظة: يتطلب التحسين وجود نقطتي توقف على الأقل بإحداثيات صالحة. إذا فشل الترميز الجغرافي لبعض النقاط، فسيتم تحسين المسار باستخدام النقاط التي تم ترميزها بنجاح فقط.
Idempotency
أعد محاولة الطلبات الفاشلة بأمان من دون إنشاء مهام مكررة.
أضف ترويسة Idempotency-Key بقيمة فريدة إلى طلبات الاستيراد. إذا أُرسل المفتاح نفسه خلال 24 ساعة، ستعيد الواجهة الاستجابة المخزنة بدلا من إنشاء مهمة مكررة.
curl -X POST https://api.routemate.app/v1/integration-import \
-H "Authorization: Bearer rm_at_your_token" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: batch-2026-03-09-zone-a" \
-d '{ ... }'
# Safe to retry — same Idempotency-Key returns cached response
curl -X POST https://api.routemate.app/v1/integration-import \
-H "Authorization: Bearer rm_at_your_token" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: batch-2026-03-09-zone-a" \
-d '{ ... }'أفضل ممارسة: استخدم دائما Idempotency-Key في بيئة الإنتاج. استخدم مفتاحا حتميا حتى لا تؤدي إعادة المحاولة عبر الشبكة إلى إنشاء بيانات مكررة.
معالجة الأخطاء
تُرجع جميع الأخطاء استجابة JSON تحتوي على حقل error.
{
"error": "Rate limit exceeded",
"retry_after_seconds": 45
}
// أو لأخطاء التحقق:
{
"error": {
"code": "VALIDATION_ERROR",
"messages": [
"external_job_id is required",
"stops[0].address is required"
]
}
}| الحالة | المعنى | الإجراء |
|---|---|---|
| 200 | نجاح | تم تنفيذ الطلب بنجاح |
| 400 | طلب غير صالح | راجع رسائل الخطأ وصحح نص الطلب |
| 401 | غير مصرح | الرمز غير صالح أو منتهي الصلاحية. احصل على رمز جديد. |
| 403 | محظور | تم تعطيل تكاملك. تواصل مع المسؤول. |
| 404 | غير موجود | المهمة أو نقطة النهاية غير موجودة |
| 405 | الطريقة غير مسموحة | استخدم طريقة HTTP الصحيحة (POST أو GET) |
| 429 | طلبات كثيرة جدا | انتظر retry_after_seconds قبل إعادة المحاولة |
| 500 | خطأ في الخادم | أعد المحاولة باستخدام exponential backoff وتواصل مع الدعم إذا استمرت المشكلة. |
حدود المعدل
تُطبق حدود المعدل لكل تكامل ضمن نافذة متحركة مدتها دقيقة واحدة.
| الخطة | الطلبات / الدقيقة | أقصى عدد توقفات / استيراد |
|---|---|---|
| Team | 60 | 200 |
| Enterprise | Custom | Custom |
عند تفعيل حد المعدل، تُرجع الواجهة HTTP 429 مع الحقل retry_after_seconds.
أمثلة كود كاملة
أمثلة جاهزة للنسخ للغات الشائعة. جميعها تعرض التدفق الكامل: المصادقة، الاستيراد، والاستعلام.
#!/bin/bash
# RouteMate API Integration Example
API_BASE="https://api.routemate.app/v1"
CLIENT_ID="rm_ci_your_client_id"
CLIENT_SECRET="rm_cs_your_client_secret"
# Step 1: Get access token
TOKEN=$(curl -s -X POST "$API_BASE/integration-token" \
-H "Content-Type: application/json" \
-d "{
\"client_id\": \"$CLIENT_ID\",
\"client_secret\": \"$CLIENT_SECRET\"
}" | jq -r '.access_token')
echo "Access Token: $TOKEN"
# Step 2: Import a job with stops
RESULT=$(curl -s -X POST "$API_BASE/integration-import" \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: my-batch-001" \
-d '{
"external_job_id": "BATCH-001",
"title": "Morning Deliveries",
"driver_email": "driver@example.com",
"scheduled_date": "2026-03-10",
"timezone": "Australia/Brisbane",
"stops": [
{
"external_stop_id": "STOP-1",
"address": "1 George St, Brisbane QLD 4000",
"label": "Customer A",
"parcel_count": 2
},
{
"external_stop_id": "STOP-2",
"address": "100 Queen St, Brisbane QLD 4000",
"label": "Customer B",
"notes": "Leave at reception"
}
]
}')
echo "$RESULT" | jq .
# Step 3: Query job status
JOB_ID=$(echo "$RESULT" | jq -r '.job_id')
curl -s "$API_BASE/integration-jobs?job_id=$JOB_ID" \
-H "Authorization: Bearer $TOKEN" | jq .Webhooks
احصل على إشعارات فورية عند اكتمال عمليات التسليم.
دعم Webhooks قادم قريبا. ستتمكن من تسجيل URL واستلام إشعارات POST لأحداث مثل:
- job.completed — تم تسليم جميع نقاط التوقف داخل المهمة
- stop.completed — تم إكمال نقطة توقف واحدة (بما في ذلك إثبات التسليم)
- stop.failed — فشلت محاولة تسليم
- driver.location — تحديثات GPS للسائق في الوقت الفعلي
هل تهتم بالحصول على وصول مبكر؟ تواصل معنا.