Reporte de Kilómetros
Distancia recorrida, consumo de combustible y métricas de costo de tu flota durante un período determinado.
/apidev/v1/reports/avl/kilometersResumen
Proporciona datos de distancia y consumo para cada vehículo de tu flota. Úsalo para auditar el kilometraje, estimar costos de combustible y hacer seguimiento de las emisiones de CO₂.
- Desglose diario —
perday=truedevuelve una fila por vehículo por día - Agrupación por conductor —
perperson=truesegmenta los resultados por el conductor asignado - Subdivisión geográfica —
groupbygeodivide los totales por estado, ciudad o barrio - Subtotales —
subtotals=trueincluye filas de resumen
Solicitud
Encabezados de la solicitud
Every request to a protected endpoint requires these headers:
| Header | Required | Description |
|---|---|---|
Authorization | Yes | Bearer token obtained from the Login endpoint. Format: Bearer <token> |
X-API-Key | Yes | Company integration key provided during onboarding. Format: gtk_xxx... |
tenant | Yes | Your assigned tenant domain (default: geotareas.com) — always send your assigned tenant |
Content-Type | Conditional | application/json — required for POST and PUT requests |
Parámetros de consulta
| Parámetro | Tipo | Requerido | Predeterminado | Descripción |
|---|---|---|---|---|
startdate | string | Sí | — | Fecha-hora de inicio en ISO 8601 (ej. 2026-03-01T00:00:00) |
enddate | string | Sí | — | Fecha-hora de fin en ISO 8601. Rango máximo 31 días desde startdate |
devices | string | No | Todos los visibles | IDs de dispositivo separados por coma. Máximo 500 |
limit | integer | No | 25 | Registros por página (1–100) |
offset | integer | No | 0 | Registros a omitir |
perday | boolean | No | false | Agrupa los resultados por día |
perperson | boolean | No | false | Agrupa los resultados por conductor asignado |
subtotals | boolean | No | false | Incluye filas de subtotal |
groupbygeo | enum | No | — | Subdivide por área: state, city o neighbourhood |
subtotals=true cambia el comportamiento de limitLas filas de subtotal y de total general se agregan después de haber cortado la página, y recién ahí el resultado se recorta a limit. O sea que con subtotals=true la respuesta sigue trayendo como máximo limit filas, pero parte de ese cupo se va en filas de resumen — vas a recibir menos filas de detalle que en una página normal del mismo tamaño.
Las filas de resumen no vienen marcadas en la respuesta. La única forma de reconocerlas es por device_name: un subtotal por móvil dice "<nombre del móvil> (subtotal)" y el total general dice "Total general". Si estás sumando los datos por tu cuenta, filtrá esas filas o vas a contar dos veces.
meta.total cuenta siempre solo las filas de detalle. Para paginar limpio, dejá subtotals apagado y calculá tus propios totales.
Cuando se omite devices, el reporte incluye todos los dispositivos visibles para el usuario autenticado según su alcance de permisos.
Ejemplos de código
- cURL
- JavaScript
- Python
curl -s "https://$TENANT/apidev/v1/reports/avl/kilometers?startdate=2026-03-01T00:00:00&enddate=2026-03-15T23:59:59&limit=50&perday=true" \
-H "Authorization: Bearer $TOKEN" \
-H "X-API-Key: $APIKEY" \
-H "tenant: $TENANT"
const params = new URLSearchParams({
startdate: "2026-03-01T00:00:00",
enddate: "2026-03-15T23:59:59",
limit: "50",
perday: "true",
});
const response = await fetch(
`https://${TENANT}/apidev/v1/reports/avl/kilometers?${params}`,
{ headers }
);
const { data, meta } = await response.json();
console.log(`${data.length} rows of ${meta.total}`);
response = requests.get(
f"https://{TENANT}/apidev/v1/reports/avl/kilometers",
headers=headers,
params={
"startdate": "2026-03-01T00:00:00",
"enddate": "2026-03-15T23:59:59",
"limit": 50,
"perday": True,
},
)
result = response.json()
for row in result["data"]:
print(f"{row['device_name']}: {row['kms']} km — {row['fuel']} L")
Campos de la respuesta
| Campo | Tipo | Descripción |
|---|---|---|
device_name | string | Nombre visible del vehículo/dispositivo |
person_name | string | Nombre del conductor asignado (solo se completa con perperson=true) |
datetime | string | null | Fecha del registro (YYYY-MM-DD, solo se completa con perday=true) |
kms | number | Total de kilómetros recorridos |
fuel | number | Combustible consumido estimado (litros) |
cost | number | Costo de combustible estimado (moneda según configuración del vehículo) |
co2 | number | Emisiones de CO₂ estimadas (kg) |
temperature | number | Lectura promedio del sensor de temperatura 1. 0 si el vehículo no tiene sensor |
state | string | Nombre del departamento. Solo aparece cuando groupbygeo es state, city o neighbourhood |
city | string | Nombre de la ciudad. Solo aparece cuando groupbygeo es city o neighbourhood |
neighbourhood | string | Nombre del barrio. Solo aparece cuando groupbygeo=neighbourhood |
state, city y neighbourhood se agregan a cada fila solo si pedís agrupación geográfica, y se van acumulando a medida que bajás de nivel:
groupbygeo | Campos que se agregan a cada fila |
|---|---|
| (sin enviar) | ninguno |
state | state |
city | state, city |
neighbourhood | state, city, neighbourhood |
Cuando un campo no se agrega, la clave no está en el objeto — "city" in fila da false. No llega como cadena vacía, así que no la leas sin verificar antes.
device_name, person_name y datetime funcionan al revés: la clave siempre está, y lo que deciden perperson / perday es si trae valor o no.
fuel, cost y co2 se calculan usando la tasa de consumo de combustible y el precio de combustible configurados en los ajustes de cada vehículo. Si no están configurados, estos campos devuelven 0.
Ejemplo de respuesta
{
"success": true,
"data": [
{
"device_name": "Truck A-101",
"person_name": "",
"datetime": "2026-03-01",
"kms": 267.7,
"fuel": 32.12,
"cost": 48.18,
"co2": 83.54,
"temperature": 22.3
},
{
"device_name": "Van B-205",
"person_name": "",
"datetime": "2026-03-01",
"kms": 142.3,
"fuel": 11.38,
"cost": 17.07,
"co2": 29.57,
"temperature": 4.1
}
],
"meta": {
"total": 84,
"limit": 50,
"offset": 0
}
}
Con perperson=true
Cuando la agrupación por conductor está habilitada, person_name se completa y pueden aparecer varias filas para el mismo dispositivo si los conductores cambiaron durante el período:
{
"device_name": "Truck A-101",
"person_name": "Carlos Martinez",
"datetime": "2026-03-01",
"kms": 180.5,
"fuel": 21.66,
"cost": 32.49,
"co2": 56.32,
"temperature": 22.3
}
Con groupbygeo=state
La agrupación geográfica agrega los niveles hasta el que pediste. Con state, la fila suma state — y ninguna clave city ni neighbourhood:
{
"device_name": "Truck A-101",
"person_name": "",
"datetime": null,
"kms": 180.5,
"fuel": 21.66,
"cost": 32.49,
"co2": 56.32,
"temperature": 0,
"state": "Montevideo"
}
Con groupbygeo=neighbourhood
El nivel más profundo trae las tres claves juntas, una fila por barrio recorrido:
{
"device_name": "Truck A-101",
"person_name": "",
"datetime": null,
"kms": 42.8,
"fuel": 5.14,
"cost": 7.71,
"co2": 13.36,
"temperature": 0,
"state": "Montevideo",
"city": "Montevideo",
"neighbourhood": "Pocitos"
}
Errores
| Código | HTTP | Descripción |
|---|---|---|
INVALID_DATE_RANGE | 400 | El rango de fechas supera el máximo de 31 días, el fin es anterior al inicio, o fechas no ISO |
VALIDATION_ERROR | 400 | Parámetros inválidos: faltan fechas, limit > 100, > 500 dispositivos |
UNAUTHORIZED | 401 | tenant / Authorization / X-API-Key faltante, inválido o expirado |
FORBIDDEN | 403 | El usuario carece del permiso APICLI_RPTAVL_KILOMETROS |
RATE_LIMITED | 429 | Se superaron las 10 req/min |
INTERNAL_ERROR | 500 | Error inesperado del servidor |
Relacionado
- Límites de solicitudes — Detalles de la ventana deslizante
- Paginación — Parámetros de paginación estándar
- API de Dispositivos — Obtené IDs de dispositivo para filtrar reportes