Saltar al contenido principal

Mensajería y Cercanos

Enviá un mensaje de texto libre a la app del móvil que corre en un vehículo, y encontrá los móviles más cercanos a un punto dado — útil para asignar la unidad más próxima a un trabajo.

Requisitos previos

Todos los endpoints requieren un token JWT válido, una clave de API y el encabezado tenant. Consultá Autenticación.


Enviar mensaje

Encola un mensaje de texto libre a la app del móvil de un único vehículo. Es sin garantía de entrega (fire-and-forget): una respuesta exitosa significa que el mensaje se encoló, no que se entregó ni que se leyó. La app del móvil lo recoge la próxima vez que consulta sus mensajes.

POST/apidev/v1/devices/{vehicle_id}/messages
PermisoAPICLI_DEVICE_MESSAGE
Límite de solicitudes20 solicitudes/min (ventana deslizante)
CachéNinguna

Parámetros de ruta

ParámetroTipoRequeridoDescripción
vehicle_idstringIdentificador único del vehículo (móvil). Debe pertenecer a tu tenant.

Cuerpo de la solicitud

CampoTipoRequeridoLongitud máximaDescripción
textstring500Mensaje a enviar al móvil. No puede estar vacío.
pushbooleanNoDisparar una notificación push (por defecto true).
Indicador push

Hoy cada mensaje encolado también dispara una notificación push, por lo que push: false se acepta pero todavía no se respeta. Enviá true (u omitilo) para no depender de ese cambio futuro.

Campos de la respuesta

CampoTipoDescripción
message_idstringIdentificador del mensaje encolado (BigInt como string). Puede omitirse si la cola no devolvió uno.
vehicle_idstringEco del identificador del móvil destino.
deliverystringSiempre "queued" — el mensaje fue aceptado en la cola de entrega. Encolado no es lo mismo que entregado ni leído.

Ejemplo de código

curl -s -X POST "https://$TENANT/apidev/v1/devices/1013/messages" \
-H "Authorization: Bearer $TOKEN" \
-H "X-API-Key: $APIKEY" \
-H "tenant: $TENANT" \
-H "Content-Type: application/json" \
-d '{
"text": "Head back to base, end of shift."
}'

Respuesta de ejemplo

{
"success": true,
"data": {
"message_id": "8472910",
"vehicle_id": "1013",
"delivery": "queued"
},
"meta": {}
}
Móvil sin dispositivo

Si el vehículo no tiene un dispositivo activo que pueda recibir mensajes (sin IMEI activo), la solicitud falla con 409 CONFLICT. Esto es distinto de 404, que significa que el vehículo no existe en tu tenant. Asociá un dispositivo activo al móvil antes de enviarle mensajes.


Móviles cercanos

Encontrá los móviles más cercanos a un punto, ordenados por distancia. La búsqueda está acotada por un radio (hasta 50 km) y se puede afinar por la antigüedad del GPS, la validez del GPS y el tipo de vehículo.

POST/apidev/v1/devices/nearby
PermisoAPICLI_FLEET_DEVICES_READ
Límite de solicitudes20 solicitudes/min (ventana deslizante)
CachéNinguna
Por qué POST para una lectura

Conceptualmente es una lectura, pero lleva un cuerpo estructurado (un punto más filtros) que no entra prolijo en parámetros de consulta, y realiza un cálculo de distancia. Sigue la misma convención que los endpoints de reportes, que también aceptan un cuerpo POST.

Cuerpo de la solicitud

CampoTipoRequeridoPor defectoDescripción
pointobjectCentro de la búsqueda: { "lat": number, "lng": number }. lat en [-90, 90], lng en [-180, 180].
radius_mnumberRadio de búsqueda en metros. Mín 1, máx 50000 (50 km).
limitnumberNo20Cantidad máxima de resultados. Mín 1, máx 100.
only_valid_gpsbooleanNotrueSolo móviles cuyo último GPS sea válido (coordenadas presentes, posición válida).
max_age_minnumberNoDescarta móviles cuyo último GPS sea más viejo que N minutos. Mín 1, máx 1440. Si se omite, no se aplica límite de antigüedad.
vehicle_typesstring[]NoFiltra por identificadores de tipo de vehículo (BigInt como strings). Hasta 100 valores.

