Reporte de Rendimiento de Personas
Productividad por persona durante un período: tareas, ocupación, tiempo trabajado vs. descansado, kilómetros y desplazamiento basado en GPS.
GET
/apidev/v1/reports/cpm/personnel-performancePermisoAPICLI_RPTCPM_RENDIMIENTOPERSONAS
Límite de solicitudes10 req/min
Caché300s
Rango máximo31 días
Resumen
Devuelve una fila por persona (o por persona y día) durante el período seleccionado, agregando las tareas atendidas, el tiempo en tarea, las horas trabajadas y descansadas, los kilómetros recorridos y las métricas de desplazamiento derivadas de GPS. Úsalo para medir la ocupación, la utilización y la carga de trabajo de tu personal de campo.
- Agrupación —
grouping=personconsolida todo el rango en una fila por persona;grouping=person_daydevuelve una fila por persona por día - Día en curso —
include_today=truefusiona el día en progreso (aún no cerrado) como una estimación en vivo aproximada - Filtros de alcance — acotá los resultados por persona, dispositivo, tipo de dispositivo o categoría de turno
- Ambigüedad de GPS — cuando un vehículo se comparte el mismo día, los campos derivados de GPS (circulación, velocidad promedio, combustible) se devuelven como
nullen lugar de un valor engañoso
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 de inicio en ISO 8601 (ej. 2026-03-01). |
enddate | string | Sí | — | Fecha de fin en ISO 8601. Rango máximo 31 días desde startdate. |
grouping | string | No | person | Nivel de agregación: person o person_day. |
persons | string | No | Todos los visibles | IDs de persona separados por coma. Máximo 500. |
devices | string | No | Todos los visibles | IDs de dispositivo separados por coma. Máximo 500. |
device_types | string | No | — | IDs de tipo de dispositivo separados por coma. Máximo 100. |
shift_categories | string | No | — | IDs de categoría de turno separados por coma. Máximo 50. |
include_today | boolean | No | true | Fusiona el día en progreso como una estimación en vivo aproximada. |
sort_by | string | No | — | Campo por el que ordenar (validado contra una lista permitida). |
sort_dir | string | No | asc | Dirección de orden: asc o desc. |
limit | integer | No | 25 | Cantidad de registros por página (1–100). |
offset | integer | No | 0 | Cantidad de registros a omitir para la paginación. |
Ejemplos de código
- cURL
- JavaScript
- Python
curl -s -H "Authorization: Bearer $TOKEN" \
-H "X-API-Key: $APIKEY" \
-H "tenant: $TENANT" \
"https://$TENANT/apidev/v1/reports/cpm/personnel-performance?startdate=2026-03-01&enddate=2026-03-15&grouping=person&limit=25"
const res = await fetch(
`https://${TENANT}/apidev/v1/reports/cpm/personnel-performance?startdate=2026-03-01&enddate=2026-03-15&grouping=person&limit=25`,
{
headers: {
'Authorization': `Bearer ${token}`,
'X-API-Key': apiKey,
'tenant': TENANT,
},
}
);
const data = await res.json();
import requests
response = requests.get(
f"https://{TENANT}/apidev/v1/reports/cpm/personnel-performance",
headers={"Authorization": f"Bearer {token}", "X-API-Key": api_key, "tenant": TENANT},
params={"startdate": "2026-03-01", "enddate": "2026-03-15", "grouping": "person", "limit": 25},
)
data = response.json()
Respuesta
Campos de la respuesta
| Campo | Tipo | Descripción |
|---|---|---|
person_id | string | Identificador de la persona. |
person_name | string | Nombre de la persona. |
day | string | null | Día (YYYY-MM-DD); presente solo cuando grouping=person_day. |
day_start | string | null | Primer inicio de turno del día/rango. |
day_end | string | null | Último fin de turno del día/rango. |
shifts_count | number | Cantidad de turnos. |
vehicles_count | number | Vehículos distintos utilizados (rotación). |
total_tasks | number | Total de tareas atendidas. |
scheduled_tasks | number | Tareas programadas. |
unscheduled_tasks | number | Tareas no programadas. |
shift_minutes | number | Tiempo bruto de turno en minutos. |
worked_minutes | number | Tiempo neto trabajado (turno menos descanso). |
task_busy_minutes | number | Tiempo neto en tarea. |
occupancy_pct | number | null | Tiempo ocupado como porcentaje del tiempo neto trabajado (limitado a 100). |
shift_kms | number | Kilómetros durante el turno. |
rest_minutes | number | Tiempo total de descanso en minutos. |
rests_count | number | Cantidad de períodos de descanso. |
gps_ambiguous | boolean | true cuando el vehículo se compartió; los campos derivados de GPS quedan en null. |
circulating_minutes | number | null | Minutos en movimiento (null si el GPS es ambiguo). |
trips_total | number | Cantidad de viajes. |
trips_kms | number | Kilómetros a lo largo de los viajes. |
max_speed | number | null | Velocidad máxima en km/h (null si el GPS es ambiguo). |
avg_speed | number | null | Velocidad promedio en km/h (null si el GPS es ambiguo). |
estimated_fuel_liters | number | null | Consumo estimado de combustible en litros (null si el GPS es ambiguo). |
utilization_pct | number | null | Tiempo de circulación como porcentaje del tiempo de motor activo (null si el GPS es ambiguo). |
tasks_per_hour | number | null | Tareas completadas por hora. |
idle_minutes | number | Tiempo muerto (ralentí) en minutos. |
status | string | null | Estado del turno: OK, WARN o ERROR. |
closed | boolean | false cuando el día aún está en progreso (estimación en vivo). |
Ejemplo de respuesta
{
"success": true,
"data": [
{
"person_id": "982710394857201700",
"person_name": "Carlos Martinez",
"day": null,
"day_start": "2026-03-01T07:00:00",
"day_end": "2026-03-15T15:30:00",
"shifts_count": 11,
"vehicles_count": 2,
"total_tasks": 84,
"scheduled_tasks": 70,
"unscheduled_tasks": 14,
"shift_minutes": 5280,
"worked_minutes": 4960,
"task_busy_minutes": 3820,
"occupancy_pct": 77.0,
"shift_kms": 1620.4,
"rest_minutes": 320,
"rests_count": 18,
"gps_ambiguous": false,
"circulating_minutes": 2740,
"trips_total": 96,
"trips_kms": 1598.2,
"max_speed": 92.0,
"avg_speed": 41.5,
"estimated_fuel_liters": 214.7,
"utilization_pct": 68.0,
"tasks_per_hour": 1.0,
"idle_minutes": 410,
"status": "OK",
"closed": true
},
{
"person_id": "982710394857201701",
"person_name": "Laura Hernandez",
"day": null,
"day_start": "2026-03-02T08:00:00",
"day_end": "2026-03-14T18:00:00",
"shifts_count": 9,
"vehicles_count": 1,
"total_tasks": 61,
"scheduled_tasks": 52,
"unscheduled_tasks": 9,
"shift_minutes": 4320,
"worked_minutes": 4080,
"task_busy_minutes": 2610,
"occupancy_pct": 64.0,
"shift_kms": 980.1,
"rest_minutes": 240,
"rests_count": 11,
"gps_ambiguous": true,
"circulating_minutes": null,
"trips_total": 0,
"trips_kms": 0,
"max_speed": null,
"avg_speed": null,
"estimated_fuel_liters": null,
"utilization_pct": null,
"tasks_per_hour": 0.9,
"idle_minutes": 360,
"status": "WARN",
"closed": true
}
],
"meta": {
"total": 2,
"limit": 25,
"offset": 0
}
}
Errores
| Código | HTTP | Descripción |
|---|---|---|
VALIDATION_ERROR | 400 | Parámetros inválidos (ej. el rango de fechas supera los 31 días). |
UNAUTHORIZED | 401 | tenant / Authorization / X-API-Key faltante, inválido o expirado |
FORBIDDEN | 403 | El usuario carece del permiso requerido. |
RATE_LIMITED | 429 | Se superaron las 10 req/min. |
INTERNAL_ERROR | 500 | Error inesperado del servidor. |