Skip to main content

Productivity Report

Task productivity metrics per vehicle/driver — task counts, hours, kilometers, and occupancy.

GET/apidev/v1/reports/gt/productivity
PermissionAPICLI_RPTGT_PRODUCTIVIDAD
Rate Limit10 req/min
Cache300s
Max Range31 days

Overview​

Returns productivity metrics aggregated per vehicle or driver over a date range — task counts (scheduled, unscheduled, total), task and shift hours, kilometers (worked, ideal, shift), average arrival time, and occupancy rate. Use group_by_person=true to aggregate by driver instead of device, and narrow results with device, driver, device type, or service type filters.

Three metrics are currently unreliable

task_hours, shift_hours and avg_arrival_time come back as null whenever they carry a real value, and as 0 when the metric is genuinely zero. Read Response Fields before you build on them.


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-time (e.g. 2026-03-01T00:00:00).
enddatestringYes—ISO 8601 end date-time. Max range 31 days from startdate.
devicesstringNo—Comma-separated device IDs. Max 500.
driversstringNo—Comma-separated driver IDs. Max 500.
device_groupsstringNo—Comma-separated device type IDs (the device_group catalog from Fleet / Devices). Max 100.
service_typesstringNo—Comma-separated service type IDs. Max 100.
group_by_personbooleanNofalseGroup results by driver instead of device.
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/gt/productivity?startdate=2026-03-01T00:00:00&enddate=2026-03-15T23:59:59&limit=25"

Response​

Response Fields​

Every field below is always present as a key. What changes between rows is whether it carries a value — see the two notes that follow the table.

FieldTypeDescription
service_typestringService type name. Currently always an empty string — see the note below.
driver_namestringDriver name. Populated only when group_by_person=true; empty string otherwise.
device_namestringVehicle name. Populated only when group_by_person=false (the default); empty string otherwise.
unscheduled_tasksnumberCount of unscheduled tasks.
scheduled_tasksnumberCount of scheduled tasks.
total_tasksnumberTotal task count.
task_hoursnumber | nullTime spent on tasks. Arrives null whenever the value is not zero — see the note below.
shift_hoursnumber | nullTotal shift time. Arrives null whenever the value is not zero — see the note below.
kms_workednumberKilometers during tasks.
kms_idealnumberIdeal/planned kilometers (the routed distance).
kms_shiftnumberTotal shift kilometers.
avg_arrival_timenumber | nullAverage arrival time for unscheduled tasks. Arrives null whenever the value is not zero — see the note below.
occupancynumberOccupancy rate percentage (task time over shift time).
task_hours, shift_hours and avg_arrival_time are not usable yet

These three metrics are the only nullable fields on this report, and their null does not mean "no data". The pattern is inverted:

  • the metric is zero → you get 0
  • the metric has any real value → you get null

So a row that did have working hours reports null, while an idle row reports 0. Do not treat null as an empty shift, and do not sum these three fields — the totals would be wrong in both directions.

Until this is fixed, derive what you need from the fields that are reliable: occupancy already expresses task time over shift time as a percentage, and total_tasks / kms_worked / kms_shift carry real numbers.

service_type is always empty

The underlying report groups by vehicle or by driver only, so it never carries the service type name — the field is present for shape compatibility but reads "" on every row. Filtering by service_types does work (it narrows which tasks are counted); it is only the label that does not travel back.

Example Response​

Default mode (group_by_person omitted), showing what production actually returns today:

{
"success": true,
"data": [
{
"service_type": "",
"driver_name": "",
"device_name": "Truck A-101",
"unscheduled_tasks": 3,
"scheduled_tasks": 12,
"total_tasks": 15,
"task_hours": null,
"shift_hours": null,
"kms_worked": 142.3,
"kms_ideal": 135.0,
"kms_shift": 180.0,
"avg_arrival_time": null,
"occupancy": 81
},
{
"service_type": "",
"driver_name": "",
"device_name": "Van B-205",
"unscheduled_tasks": 0,
"scheduled_tasks": 0,
"total_tasks": 0,
"task_hours": 0,
"shift_hours": 0,
"kms_worked": 0,
"kms_ideal": 0,
"kms_shift": 0,
"avg_arrival_time": 0,
"occupancy": 0
}
],
"meta": {
"total": 2,
"limit": 25,
"offset": 0
}
}

With group_by_person=true​

Rows are aggregated per driver: driver_name carries the name and device_name turns into an empty string.

{
"service_type": "",
"driver_name": "Carlos Martinez",
"device_name": "",
"unscheduled_tasks": 5,
"scheduled_tasks": 18,
"total_tasks": 23,
"task_hours": null,
"shift_hours": null,
"kms_worked": 210.6,
"kms_ideal": 198.0,
"kms_shift": 265.0,
"avg_arrival_time": null,
"occupancy": 74
}

Errors​

CodeHTTPDescription
VALIDATION_ERROR400Invalid params: missing dates, range > 31 days, invalid enum values.
UNAUTHORIZED401Missing, invalid, or expired tenant / Authorization / X-API-Key
FORBIDDEN403User lacks required permission.
RATE_LIMITED429Exceeded 10 req/min.
INTERNAL_ERROR500Unexpected server error.