Campos de la respuesta

El campo data es un arreglo de móviles cercanos, ordenados por distancia ascendente.

CampoTipoDescripción
vehicle_idstringIdentificador del vehículo (móvil) (BigInt como string).
namestringNombre para mostrar del móvil.
platestringPatente.
vehicle_type_idstring | nullIdentificador del tipo de vehículo (BigInt como string).
pointobjectÚltimo punto GPS: { "lat": number, "lng": number }.
distance_mnumberDistancia al point solicitado, en metros (redondeada).
headingnumber | nullRumbo en grados (0–359), o null cuando no está disponible.
speednumberVelocidad en km/h del último punto GPS.
last_signalstring | nullMarca de tiempo del último GPS válido (sin zona horaria).
valid_gpsbooleanSi el último GPS es válido.
Rumbo y marcas de tiempo

heading es null cuando no hay rumbo disponible — nunca 0, que significaría "norte exacto". last_signal se devuelve sin zona horaria (p. ej., "2026-06-25T14:58:00") y representa la zona horaria configurada de la compañía; mostralo tal cual, sin agregar Z ni convertir a UTC.

Ejemplo de código

curl -s -X POST "https://$TENANT/apidev/v1/devices/nearby" \
-H "Authorization: Bearer $TOKEN" \
-H "X-API-Key: $APIKEY" \
-H "tenant: $TENANT" \
-H "Content-Type: application/json" \
-d '{
"point": { "lat": -34.9050, "lng": -56.1910 },
"radius_m": 5000,
"limit": 10,
"only_valid_gps": true,
"max_age_min": 30,
"vehicle_types": ["5"]
}'

Respuesta de ejemplo

{
"success": true,
"data": [
{
"vehicle_id": "1013",
"name": "Grua 07",
"plate": "ABC 1234",
"vehicle_type_id": "5",
"point": { "lat": -34.9012, "lng": -56.1888 },
"distance_m": 342,
"heading": 270,
"speed": 0,
"last_signal": "2026-06-25T14:58:00",
"valid_gps": true
},
{
"vehicle_id": "1021",
"name": "Grua 12",
"plate": "DEF 5678",
"vehicle_type_id": "5",
"point": { "lat": -34.9100, "lng": -56.1950 },
"distance_m": 820,
"heading": 135,
"speed": 34,
"last_signal": "2026-06-25T14:59:30",
"valid_gps": true
}
],
"meta": {
"total": 2,
"limit": 10
}
}
Sin resultados no es un error

Si ningún móvil cae dentro del radio — o todos quedan filtrados por only_valid_gps, max_age_min o las reglas de visibilidad — la respuesta es 200 con un arreglo data vacío. Cada móvil también está sujeto a las reglas de visibilidad de tu usuario técnico, por lo que solo ves los móviles que ese usuario tiene permitido ver.

Tope de radio

El radio máximo es 50 km. Un radius_m mayor se rechaza con 400 en lugar de acotarse en silencio, para evitar un barrido accidental de toda la flota.


Errores

Consultá Manejo de errores para la referencia completa.

CódigoHTTPAplica aDescripción
VALIDATION_ERROR400Enviar mensaje, Cercanostext vacío; o point fuera de rango, radius_m ausente o mayor a 50000, limit mayor a 100.
UNAUTHORIZED401Todostenant / Authorization / X-API-Key ausente, inválido o expirado.
FORBIDDEN403TodosEl usuario no tiene APICLI_DEVICE_MESSAGE (Enviar mensaje) o APICLI_FLEET_DEVICES_READ (Cercanos).
NOT_FOUND404Enviar mensajeEl vehicle_id no existe o no pertenece a tu tenant.
CONFLICT409Enviar mensajeEl móvil no tiene un dispositivo activo que pueda recibir mensajes (sin IMEI activo).
RATE_LIMITED429TodosSe superaron 20 solicitudes/min.
INTERNAL_ERROR500TodosError inesperado del servidor.