Qué es
Cada empresa en OptiRoutes tiene su propia carpeta privada de archivos: los pedidos que carga, las notas de entrega firmadas (POD) con sus fotos y firmas, las exportaciones de rutas y los informes de fin de día. La API de archivos permite que sus sistemas lean y escriban directamente en esa carpeta, sin un servidor FTP de por medio.
- Dirección:
https://srv2.optiroutes.com/api/v1— solo HTTPS. - Acceso: una clave de API que el gerente de la empresa crea en OptiRoutes, en Configuración → API y archivos. No es necesario hacer ninguna solicitud al soporte de OptiRoutes.
- Todos los tipos de archivo con los que trabaja hoy el sistema: CSV, JSON, TXT, XLSX/XLS, PDF e imágenes.
- Las respuestas son JSON, salvo las descargas de archivos, que devuelven el propio archivo.
Empiece en 3 pasos
- Cree una clave. En OptiRoutes, el gerente abre Configuración → API y archivos, hace clic en Clave nueva, le da un nombre (por ejemplo, “servidor ERP”), elige los permisos y copia la clave. La clave se muestra una sola vez.
- Compruebe la conexión.
curl -H "Authorization: Bearer $OPTIROUTES_KEY" https://srv2.optiroutes.com/api/v1/me - Descargue los POD firmados de hoy en un único ZIP:
curl -H "Authorization: Bearer $OPTIROUTES_KEY" -o pod.zip "https://srv2.optiroutes.com/api/v1/pod/archive?date=$(date +%F)"
Seguridad: léalo con atención
- Trate la clave como una contraseña. Guárdela en un almacén de secretos o en una variable de entorno de su servidor. No la ponga nunca en una página web, una aplicación móvil, un correo electrónico, un ticket ni un control de versiones.
- Mínimo privilegio. Dé a cada sistema su propia clave, con solo los permisos que necesita:
pod:read(solo los POD firmados),files:read(leer todos los archivos de la empresa),files:write(subir pedidos y archivos del buzón de entrada). - Limite las direcciones. Si su servidor tiene una dirección IP fija, añádala a la clave (“Direcciones permitidas”). Se rechaza toda llamada desde cualquier otra dirección.
- Caducidad y rotación. Una clave puede caducar al cabo de cierto número de días. Para rotarla: cree una clave nueva, cambie su sistema a ella y después revoque la antigua; así no hay tiempo de inactividad.
- Revoque de inmediato una clave que pueda haberse filtrado: Configuración → API y archivos → Revocar clave. Deja de funcionar en un máximo de 30 segundos.
- Auditoría. Cada llamada se registra (hora, dirección, archivo, respuesta) y se muestra al gerente en esa misma pantalla.
- OptiRoutes conserva solo una huella (SHA-256) de cada clave, nunca la clave en sí. Las conexiones son únicamente HTTPS (TLS 1.2 o superior).
- Una clave solo llega a la carpeta de su propia empresa. Los archivos de otras empresas y las carpetas internas del sistema nunca son accesibles.
Autenticación
Envíe la clave en cada solicitud, en una de estas cabeceras:
Authorization: Bearer opr_2813_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# or
X-API-Key: opr_2813_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxUna clave tiene este aspecto: opr_2813_… (el número de la empresa, seguido de 32 caracteres aleatorios).
La carpeta de la empresa
| Carpeta | Qué contiene | Quién escribe |
|---|---|---|
orders_files/ | El archivo diario de pedidos que carga OptiRoutes: orders_files/YYYY-MM-DD.csv (o .json / .TXT, según lo definido en Configuración → Carga). Exportaciones de rutas: orders_files/routes_export_YYYY_MM_DD.csv. | Usted (pedidos) · OptiRoutes (exportaciones) |
pod/YYYY/MM/DD/ | Los POD firmados de ese día: <order>_sign_….pdf, la firma y las fotos (<order>_….png/jpg). | OptiRoutes |
pod/ | Notas de entrega de origen que se firmarán en la aplicación del conductor: pod/<order number>.pdf. | Usted |
reports/YYYY/MM/ | Informes de fin de día y de devoluciones. | OptiRoutes |
podBaseFile/ | El formulario base del POD. | Usted |
inbox/ | Carpeta libre para los archivos que desee entregar. | Usted |
Referencia
| Llamada | Permiso | Qué hace |
|---|---|---|
GET /api/v1/me | cualquiera | Comprueba la clave. Responde con el número de la empresa, los permisos de la clave y su dirección. |
GET /api/v1/files?folder=<folder> | files:read (pod:read: solo pod/) | Lista un nivel de carpeta: archivos (nombre, ruta, tamaño, fecha de modificación) y subcarpetas. |
GET /api/v1/files/download?path=<file> | files:read (pod:read: solo pod/) | Descarga un archivo. |
PUT /api/v1/files?path=<file> | files:write | Sube un archivo (el cuerpo de la solicitud es el archivo, o un formulario multipart con un campo file). Un archivo existente se reemplaza. Máximo 50 MB. |
DELETE /api/v1/files?path=<file> | files:write | Elimina un archivo que usted subió (donde se permite subir). |
GET /api/v1/pod?date=YYYY-MM-DD[&order=<number>] | pod:read | Los archivos POD de un día, cada uno con su número de pedido y su tipo: signed_pdf, signature, photo. |
GET /api/v1/pod/archive?date=YYYY-MM-DD[&kind=signed_pdf] | pod:read | Todos los archivos POD del día en un único ZIP. |
Ejemplo de respuesta de un listado:
{
"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" }
]
}Tareas habituales
Subir el archivo de pedidos de hoy
# 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 carga el archivo igual que lo hace hoy (mediante la carga automática de Configuración → Carga, o mediante “Cargar archivo” del usuario).
Descargar los POD firmados de un pedido
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"
Descargar el informe de fin de día
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()));
}Trabajar como con FTP: un script de sincronización de carpetas
Los equipos que trabajaban con FTP pueden mantener una carpeta de su propio servidor sincronizada con la carpeta de la empresa: una tarea programada descarga los archivos nuevos (por ejemplo, los POD) y sube los archivos que usted deja en una carpeta local. El script de PowerShell que se muestra a continuación hace ambas cosas; ejecútelo cada pocos minutos desde el Programador de tareas de Windows (en Linux, use las líneas de curl con 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
}Pasar una empresa de FTP a la API
El gerente cambia en Configuración → API y archivos → Cómo se mueven los archivos de la empresa: API (recomendado). Desde ese momento no se envía nada al FTP de la empresa y, en su lugar, todos los archivos están en la carpeta de la empresa:
| Con FTP | Con la API |
|---|---|
| Usted coloca el archivo de pedidos en el FTP | PUT /api/v1/files?path=orders_files/YYYY-MM-DD.csv |
Los POD firmados se envían a /POD/ en su FTP | GET /api/v1/pod?date=… / /api/v1/pod/archive?date=… |
La exportación de rutas se envía a /orders/ | orders_files/routes_export_YYYY_MM_DD.csv |
Los informes se envían a /orders/YYYY/MM/ | reports/YYYY/MM/ |
Las empresas nuevas trabajan con la API desde el principio. Volver a FTP se hace con el mismo conmutador.
Empresas en el servidor antiguo de OptiRoutes
Una empresa que todavía trabaja con el servidor antiguo de OptiRoutes (WEB) puede usar la API para sus POD firmados: cree una clave con el permiso pod:read y utilice /api/v1/pod, /api/v1/pod/archive y /api/v1/files/download?path=pod/…. Sus demás archivos siguen circulando como hoy, hasta que la empresa pase al servidor nuevo.
Errores
Un error responde con {"ok": false, "error": "<code>", "message": "<explanation>"}.
| HTTP | error | Qué hacer |
|---|---|---|
| 401 | missing_key / invalid_key | Envíe la clave; compruebe que no se haya revocado ni haya caducado. |
| 403 | scope_missing | A la clave le falta el permiso: cree una clave que lo tenga. |
| 403 | ip_not_allowed | Llame desde una dirección permitida o actualice las direcciones de la clave. |
| 403 | folder_read_only | Suba archivos solo a orders_files/, inbox/, podBaseFile/ o pod/<file>.pdf. |
| 400 | invalid_path / invalid_date | Las rutas son relativas (orders_files/a.csv) y las fechas tienen el formato YYYY-MM-DD. |
| 404 | not_found / no_pod_files | No existe ese archivo / no hay POD ese día. |
| 413 | file_too_large | Máximo 50 MB por archivo. |
| 429 | rate_limited | Espere un minuto y vuelva a intentarlo. |
| 502 / 503 | storage_unavailable / files_api_unavailable | Temporal: vuelva a intentarlo en un minuto. |
Límites
- 300 solicitudes por minuto y por clave.
- 50 MB por archivo.
- 20 claves activas por empresa.
- El listado de una carpeta devuelve hasta 5000 entradas; para ver más, liste las subcarpetas (por ejemplo, un día de POD).
Ayuda
El gerente de la empresa ve cada clave, su último uso y las últimas llamadas en Configuración → API y archivos. Para cualquier otra cuestión, póngase en contacto con el soporte de OptiRoutes indicando el número de la empresa y la hora de la llamada; nunca envíe la clave en sí.