Что это
У каждой компании в OptiRoutes есть своя закрытая папка с файлами: загружаемые ею заказы, подписанные накладные (POD) с фотографиями и подписями, экспорт маршрутов и отчёты по итогам дня. 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(загрузка заказов и файлов во входящую папку). - Ограничьте адреса. Если у вашего сервера фиксированный 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 активных ключей на компанию.
- Список папки содержит не более 5 000 элементов; чтобы получить больше, запрашивайте списки вложенных папок (например, одного дня POD).
Помощь
Менеджер компании видит каждый ключ, время его последнего использования и последние вызовы в разделе Настройки → API и файлы. По всем остальным вопросам обращайтесь в поддержку OptiRoutes, указав номер компании и время вызова, — никогда не отправляйте сам ключ.