ما هذه الواجهة
لكل شركة في OptiRoutes مجلد ملفات خاص بها: الطلبات التي تحمّلها، وإشعارات التسليم الموقّعة (POD) مع صورها وتواقيعها، وتصديرات المسارات، وتقارير نهاية اليوم. تتيح واجهة الملفات لأنظمتكم قراءة هذا المجلد والكتابة فيه مباشرة، دون خادم FTP وسيط.
- العنوان:
https://srv2.optiroutes.com/api/v1— HTTPS فقط. - الوصول: مفتاح API ينشئه مدير الشركة بنفسه في OptiRoutes، في الإعدادات ← API والملفات. لا حاجة إلى تقديم طلب إلى دعم OptiRoutes.
- جميع أنواع الملفات التي يعمل بها النظام اليوم: CSV وJSON وTXT وXLSX/XLS وPDF والصور.
- الردود بصيغة JSON، باستثناء تنزيل الملفات الذي يعيد الملف نفسه.
ابدؤوا في 3 خطوات
- أنشئوا مفتاحًا. في OptiRoutes يفتح المدير الإعدادات ← API والملفات، ويضغط على مفتاح جديد، ويعطيه اسمًا (مثلًا «خادم ERP»)، ويختار الصلاحيات، ثم ينسخ المفتاح. يُعرض المفتاح مرة واحدة فقط.
- تحققوا من الاتصال.
curl -H "Authorization: Bearer $OPTIROUTES_KEY" https://srv2.optiroutes.com/api/v1/me - نزّلوا POD الموقّعة لهذا اليوم في ملف ZIP واحد:
curl -H "Authorization: Bearer $OPTIROUTES_KEY" -o pod.zip "https://srv2.optiroutes.com/api/v1/pod/archive?date=$(date +%F)"
الأمان — يرجى القراءة
- تعاملوا مع المفتاح كما تتعاملون مع كلمة المرور. احفظوه في مخزن أسرار أو في متغير بيئة على خادمكم. لا تضعوه أبدًا في صفحة ويب أو تطبيق جوال أو بريد إلكتروني أو تذكرة دعم أو نظام التحكم بالإصدارات.
- أقل قدر من الصلاحيات. امنحوا كل نظام مفتاحه الخاص بالصلاحيات التي يحتاجها فقط:
pod:read(POD الموقّعة فقط)،files:read(قراءة جميع ملفات الشركة)،files:write(رفع الطلبات وملفات صندوق الوارد). - قيّدوا العناوين. إذا كان لخادمكم عنوان IP ثابت، فأضيفوه إلى المفتاح («العناوين المسموح بها»). يُرفض أي استدعاء من عنوان آخر.
- انتهاء الصلاحية والتدوير. يمكن أن تنتهي صلاحية المفتاح بعد عدد من الأيام. للتدوير: أنشئوا مفتاحًا جديدًا، وحوّلوا نظامكم إليه، ثم ألغوا المفتاح القديم — دون أي توقف في الخدمة.
- ألغوا فورًا أي مفتاح قد يكون تسرّب: الإعدادات ← API والملفات ← إلغاء المفتاح. يتوقف عن العمل خلال 30 ثانية.
- التدقيق. يُسجَّل كل استدعاء (الوقت والعنوان والملف والرد) ويُعرض للمدير في الشاشة نفسها.
- يحتفظ OptiRoutes ببصمة (SHA-256) لكل مفتاح فقط، وليس بالمفتاح نفسه أبدًا. الاتصالات عبر HTTPS (TLS 1.2 أو أحدث) فقط.
- لا يصل المفتاح إلا إلى مجلد شركته. أما ملفات الشركات الأخرى والمجلدات الداخلية للنظام فلا يمكن الوصول إليها إطلاقًا.
المصادقة
أرسلوا المفتاح مع كل طلب، في إحدى الترويستين التاليتين:
Authorization: Bearer opr_2813_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# or
X-API-Key: opr_2813_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxيبدو المفتاح هكذا: opr_2813_… (رقم الشركة، ثم 32 حرفًا عشوائيًا).
مجلد الشركة
| المجلد | ما بداخله | من يكتب |
|---|---|---|
orders_files/ | ملف الطلبات اليومي الذي يحمّله OptiRoutes: orders_files/YYYY-MM-DD.csv (أو .json / .TXT، بحسب الإعداد في الإعدادات ← التحميل). تصديرات المسارات: orders_files/routes_export_YYYY_MM_DD.csv. | أنتم (الطلبات) · OptiRoutes (التصديرات) |
pod/YYYY/MM/DD/ | POD الموقّعة لذلك اليوم: <order>_sign_….pdf، والتوقيع والصور (<order>_….png/jpg). | OptiRoutes |
pod/ | إشعارات التسليم الأصلية التي ستُوقَّع في تطبيق السائق: pod/<order number>.pdf. | أنتم |
reports/YYYY/MM/ | تقارير نهاية اليوم وتقارير المرتجعات. | OptiRoutes |
podBaseFile/ | النموذج الأساسي لـ POD. | أنتم |
inbox/ | مجلد حر للملفات التي تريدون تسليمها. | أنتم |
المرجع
| الاستدعاء | الصلاحية | ما يفعله |
|---|---|---|
GET /api/v1/me | أي صلاحية | يتحقق من المفتاح. يعيد رقم الشركة وصلاحيات المفتاح وعنوانكم. |
GET /api/v1/files?folder=<folder> | files:read (مع pod:read — pod/ فقط) | يعرض مستوى واحدًا من المجلد: الملفات (الاسم والمسار والحجم وتاريخ التعديل) والمجلدات الفرعية. |
GET /api/v1/files/download?path=<file> | files:read (مع pod:read — pod/ فقط) | ينزّل ملفًا واحدًا. |
PUT /api/v1/files?path=<file> | files:write | يرفع ملفًا (جسم الطلب هو الملف، أو نموذج multipart بحقل file). يُستبدل الملف الموجود. بحد أقصى 50 ميغابايت. |
DELETE /api/v1/files?path=<file> | files:write | يحذف ملفًا رفعتموه (في المواضع المسموح الرفع إليها). |
GET /api/v1/pod?date=YYYY-MM-DD[&order=<number>] | pod:read | ملفات POD ليوم معيّن، لكل ملف رقم الطلب ونوعه: signed_pdf وsignature وphoto. |
GET /api/v1/pod/archive?date=YYYY-MM-DD[&kind=signed_pdf] | pod:read | جميع ملفات POD لليوم في ملف ZIP واحد. |
مثال على رد قائمة ملفات:
{
"ok": true,
"folder": "pod/2026/10/11/",
"items": [
{ "name": "12345_sign_2026_10_11.pdf", "path": "pod/2026/10/11/12345_sign_2026_10_11.pdf",
"type": "file", "size": 84213, "modified": "2026-10-11T09:14:02.000Z" }
]
}المهام الشائعة
رفع ملف طلبات اليوم
# curl (Linux / macOS / Windows 10+)
curl -X PUT -H "Authorization: Bearer $OPTIROUTES_KEY" \
--data-binary @orders.csv -H "Content-Type: text/csv" \
"https://srv2.optiroutes.com/api/v1/files?path=orders_files/$(date +%F).csv"
# PowerShell
Invoke-RestMethod -Method Put -InFile .\orders.csv -ContentType 'text/csv' `
-Headers @{ Authorization = "Bearer $env:OPTIROUTES_KEY" } `
-Uri "https://srv2.optiroutes.com/api/v1/files?path=orders_files/$(Get-Date -f yyyy-MM-dd).csv"يحمّل OptiRoutes الملف كما يحمّله اليوم (عبر التحميل التلقائي في الإعدادات ← التحميل، أو عبر «تحميل ملف» من المستخدم).
تنزيل POD الموقّعة لطلب واحد
curl -H "Authorization: Bearer $OPTIROUTES_KEY" "https://srv2.optiroutes.com/api/v1/pod?date=2026-10-11&order=12345"
# then, for each item:
curl -H "Authorization: Bearer $OPTIROUTES_KEY" -OJ "https://srv2.optiroutes.com/api/v1/files/download?path=pod/2026/10/11/12345_sign_2026_10_11.pdf"
تنزيل تقرير نهاية اليوم
curl -H "Authorization: Bearer $OPTIROUTES_KEY" "https://srv2.optiroutes.com/api/v1/files?folder=reports/2026/10/"
curl -H "Authorization: Bearer $OPTIROUTES_KEY" -OJ "https://srv2.optiroutes.com/api/v1/files/download?path=reports/2026/10/report_2026_10_11.csv"
Python
import os, datetime, requests
BASE = "https://srv2.optiroutes.com/api/v1"
H = {"Authorization": f"Bearer {os.environ['OPTIROUTES_KEY']}"}
# upload today's orders
day = datetime.date.today().isoformat()
with open("orders.csv", "rb") as f:
r = requests.put(f"{BASE}/files", params={"path": f"orders_files/{day}.csv"},
data=f, headers={**H, "Content-Type": "text/csv"}, timeout=60)
r.raise_for_status()
# download every signed POD of the day
pods = requests.get(f"{BASE}/pod", params={"date": day}, headers=H, timeout=60).json()["items"]
for p in pods:
if p["kind"] == "signed_pdf":
data = requests.get(f"{BASE}/files/download", params={"path": p["path"]}, headers=H, timeout=60)
open(p["name"], "wb").write(data.content)
C# (.NET)
using var http = new HttpClient { BaseAddress = new Uri("https://srv2.optiroutes.com/api/v1/") };
http.DefaultRequestHeaders.Authorization =
new("Bearer", Environment.GetEnvironmentVariable("OPTIROUTES_KEY"));
// upload today's orders
var day = DateTime.Today.ToString("yyyy-MM-dd");
using var content = new ByteArrayContent(File.ReadAllBytes("orders.csv"));
content.Headers.ContentType = new("text/csv");
(await http.PutAsync($"files?path=orders_files/{day}.csv", content)).EnsureSuccessStatusCode();
// the day's PODs as one ZIP
var zip = await http.GetByteArrayAsync($"pod/archive?date={day}");
File.WriteAllBytes($"pod-{day}.zip", zip);
Node.js
const BASE = 'https://srv2.optiroutes.com/api/v1';
const H = { Authorization: `Bearer ${process.env.OPTIROUTES_KEY}` };
const day = new Date().toISOString().slice(0, 10);
// list and download the day's signed PODs (Node 18+)
const { items } = await (await fetch(`${BASE}/pod?date=${day}`, { headers: H })).json();
for (const p of items.filter((i) => i.kind === 'signed_pdf')) {
const res = await fetch(`${BASE}/files/download?path=${encodeURIComponent(p.path)}`, { headers: H });
await require('fs/promises').writeFile(p.name, Buffer.from(await res.arrayBuffer()));
}العمل كما في FTP — سكربت لمزامنة المجلد
يمكن للفرق التي اعتادت العمل مع FTP إبقاء مجلد على خادمها متزامنًا مع مجلد الشركة: تنزّل مهمة مجدولة الملفات الجديدة (مثل POD) وترفع الملفات التي تضعونها في مجلد محلي. يقوم سكربت PowerShell أدناه بالأمرين معًا؛ شغّلوه كل بضع دقائق من مجدول المهام في Windows (وفي Linux استخدموا أسطر curl مع cron).
# optiroutes-sync.ps1 — download new PODs, upload what is in .\outbox (run every 5 minutes)
$Base = 'https://srv2.optiroutes.com/api/v1'
$H = @{ Authorization = "Bearer $env:OPTIROUTES_KEY" }
$Local = 'C:\OptiRoutes'
New-Item -ItemType Directory -Force "$Local\pod", "$Local\outbox", "$Local\sent" | Out-Null
# 1. today's and yesterday's PODs -> C:\OptiRoutes\pod\YYYY-MM-DD\
foreach ($d in (Get-Date), (Get-Date).AddDays(-1)) {
$day = $d.ToString('yyyy-MM-dd'); $dir = "$Local\pod\$day"
New-Item -ItemType Directory -Force $dir | Out-Null
$list = Invoke-RestMethod -Headers $H -Uri "$Base/pod?date=$day"
foreach ($f in $list.items) {
$dest = Join-Path $dir $f.name
if (-not (Test-Path $dest)) {
Invoke-WebRequest -Headers $H -OutFile $dest -Uri ("$Base/files/download?path=" + [uri]::EscapeDataString($f.path))
}
}
}
# 2. every file in C:\OptiRoutes\outbox -> orders_files/, then moved to C:\OptiRoutes\sent
Get-ChildItem "$Local\outbox" -File | ForEach-Object {
Invoke-RestMethod -Method Put -Headers $H -InFile $_.FullName -ContentType 'application/octet-stream' `
-Uri ("$Base/files?path=" + [uri]::EscapeDataString("orders_files/" + $_.Name)) | Out-Null
Move-Item $_.FullName "$Local\sent\" -Force
}نقل شركة من FTP إلى API
يبدّل المدير الوضع في الإعدادات ← API والملفات ← كيف تنتقل ملفات الشركة: API (موصى به). ومنذ تلك اللحظة لا يُرسل أي شيء إلى FTP الخاص بالشركة، وتصبح كل الملفات في مجلد الشركة بدلًا من ذلك:
| مع FTP | مع API |
|---|---|
| تضعون ملف الطلبات على FTP | PUT /api/v1/files?path=orders_files/YYYY-MM-DD.csv |
تُدفع POD الموقّعة إلى /POD/ على FTP الخاص بكم | GET /api/v1/pod?date=… / /api/v1/pod/archive?date=… |
يُدفع تصدير المسارات إلى /orders/ | orders_files/routes_export_YYYY_MM_DD.csv |
تُدفع التقارير إلى /orders/YYYY/MM/ | reports/YYYY/MM/ |
تعمل الشركات الجديدة مع API منذ البداية. والعودة إلى FTP تتم بالمفتاح نفسه.
الشركات على خادم OptiRoutes القديم
يمكن للشركة التي ما زالت تعمل مع خادم OptiRoutes القديم (WEB) أن تستخدم API لـ POD الموقّعة الخاصة بها: أنشئوا مفتاحًا بصلاحية pod:read واستخدموا /api/v1/pod و/api/v1/pod/archive و/api/v1/files/download?path=pod/…. أما بقية ملفاتها فتستمر في الانتقال كما هي اليوم، إلى أن تنتقل الشركة إلى الخادم الجديد.
الأخطاء
يكون رد الخطأ بالشكل {"ok": false, "error": "<code>", "message": "<explanation>"}.
| HTTP | error | ما العمل |
|---|---|---|
| 401 | missing_key / invalid_key | أرسلوا المفتاح؛ وتأكدوا من أنه لم يُلغَ ولم تنتهِ صلاحيته. |
| 403 | scope_missing | ينقص المفتاح الصلاحية — أنشئوا مفتاحًا يملكها. |
| 403 | ip_not_allowed | استدعوا من عنوان مسموح به، أو حدّثوا عناوين المفتاح. |
| 403 | folder_read_only | ارفعوا الملفات فقط إلى orders_files/ أو inbox/ أو podBaseFile/ أو pod/<file>.pdf. |
| 400 | invalid_path / invalid_date | المسارات نسبية (orders_files/a.csv)، والتواريخ بصيغة YYYY-MM-DD. |
| 404 | not_found / no_pod_files | لا يوجد ملف كهذا / لا توجد POD في ذلك اليوم. |
| 413 | file_too_large | بحد أقصى 50 ميغابايت للملف. |
| 429 | rate_limited | انتظروا دقيقة ثم أعيدوا المحاولة. |
| 502 / 503 | storage_unavailable / files_api_unavailable | مؤقت — أعيدوا المحاولة بعد دقيقة. |
الحدود
- 300 طلب في الدقيقة لكل مفتاح.
- 50 ميغابايت للملف.
- 20 مفتاحًا نشطًا لكل شركة.
- تعيد قائمة المجلد ما يصل إلى 5000 عنصر؛ للمزيد اعرضوا المجلدات الفرعية (مثلًا يومًا واحدًا من POD).
المساعدة
يرى مدير الشركة كل مفتاح وآخر استخدام له وآخر الاستدعاءات في الإعدادات ← API والملفات. لأي أمر آخر، تواصلوا مع دعم OptiRoutes مع ذكر رقم الشركة ووقت الاستدعاء — ولا ترسلوا المفتاح نفسه أبدًا.