ממשק הקבצים של אופטירוץ (API)

מדריך לצוותי התוכנה שמחברים חברה לאופטירוץ: טעינת הזמנות, משיכת 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

מה זה

לכל חברה באופטירוץ יש תיקיית קבצים פרטית משלה: ההזמנות שהיא טוענת, תעודות המשלוח החתומות (POD) עם התמונות והחתימות, ייצואי המסלולים ודוחות סוף היום. ממשק הקבצים מאפשר למערכות שלכם לקרוא ולכתוב בתיקייה הזו ישירות, בלי שרת FTP באמצע.

מתחילים ב־3 צעדים

  1. יוצרים מפתח. באופטירוץ המנהל פותח הגדרות ← 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/קובץ ההזמנות היומי שאופטירוץ טוענת: orders_files/YYYY-MM-DD.csv (או .json / .TXT, לפי הגדרות ← טעינה). ייצוא מסלולים: orders_files/routes_export_YYYY_MM_DD.csv.אתם (הזמנות) · אופטירוץ (ייצואים)
pod/YYYY/MM/DD/ה־POD החתומים של אותו יום: <order>_sign_….pdf, החתימה והתמונות.אופטירוץ
pod/תעודות מקור לחתימה באפליקציית הנהג: pod/<מספר הזמנה>.pdf.אתם
reports/YYYY/MM/דוחות סוף יום והחזרות.אופטירוץ
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). קובץ קיים מוחלף. עד 50MB.
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"

אופטירוץ טוענת את הקובץ כמו היום (הטעינה האוטומטית של הגדרות ← טעינה, או "טעינת קובץ" של המשתמש).

הורדת ה־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 שלמטה עושה את שניהם; מריצים אותו כל כמה דקות מ־Task Scheduler של Windows (בלינוקס — שורות ה־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 — באותו מתג.

חברות שעובדות מול השרת הישן

חברה שעדיין עובדת מול השרת הישן של אופטירוץ (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עד 50MB לקובץ.
429rate_limitedמחכים דקה ומנסים שוב.
502 / 503storage_unavailable / files_api_unavailableזמני — מנסים שוב בעוד דקה.

מגבלות

עזרה

מנהל החברה רואה כל מפתח, את השימוש האחרון בו ואת הפניות האחרונות בהגדרות ← API וקבצים. לכל דבר אחר — פונים לתמיכה של אופטירוץ עם מספר החברה והשעה של הפנייה. לעולם לא שולחים את המפתח עצמו.