Introducción
El servidor de Trucks-MDT expone una API HTTP con JSON, más un WebSocket para eventos en vivo. La usan la tablet, el cliente de escritorio y el panel web. La versión actual de la API es 1.0.
| Elemento | Valor |
|---|---|
| URL base | La dirección del servidor (PUBLIC_URL). En desarrollo, http://localhost:3000 |
| Formato | JSON. Las peticiones con cuerpo deben enviar Content-Type: application/json |
| WebSocket | /ws: empuja eventos a los paneles (cookie de sesión) y al cliente (token Bearer) |
Errores
Toda respuesta de error usa el mismo formato, con el código HTTP correspondiente:
{
"error": {
"code": "BAD_CSRF",
"message": "Token CSRF inválido o ausente",
"details": null
}
}
| Código | HTTP | Cuándo |
|---|---|---|
UNSUPPORTED_MEDIA_TYPE | 415 | El cuerpo no es application/json |
BAD_CSRF | 403 | Falta o es inválido el token CSRF en una petición que modifica datos |
LICENSE_REQUIRED | 402 | El modo empresa necesita una licencia válida para este servidor (falta, venció, es de otra IP o fue revocada). Los conductores no se ven afectados |
NOT_FOUND | 404 | La ruta o el recurso no existe |
METHOD_NOT_ALLOWED | 405 | La ruta existe pero no con ese método |
INTERNAL | 500 | Error interno del servidor |
Autenticación
Cada ruta acepta uno de estos mecanismos, indicado en la columna Auth de las tablas:
Sesión (cookie)
Se inicia con POST /api/auth/login, que responde con el usuario y un csrf_token y guarda una cookie HttpOnly. Las peticiones que modifican datos (POST, PATCH, DELETE) deben enviar ese token en la cabecera X-CSRF-Token. Puedes recuperarlo con GET /api/auth/me.
POST /api/auth/login
Content-Type: application/json
{ "email": "conductor@ejemplo.com", "password": "********" }
→ 200
{ "user": { … }, "csrf_token": "…" }
Si la cuenta usa verificación en dos pasos, añade el campo totp con el código.
Token de instalación (Bearer)
El cliente de escritorio se identifica con un token de instalación, que empieza por ets2_ y se envía como Authorization: Bearer ets2_…. Opcionalmente puede enviar X-Client-Version. El token se crea desde la sesión con POST /api/integration/installations y solo se muestra en claro esa vez; caduca a los 90 días por defecto y puede rotarse o revocarse.
Rutas con «Sesión o instalación»
Aceptan ambos mecanismos: se usa el Bearer si se envía la cabecera Authorization, y si no, la cookie de sesión.
Límites de uso
El servidor limita las peticiones. Estos son los valores por defecto, ajustables en la configuración del servidor:
| Límite | Por defecto | Variable |
|---|---|---|
| Peticiones globales por minuto | 600 | RATE_GLOBAL_PER_MINUTE |
| Autenticación por minuto | 10 | RATE_AUTH_PER_MINUTE |
| Registros por hora | 10 | RATE_REGISTER_PER_HOUR |
| Telemetría por minuto (por instalación) | 240 | RATE_TELEMETRY_PER_MINUTE |
Algunas rutas tienen además su propio límite: por ejemplo, 10 instalaciones por hora, 30 invitaciones por hora, 30 envíos de mercado por minuto y 20 cambios de avatar por hora.
Estado del servidor
| Método | Ruta | Auth | Descripción |
|---|---|---|---|
GET | /api/health | Ninguna | Comprueba que el servidor responde. Devuelve { ok, service, time } |
GET | /api/version | Ninguna | Versión de la API, versión mínima del cliente, juegos habilitados y ruta del WebSocket |
GET | /api/meta/rates | Ninguna | Tipos de cambio desde el euro (60 peticiones por minuto) |
Marca y licencia
La marca (nombre, logotipo, textos y colores) y la licencia del modo empresa se leen y se cambian con estas rutas. Solo el dueño puede modificarlas.
| Método | Ruta | Auth | Descripción |
|---|---|---|---|
| GET | /api/brand | Ninguna | Marca actual: la usan la tablet y el cliente al arrancar |
| POST | /api/brand | Sesión (dueño) | Guarda la marca. El logotipo va como imagen en el propio cuerpo (con tamaño máximo) |
| POST | /api/brand/reset | Sesión (dueño) | Restablece la marca de fábrica |
| GET | /api/license | Ninguna | Estado de la licencia: state (ok, ausente, vencida, otra_ip, sin_verificar, revocada…), licenciatario y vencimiento |
| POST | /api/license | Sesión (dueño) | Instala el archivo de licencia (campo license, el texto del archivo). Verifica la firma y la IP del servidor |
Las rutas del modo empresa responden 402 LICENSE_REQUIRED mientras la licencia no esté ok. Cada pocas horas el servidor avisa a PHILIP Studio con su licencia, su versión y cuatro contadores (conductores, dueños, empresas y trabajos de 30 días); si la licencia fue revocada, el estado pasa a revocada. Mira Instalación.
Cuenta y sesión
| Método | Ruta | Auth | Descripción |
|---|---|---|---|
POST | /api/auth/register | Ninguna | Crea una cuenta |
POST | /api/auth/verify-email | Ninguna | Verifica el correo con el token recibido |
POST | /api/auth/resend-verification | Ninguna | Reenvía el correo de verificación |
POST | /api/auth/login | Ninguna | Inicia sesión. Cuerpo: email, password, totp (opcional) |
POST | /api/auth/logout | Sesión | Cierra la sesión |
GET | /api/auth/me | Sesión | Usuario actual y token CSRF |
POST | /api/auth/forgot-password | Ninguna | Solicita el correo de recuperación de contraseña |
POST | /api/auth/reset-password | Ninguna | Establece una contraseña nueva con el token de recuperación |
POST | /api/auth/change-password | Sesión | Cambia la contraseña |
PATCH | /api/auth/preferences | Sesión | Actualiza las preferencias del usuario |
POST | /api/me/avatar | Sesión | Sube la foto de perfil (campo image, máx. 512 KB) |
DELETE | /api/me/avatar | Sesión | Quita la foto de perfil |
Steam
| Método | Ruta | Auth | Descripción |
|---|---|---|---|
POST | /api/steam/connect | Sesión | Inicia el vínculo con Steam (inicio de sesión verificado) |
POST | /api/steam/link-id | Sesión | Vincula escribiendo el SteamID (sin verificar) |
GET | /api/steam/callback | Ninguna | Retorno del inicio de sesión de Steam |
GET | /api/steam/status | Sesión | Estado del vínculo, horas y perfil |
POST | /api/steam/sync | Sesión | Sincroniza los datos de Steam (6 cada 10 minutos) |
POST | /api/steam/disconnect | Sesión | Desvincula la cuenta de Steam |
Empresa
Estas rutas dependen del rol del usuario dentro de la empresa; el servidor responde con error si no tiene permiso. :id es el id de la empresa.
| Método | Ruta | Auth | Descripción |
|---|---|---|---|
GET | /api/companies | Sesión | Empresas a las que perteneces |
GET | /api/companies/:id | Sesión | Detalle de la empresa |
PATCH | /api/companies/:id | Sesión | Actualiza la empresa |
GET | /api/companies/:id/statistics | Sesión | Panel de estadísticas de la empresa |
GET | /api/companies/:id/live | Sesión | Conductores conectados en vivo |
GET | /api/companies/:id/drivers | Sesión | Lista de conductores |
GET | /api/companies/:id/drivers/:driverId | Sesión | Detalle de un conductor |
GET | /api/companies/:id/drivers/:driverId/trail | Sesión | Recorrido reciente de un conductor |
POST | /api/companies/:id/invitations | Sesión | Invita a un conductor (30 por hora) |
POST | /api/invitations/accept | Sesión | Acepta una invitación |
PATCH | /api/companies/:id/members/:memberId | Sesión | Cambia el rol o el estado de un miembro |
GET | /api/companies/:id/vehicles | Sesión | Lista de vehículos |
POST | /api/companies/:id/vehicles | Sesión | Crea un vehículo |
PATCH | /api/companies/:id/vehicles/:vid | Sesión | Actualiza un vehículo |
POST | /api/companies/:id/vehicles/:vid/maintenance | Sesión | Registra un mantenimiento |
GET | /api/companies/:id/jobs | Sesión | Trabajos de la empresa (filtro opcional status) |
GET | /api/companies/:id/finance | Sesión | Resumen financiero |
POST | /api/companies/:id/finance/adjustments | Sesión | Registra un ajuste financiero |
GET | /api/companies/:id/violations | Sesión | Multas (filtro status: PENDIENTE, PAGADA, ANULADA) |
PATCH | /api/companies/:id/violations/:vid | Sesión | Actualiza una multa |
GET | /api/companies/:id/incidents | Sesión | Accidentes |
GET | /api/companies/:id/fraud-alerts | Sesión | Alertas de coherencia (filtro status: abierta, revisada, descartada) |
PATCH | /api/companies/:id/fraud-alerts/:aid | Sesión | Cambia el estado de una alerta |
GET | /api/companies/:id/settings | Sesión | Política de realismo y ajustes de la empresa |
PATCH | /api/companies/:id/settings | Sesión | Actualiza los ajustes |
GET | /api/companies/:id/audit | Sesión | Registro de auditoría |
POST | /api/companies/:id/catalog/:kind | Sesión | Añade elementos al catálogo de la empresa |
Trabajos y despacho
| Método | Ruta | Auth | Descripción |
|---|---|---|---|
POST | /api/jobs | Sesión | Crea un trabajo |
GET | /api/jobs | Sesión | Lista de trabajos |
GET | /api/jobs/:id | Sesión | Detalle de un trabajo |
POST | /api/jobs/:id/offer | Sesión | Ofrece el trabajo a un conductor |
POST | /api/jobs/:id/accept | Sesión o instalación | El conductor acepta el trabajo |
POST | /api/jobs/:id/reject | Sesión o instalación | El conductor rechaza el trabajo |
POST | /api/jobs/:id/start | Sesión | Inicia el trabajo manualmente |
POST | /api/jobs/:id/complete | Sesión | Completa el trabajo |
POST | /api/jobs/:id/cancel | Sesión | Cancela el trabajo |
POST | /api/jobs/:id/resume | Sesión | Reanuda un trabajo |
GET | /api/dispatch/pending | Sesión o instalación | Despachos pendientes del conductor |
POST | /api/dispatch/:id/acknowledge | Sesión o instalación | Confirma que el despacho fue visto |
Conductor
| Método | Ruta | Auth | Descripción |
|---|---|---|---|
GET | /api/driver/me | Sesión o instalación | Perfil del conductor |
GET | /api/driver/jobs | Sesión o instalación | Trabajos del conductor (?scope=mine o ?scope=history) |
GET | /api/driver/jobs/:id | Sesión o instalación | Detalle de un trabajo del conductor |
PATCH | /api/driver/status | Sesión | Cambia el estado del conductor |
GET | /api/driver/stats | Sesión o instalación | Estadísticas del conductor |
GET | /api/driver/violations | Sesión o instalación | Multas del conductor |
GET | /api/driver/incidents | Sesión | Incidentes del conductor |
GET | /api/driver/fuel | Sesión | Consumo de combustible |
GET | /api/driver/vehicle | Sesión | Vehículo asignado |
GET | /api/driver/companies | Sesión o instalación | Empresas del conductor |
GET | /api/driver/hours | Sesión | Horas de conducción |
GET | /api/driver/game-profiles | Sesión | Perfiles del juego asociados a cada empresa |
POST | /api/driver/game-profiles | Sesión | Asocia un perfil del juego a una empresa |
Mercado de fletes
| Método | Ruta | Auth | Descripción |
|---|---|---|---|
POST | /api/driver/market | Instalación | El cliente sube las ofertas de la última partida guardada (máx. 1 MB, 30 por minuto) |
GET | /api/driver/market | Sesión | Ofertas del conductor, con filtros |
GET | /api/companies/:id/market/drivers | Sesión | Conductores que tienen mercado |
GET | /api/companies/:id/market | Sesión | Mercado de un conductor (?driver_id=) |
POST | /api/companies/:id/market/:offerId/dispatch | Sesión | Despacha una oferta del mercado a un conductor |
Filtros de GET /api/driver/market: q, origin, destination, cargo, group, body, adr, fragile, valuable, heavy, km_min, km_max, weight_min, weight_max, min_game_min, value_min, sort (value, expires, km, -km, weight, -weight, cargo) y limit.
Subir ofertas
POST /api/driver/market
Authorization: Bearer ets2_…
{
"game": "ets2",
"profile": "Mi perfil",
"save_name": "quicksave",
"game_time": 123456,
"saved_at": "2026-09-29T18:00:00Z",
"offers": [
{
"src_company": "…", "src_city": "…",
"dst_company": "…", "dst_city": "…",
"cargo": "…", "km": 412.5,
"expires_in_min": 300, "urgency": 1, "units": 1,
"truck": "…", "trailer": "…"
}
]
}
Solo src_company, src_city, dst_company, dst_city, cargo y km son obligatorios en cada oferta; el resto es opcional.
Billetera
| Método | Ruta | Auth | Descripción |
|---|---|---|---|
GET | /api/driver/wallet | Sesión | Saldo, facturas pendientes y movimientos del conductor |
POST | /api/driver/wallet/bills/:id/pay | Sesión | Paga una factura |
POST | /api/driver/wallet/pay-all | Sesión | Paga todas las facturas |
PATCH | /api/driver/wallet | Sesión | Activa o desactiva la billetera ({ "enabled": true }) |
GET | /api/companies/:id/wallets | Sesión | Billeteras de los conductores de la empresa |
GET | /api/companies/:id/wallet | Sesión | Billetera de la empresa |
POST | /api/companies/:id/wallet/bonus | Sesión | Envía una bonificación a un conductor |
POST | /api/companies/:id/wallet/cover | Sesión | La empresa paga facturas de conductores |
GET | /api/companies/:id/fuel | Sesión | Combustible de la flota |
Mensajes y notificaciones
| Método | Ruta | Auth | Descripción |
|---|---|---|---|
GET | /api/messages | Sesión | Mensajes recibidos |
POST | /api/messages/read-all | Sesión | Marca todos los mensajes como leídos |
POST | /api/messages/:id/read | Sesión | Marca un mensaje como leído |
GET | /api/notifications | Sesión | Notificaciones |
POST | /api/notifications/read-all | Sesión | Marca todas las notificaciones como leídas |
POST | /api/notifications/:id/read | Sesión | Marca una notificación como leída |
POST | /api/push/subscribe | Sesión | Suscribe el navegador a notificaciones push |
POST | /api/push/unsubscribe | Sesión | Cancela la suscripción push |
GET | /api/catalog/maps | Sesión | Catálogo de mapas |
GET | /api/catalog/:kind | Sesión | Catálogo por tipo |
Integración del cliente
| Método | Ruta | Auth | Descripción |
|---|---|---|---|
GET | /api/integration/status | Sesión | Estado de la integración del usuario |
GET | /api/integration/installations | Sesión | Instalaciones (equipos vinculados) |
POST | /api/integration/installations | Sesión | Crea una instalación. Cuerpo: { "name": "…" } (2 a 60 caracteres). Devuelve el token una sola vez |
DELETE | /api/integration/installations/:id | Sesión | Revoca una instalación |
POST | /api/integration/installations/:id/rotate | Sesión | Genera un token nuevo y anula el anterior |
Telemetría
El cliente de escritorio abre una sesión de telemetría por cada partida y le envía eventos. Todas estas rutas usan el token de instalación.
| Método | Ruta | Auth | Descripción |
|---|---|---|---|
POST | /api/telemetry/session | Instalación | Abre una sesión y devuelve su session_id |
POST | /api/telemetry/events | Instalación | Envía un lote de eventos (máx. 1000 y 512 KB) |
POST | /api/telemetry/heartbeat | Instalación | Marca que el cliente sigue conectado |
POST | /api/telemetry/end | Instalación | Cierra la sesión |
Abrir una sesión
POST /api/telemetry/session
Authorization: Bearer ets2_…
{
"api_version": "1.0",
"client_version": "2.0.0",
"game": { "name": "ets2", "version": "1.55" },
"plugin": { "name": "…", "version": "…" },
"environment": {
"profile": "Mi perfil",
"mods": [ { "name": "…", "package": "…" } ]
}
}
game.name puede ser ets2 o ats. plugin y environment son opcionales.
Enviar eventos
POST /api/telemetry/events
Authorization: Bearer ets2_…
{
"session_id": 42,
"seq": 1,
"events": [
{ "t": "2026-09-29T18:00:05Z", "type": "sample", "data": { … } }
]
}
| Tipo de evento | Cuándo se envía |
|---|---|
sample | Lectura periódica del estado del camión |
job_context | Contexto del trabajo actual |
job_delivered | Entrega completada |
job_cancelled | Trabajo cancelado |
fined | Multa |
refuel | Repostaje |
transport | Transporte en ferry o tren |
tollgate | Peaje |
profile | Cambio de perfil del juego |
Latido y cierre
POST /api/telemetry/heartbeat
{ "session_id": 42, "rtt_ms": 80, "state": { "game_connected": true, "telemetry_active": true } }
POST /api/telemetry/end
{ "session_id": 42 }
