واجهة ملفات OptiRoutes (API)

دليل لفرق البرمجيات التي تربط شركة بنظام OptiRoutes: تحميل الطلبات، وجمع POD والتصديرات والتقارير — بشكل آمن عبر HTTPS.

EN · HE · AR · RU · ES · IT · CS · RO · EL · DE · FR · PT · JA · KO · ZH · NL · PL · TR · SV · DA · NB · FI · HU · SK · HR · BG · UK · ID · MS · TH · VI · HI · LT · SL

ما هذه الواجهة

لكل شركة في OptiRoutes مجلد ملفات خاص بها: الطلبات التي تحمّلها، وإشعارات التسليم الموقّعة (POD) مع صورها وتواقيعها، وتصديرات المسارات، وتقارير نهاية اليوم. تتيح واجهة الملفات لأنظمتكم قراءة هذا المجلد والكتابة فيه مباشرة، دون خادم FTP وسيط.

ابدؤوا في 3 خطوات

  1. أنشئوا مفتاحًا. في OptiRoutes يفتح المدير الإعدادات ← API والملفات، ويضغط على مفتاح جديد، ويعطيه اسمًا (مثلًا «خادم ERP»)، ويختار الصلاحيات، ثم ينسخ المفتاح. يُعرض المفتاح مرة واحدة فقط.
  2. تحققوا من الاتصال.
    curl -H "Authorization: Bearer $OPTIROUTES_KEY" https://srv2.optiroutes.com/api/v1/me
  3. نزّلوا POD الموقّعة لهذا اليوم في ملف ZIP واحد:
    curl -H "Authorization: Bearer $OPTIROUTES_KEY" -o pod.zip "https://srv2.optiroutes.com/api/v1/pod/archive?date=$(date +%F)"

الأمان — يرجى القراءة

المصادقة

أرسلوا المفتاح مع كل طلب، في إحدى الترويستين التاليتين:

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
تضعون ملف الطلبات على FTPPUT /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>"}.

HTTPerrorما العمل
401missing_key / invalid_keyأرسلوا المفتاح؛ وتأكدوا من أنه لم يُلغَ ولم تنتهِ صلاحيته.
403scope_missingينقص المفتاح الصلاحية — أنشئوا مفتاحًا يملكها.
403ip_not_allowedاستدعوا من عنوان مسموح به، أو حدّثوا عناوين المفتاح.
403folder_read_onlyارفعوا الملفات فقط إلى orders_files/ أو inbox/ أو podBaseFile/ أو pod/<file>.pdf.
400invalid_path / invalid_dateالمسارات نسبية (orders_files/a.csv)، والتواريخ بصيغة YYYY-MM-DD.
404not_found / no_pod_filesلا يوجد ملف كهذا / لا توجد POD في ذلك اليوم.
413file_too_largeبحد أقصى 50 ميغابايت للملف.
429rate_limitedانتظروا دقيقة ثم أعيدوا المحاولة.
502 / 503storage_unavailable / files_api_unavailableمؤقت — أعيدوا المحاولة بعد دقيقة.

الحدود

المساعدة

يرى مدير الشركة كل مفتاح وآخر استخدام له وآخر الاستدعاءات في الإعدادات ← API والملفات. لأي أمر آخر، تواصلوا مع دعم OptiRoutes مع ذكر رقم الشركة ووقت الاستدعاء — ولا ترسلوا المفتاح نفسه أبدًا.