Apakah ini
Setiap syarikat dalam OptiRoutes mempunyai folder fail peribadinya sendiri: pesanan yang dimuatkannya, nota penghantaran yang ditandatangani (POD) bersama foto dan tandatangannya, eksport laluan dan laporan akhir hari. API Fail membolehkan sistem Anda membaca dan menulis folder itu secara terus, tanpa pelayan FTP di tengah-tengah.
- Alamat:
https://srv2.optiroutes.com/api/v1— HTTPS sahaja. - Akses: kunci API yang dicipta oleh pengurus syarikat dalam OptiRoutes, dalam Tetapan → API & fail. Tiada permintaan kepada sokongan OptiRoutes diperlukan.
- Setiap jenis fail yang digunakan oleh sistem hari ini: CSV, JSON, TXT, XLSX/XLS, PDF dan imej.
- Jawapan adalah dalam JSON, kecuali muat turun fail, yang mengembalikan fail itu sendiri.
Mulakan dalam 3 langkah
- Cipta kunci. Dalam OptiRoutes, pengurus membuka Tetapan → API & fail, mengklik Kunci baharu, memberikannya nama (contohnya "pelayan ERP"), memilih kebenaran dan menyalin kunci. Kunci dipaparkan sekali sahaja.
- Semak sambungan.
curl -H "Authorization: Bearer $OPTIROUTES_KEY" https://srv2.optiroutes.com/api/v1/me - Muat turun POD bertandatangan hari ini sebagai satu ZIP:
curl -H "Authorization: Bearer $OPTIROUTES_KEY" -o pod.zip "https://srv2.optiroutes.com/api/v1/pod/archive?date=$(date +%F)"
Keselamatan — sila baca
- Layan kunci seperti kata laluan. Simpannya dalam stor rahsia atau pemboleh ubah persekitaran pada pelayan Anda. Jangan sekali-kali meletakkannya dalam halaman web, aplikasi mudah alih, e-mel, tiket atau kawalan sumber.
- Keistimewaan minimum. Berikan setiap sistem kuncinya sendiri dengan hanya kebenaran yang diperlukannya:
pod:read(POD bertandatangan sahaja),files:read(baca setiap fail syarikat),files:write(muat naik pesanan dan fail peti masuk). - Hadkan alamat. Apabila pelayan Anda mempunyai alamat IP tetap, tambahkannya pada kunci ("Alamat yang dibenarkan"). Panggilan dari mana-mana alamat lain ditolak.
- Tamat tempoh dan penggiliran. Kunci boleh tamat tempoh selepas beberapa hari. Untuk menggilir: cipta kunci baharu, tukar sistem Anda kepadanya, kemudian batalkan kunci lama — tiada masa henti.
- Batalkan serta-merta kunci yang mungkin telah bocor: Tetapan → API & fail → Batalkan. Ia berhenti berfungsi dalam masa 30 saat.
- Audit. Setiap panggilan direkodkan (masa, alamat, fail, jawapan) dan dipaparkan kepada pengurus dalam skrin yang sama.
- OptiRoutes hanya menyimpan cap jari (SHA-256) setiap kunci, tidak pernah kunci itu sendiri. Sambungan adalah HTTPS (TLS 1.2+) sahaja.
- Kunci hanya mencapai folder syarikatnya sendiri. Fail syarikat lain dan folder dalaman sistem tidak boleh dicapai sama sekali.
Pengesahan
Hantar kunci dalam setiap permintaan, dalam salah satu pengepala ini:
Authorization: Bearer opr_2813_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# or
X-API-Key: opr_2813_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxKunci kelihatan seperti opr_2813_… (nombor syarikat, kemudian 32 aksara rawak).
Folder syarikat
| Folder | Kandungannya | Siapa yang menulis |
|---|---|---|
orders_files/ | Fail pesanan harian yang dimuatkan oleh OptiRoutes: orders_files/YYYY-MM-DD.csv (atau .json / .TXT, seperti yang ditetapkan dalam Tetapan → Pemuatan). Eksport laluan: orders_files/routes_export_YYYY_MM_DD.csv. | Anda (pesanan) · OptiRoutes (eksport) |
pod/YYYY/MM/DD/ | POD bertandatangan hari itu: <order>_sign_….pdf, tandatangan dan foto (<order>_….png/jpg). | OptiRoutes |
pod/ | Nota penghantaran sumber untuk ditandatangani dalam aplikasi pemandu: pod/<order number>.pdf. | Anda |
reports/YYYY/MM/ | Laporan akhir hari dan pemulangan. | OptiRoutes |
podBaseFile/ | Borang asas POD. | Anda |
inbox/ | Folder bebas untuk fail yang Anda mahu serahkan. | Anda |
Rujukan
| Panggilan | Kebenaran | Apa yang dilakukannya |
|---|---|---|
GET /api/v1/me | sebarang | Menyemak kunci. Menjawab dengan nombor syarikat, kebenaran kunci dan alamat Anda. |
GET /api/v1/files?folder=<folder> | files:read (pod:read: pod/ sahaja) | Menyenaraikan satu tahap folder: fail (nama, laluan, saiz, diubah suai) dan subfolder. |
GET /api/v1/files/download?path=<file> | files:read (pod:read: pod/ sahaja) | Memuat turun satu fail. |
PUT /api/v1/files?path=<file> | files:write | Memuat naik fail (badan permintaan ialah fail, atau borang multipart dengan medan file). Fail sedia ada digantikan. Paling besar 50 MB. |
DELETE /api/v1/files?path=<file> | files:write | Memadam fail yang Anda muat naik (di tempat Anda dibenarkan memuat naik). |
GET /api/v1/pod?date=YYYY-MM-DD[&order=<number>] | pod:read | Fail POD sesuatu hari, masing-masing dengan nombor pesanan dan jenisnya: signed_pdf, signature, photo. |
GET /api/v1/pod/archive?date=YYYY-MM-DD[&kind=signed_pdf] | pod:read | Setiap fail POD hari itu sebagai satu ZIP. |
Contoh jawapan penyenaraian:
{
"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" }
]
}Tugasan biasa
Muat naik fail pesanan hari ini
# 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 memuatkan fail seperti yang dimuatkannya hari ini (pemuatan automatik Tetapan → Pemuatan, atau "Muatkan fail" oleh pengguna).
Muat turun POD bertandatangan bagi satu pesanan
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"
Muat turun laporan akhir hari
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()));
}Bekerja seperti FTP — skrip penyegerakan folder
Pasukan yang bekerja dengan FTP boleh mengekalkan folder pada pelayan mereka sendiri disegerakkan dengan folder syarikat: tugasan berjadual memuat turun fail baharu (contohnya POD) dan memuat naik fail yang Anda letakkan dalam folder setempat. Skrip PowerShell di bawah melakukan kedua-duanya; jalankannya setiap beberapa minit daripada Windows Task Scheduler (pada Linux, gunakan baris curl dengan 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
}Memindahkan syarikat dari FTP ke API
Pengurus menukar dalam Tetapan → API & fail → Fail bergerak melalui: API. Mulai saat itu, tiada apa-apa dihantar ke FTP syarikat, dan setiap fail berada dalam folder syarikat:
| Dengan FTP | Dengan API |
|---|---|
| Anda meletakkan fail pesanan pada FTP | PUT /api/v1/files?path=orders_files/YYYY-MM-DD.csv |
POD bertandatangan dihantar ke /POD/ pada FTP Anda | GET /api/v1/pod?date=… / /api/v1/pod/archive?date=… |
Eksport laluan dihantar ke /orders/ | orders_files/routes_export_YYYY_MM_DD.csv |
Laporan dihantar ke /orders/YYYY/MM/ | reports/YYYY/MM/ |
Syarikat baharu bekerja dengan API dari awal. Kembali ke FTP menggunakan suis yang sama.
Syarikat pada pelayan OptiRoutes lama
Syarikat yang masih bekerja dengan pelayan OptiRoutes lama (WEB) boleh menggunakan API untuk POD bertandatangannya: cipta kunci dengan kebenaran pod:read dan gunakan /api/v1/pod, /api/v1/pod/archive dan /api/v1/files/download?path=pod/…. Fail lainnya terus bergerak seperti hari ini, sehingga syarikat berpindah ke pelayan baharu.
Ralat
Ralat menjawab dengan {"ok": false, "error": "<code>", "message": "<explanation>"}.
| HTTP | error | Apa yang perlu dilakukan |
|---|---|---|
| 401 | missing_key / invalid_key | Hantar kunci; semak bahawa ia tidak dibatalkan atau tamat tempoh. |
| 403 | scope_missing | Kunci tiada kebenaran itu — cipta kunci dengan kebenaran tersebut. |
| 403 | ip_not_allowed | Buat panggilan dari alamat yang dibenarkan, atau kemas kini alamat kunci. |
| 403 | folder_read_only | Muat naik hanya ke orders_files/, inbox/, podBaseFile/ atau pod/<file>.pdf. |
| 400 | invalid_path / invalid_date | Laluan adalah relatif (orders_files/a.csv), tarikh dalam format YYYY-MM-DD. |
| 404 | not_found / no_pod_files | Tiada fail sedemikian / tiada POD pada hari itu. |
| 413 | file_too_large | Paling besar 50 MB bagi setiap fail. |
| 429 | rate_limited | Tunggu seminit dan cuba semula. |
| 502 / 503 | storage_unavailable / files_api_unavailable | Sementara — cuba semula dalam seminit. |
Had
- 300 permintaan seminit bagi setiap kunci.
- 50 MB bagi setiap fail.
- 20 kunci aktif bagi setiap syarikat.
- Penyenaraian folder mengembalikan sehingga 5,000 entri; senaraikan subfolder (contohnya POD untuk satu hari) untuk lebih banyak.
Bantuan
Pengurus syarikat melihat setiap kunci, penggunaan terakhirnya dan panggilan terakhir dalam Tetapan → API & fail. Untuk perkara lain, hubungi sokongan OptiRoutes dengan nombor syarikat dan masa panggilan — jangan sekali-kali menghantar kunci itu sendiri.