Skip to main content

Personnel Performance Report

Per-person productivity over a period: tasks, occupancy, worked vs. rested time, kilometers, and GPS-based travel.

GET/apidev/v1/reports/cpm/personnel-performance
PermissionAPICLI_RPTCPM_RENDIMIENTOPERSONAS
Rate Limit10 req/min
Cache300s
Max Range31 days

Overview​

Returns one row per person (or per person and day) over the selected period, aggregating tasks handled, time on task, worked and rested hours, kilometers driven, and GPS-derived travel metrics. Use it to measure occupancy, utilization, and workload across your field staff.

  • Grouping — group_by=persona rolls up the whole range into one row per person; group_by=persona_dia returns one row per person per day
  • Live day — include_today=true merges the in-progress (not-yet-closed) day as an approximate live estimate
  • Scope filters — narrow results by person, device, device type, or shift category
  • GPS ambiguity — when a vehicle is shared on the same day, GPS-derived fields (circulating, average speed, fuel) are returned as null instead of a misleading value

Request​

Request Headers​

Every request to a protected endpoint requires these headers:

HeaderRequiredDescription
AuthorizationYesBearer token obtained from the Login endpoint. Format: Bearer <token>
X-API-KeyYesCompany integration key provided during onboarding. Format: gtk_xxx...
tenantYesYour assigned tenant domain (default: geotareas.com) — always send your assigned tenant
Content-TypeConditionalapplication/json — required for POST and PUT requests

Query Parameters​

ParameterTypeRequiredDefaultDescription
startdatestringYes—ISO 8601 start date (e.g. 2026-03-01).
enddatestringYes—ISO 8601 end date. Max range 31 days from startdate.
group_bystringNopersonaAggregation level: persona or persona_dia.
driversstringNoAll visibleComma-separated person IDs. Max 500.
devicesstringNoAll visibleComma-separated device IDs. Max 500.
device_typesstringNo—Comma-separated device type IDs. Max 100.
shift_categoriesstringNo—Comma-separated shift category IDs. Max 50.
include_todaybooleanNotrueMerge the in-progress day as an approximate live estimate.
limitintegerNo25Number of records per page (1–100).
offsetintegerNo0Number of records to skip for pagination.

Code Examples​

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&group_by=persona&limit=25"

Response​

Response Fields​

FieldTypeDescription
person_idstring | nullPerson identifier.
person_namestring | nullPerson name.
daystring | nullDay (YYYY-MM-DD); present only when group_by=persona_dia.
day_startstring | nullFirst shift start of the day/range.
day_endstring | nullLast shift end of the day/range.
shifts_countnumber | nullNumber of shifts.
vehicles_countnumber | nullDistinct vehicles used (rotation). Only computed per day: null when group_by=persona.
total_tasksnumberTotal tasks handled.
scheduled_tasksnumberScheduled tasks.
unscheduled_tasksnumberUnscheduled tasks.
shift_minutesnumberGross shift time in minutes.
worked_minutesnumberNet worked time (shift minus rest).
task_busy_minutesnumberNet time on task.
occupancy_pctnumber | nullBusy time as a percentage of net worked time (capped at 100).
shift_kmsnumberKilometers during the shift.
rest_minutesnumberTotal rest time in minutes.
rests_countnumberNumber of rest periods.
gps_ambiguousbooleantrue when the vehicle was shared; GPS-derived fields are then null.
circulating_minutesnumber | nullMinutes in motion (null if GPS ambiguous).
trips_totalnumberNumber of trips.
trips_kmsnumberKilometers across trips.
max_speednumber | nullMaximum speed in km/h (null if GPS ambiguous).
avg_speednumber | nullAverage speed in km/h (null if GPS ambiguous).
estimated_fuel_litersnumber | nullEstimated fuel consumption in liters (null if GPS ambiguous).
utilization_pctnumber | nullCirculating time as a percentage of active engine time (null if GPS ambiguous).
tasks_per_hournumber | nullTasks completed per hour.
idle_minutesnumberStopped with the engine running, inside the shift (idle/waiting), in minutes.
idle_countnumberNumber of engine-on stops inside the shift.
engine_off_rest_minutesnumberRest inside the shift (engine off and no task), in minutes.
engine_off_rest_countnumberNumber of rests inside the shift (engine off, no task).
engine_off_rest_max_minutesnumberLongest single rest (engine off, no task), in minutes.
off_shift_engine_off_minutesnumber | nullEngine off outside the shift, in minutes. null when the vehicle was shared.
off_shift_engine_off_countnumber | nullNumber of engine-off stops outside the shift. null when the vehicle was shared.
statusstring | nullShift status: OK, WARN, or ERROR.
closedbooleanfalse when the day is still in progress (live estimate).

Example Response​

{
"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": null,
"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,
"idle_count": 32,
"engine_off_rest_minutes": 260,
"engine_off_rest_count": 14,
"engine_off_rest_max_minutes": 48,
"off_shift_engine_off_minutes": 120,
"off_shift_engine_off_count": 3,
"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": null,
"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,
"idle_count": 27,
"engine_off_rest_minutes": 190,
"engine_off_rest_count": 9,
"engine_off_rest_max_minutes": 41,
"off_shift_engine_off_minutes": null,
"off_shift_engine_off_count": null,
"status": "WARN",
"closed": true
}
],
"meta": {
"total": 2,
"limit": 25,
"offset": 0
}
}

Errors​

CodeHTTPDescription
VALIDATION_ERROR400Invalid parameters (e.g. date range exceeds 31 days).
UNAUTHORIZED401Missing, invalid, or expired tenant / Authorization / X-API-Key
FORBIDDEN403User lacks required permission.
RATE_LIMITED429Exceeded 10 req/min.
INTERNAL_ERROR500Unexpected server error.