คืออะไร
ทุกบริษัทใน OptiRoutes มีโฟลเดอร์ไฟล์ส่วนตัวของตัวเอง: การจัดส่งที่โหลด ใบส่งของที่ลงนามแล้ว (POD) พร้อมรูปภาพและลายเซ็น ไฟล์ส่งออกเส้นทาง และรายงานเมื่อจบวัน Files API ช่วยให้ระบบของคุณอ่านและเขียนโฟลเดอร์นั้นได้โดยตรง โดยไม่ต้องมีเซิร์ฟเวอร์ 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(อัปโหลดการจัดส่งและไฟล์ inbox) - จำกัดที่อยู่ เมื่อเซิร์ฟเวอร์ของคุณมีที่อยู่ 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 MB |
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 Task Scheduler (บน 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 MB ต่อไฟล์ |
| 429 | rate_limited | รอหนึ่งนาทีแล้วลองอีกครั้ง |
| 502 / 503 | storage_unavailable / files_api_unavailable | ชั่วคราว — ลองอีกครั้งในอีกหนึ่งนาที |
ขีดจำกัด
- 300 คำขอต่อนาทีต่อคีย์
- 50 MB ต่อไฟล์
- คีย์ที่ใช้งานอยู่ 20 รายการต่อบริษัท
- การแสดงรายการโฟลเดอร์ส่งคืนได้สูงสุด 5,000 รายการ หากต้องการมากกว่านี้ ให้แสดงรายการโฟลเดอร์ย่อย (เช่น POD ของหนึ่งวัน)
ความช่วยเหลือ
ผู้จัดการของบริษัทจะเห็นทุกคีย์ การใช้ครั้งล่าสุด และการเรียกล่าสุดใน การตั้งค่า → API และไฟล์ สำหรับเรื่องอื่น ๆ โปรดติดต่อฝ่ายสนับสนุนของ OptiRoutes พร้อมเลขทะเบียนบริษัทและเวลาของการเรียก — ห้ามส่งตัวคีย์