Skip to main content

App Utilization Users for One App

Approved

This endpoint is approved but has not been implemented yet.

GET /clients/{client_id}/analytics/apps/{app_id}/utilization/users

Returns a paginated list of users for one specific app, ranked by usage within the requested period. This is the per-app user breakdown companion to App Utilization Detail.

Use this endpoint for both the "Top App Users" preview and the full "All Users" drawer on an app detail page. "Top users" is not a separate route: request the same endpoint with a small page_size such as 5.

Data source is app_usage_reports, scoped to one app and aggregated by user over the requested period.

Use Case

Use this endpoint to:

  • Show the top users for one app on the app detail page
  • Drive the full paginated user list for one app
  • Compare each user's average time in the app to a prior period
  • Filter the app's user list to one or more departments

Path Parameters

ParameterTypeDescription
client_idstring (uuid)Unique identifier for the client organization
app_idstring (uuid)Unique identifier for the application

Query Parameters

ParameterTypeRequiredDefaultDescription
granularitystringYes-Aggregation granularity: daily, weekly, monthly, quarterly. Determines how avg_time_ms_per_day is computed.
start_datestringYes-Start of period (YYYY-MM-DD)
end_datestringYes-End of period, inclusive (YYYY-MM-DD)
compare_start_datestringNo-Comparison period start (YYYY-MM-DD). Must be provided with compare_end_date.
compare_end_datestringNo-Comparison period end, inclusive (YYYY-MM-DD). Must be provided with compare_start_date.
department_idsstringNo-Comma-separated department UUIDs to scope usage data to
sort_bystringNoavg_timeSort field: avg_time, avg_time_change, days_active, username
sort_orderstringNodescSort direction: asc, desc
page_sizeintegerNo50Items per page. Max: 200
cursorstringNo-Pagination cursor from a previous response

The singular form department_id is accepted as a deprecated alias. Use the plural form for new integrations.

Comparison period

When both compare_start_date and compare_end_date are provided, avg_time_ms_per_day.change_pct contains the percentage change from the comparison period to the primary period. When omitted, avg_time_ms_per_day.change_pct is null.

Providing only one of the two comparison parameters returns 400.

Response

FieldTypeDescription
periodPeriodResolved date range
dataAppUserUtilization[]Array of per-user utilization rows for this app
total_countintegerTotal number of users matching the current filters
next_cursorstring | nullCursor for the next page. null when on the last page.

Example Requests

Top 5 users for one app

curl -X GET "https://api.example.com/v2/clients/aa7cf840-9ca9-46a3-9778-9015d6580d50/analytics/apps/f1a2b3c4-d5e6-7890-abcd-ef1234567890/utilization/users?granularity=monthly&start_date=2026-02-01&end_date=2026-02-28&page_size=5" \
-H "Authorization: Bearer YOUR_API_TOKEN"

Full list with month-over-month comparison

curl -X GET "https://api.example.com/v2/clients/aa7cf840-9ca9-46a3-9778-9015d6580d50/analytics/apps/f1a2b3c4-d5e6-7890-abcd-ef1234567890/utilization/users?granularity=monthly&start_date=2026-02-01&end_date=2026-02-28&compare_start_date=2026-01-01&compare_end_date=2026-01-31&sort_by=avg_time_change&sort_order=desc" \
-H "Authorization: Bearer YOUR_API_TOKEN"

Scoped to a department

curl -X GET "https://api.example.com/v2/clients/aa7cf840-9ca9-46a3-9778-9015d6580d50/analytics/apps/f1a2b3c4-d5e6-7890-abcd-ef1234567890/utilization/users?granularity=monthly&start_date=2026-02-01&end_date=2026-02-28&department_ids=d1a2b3c4-e5f6-7890-abcd-ef1234567890" \
-H "Authorization: Bearer YOUR_API_TOKEN"

Example Responses

With comparison period

{
"period": {
"start_date": "2026-02-01",
"end_date": "2026-02-28",
"compare_start_date": "2026-01-01",
"compare_end_date": "2026-01-31"
},
"data": [
{
"user": {
"id": "u1a2b3c4-d5e6-7890-abcd-ef1234567890",
"username": "james.wilson",
"user_key": "james.wilson@example.com",
"last_activity": {
"at": "2026-02-28T17:42:00.000Z",
"desktop_at": "2026-02-28T17:42:00.000Z",
"web_at": null
}
},
"avg_time_ms_per_day": { "value": 6060000, "change_pct": 12.5, "compare_value": 5386666 },
"days_active": 24
},
{
"user": {
"id": "u2b3c4d5-e6f7-8901-bcde-f12345678901",
"username": "sarah.chen",
"user_key": "sarah.chen@example.com",
"last_activity": {
"at": "2026-02-28T16:10:00.000Z",
"desktop_at": "2026-02-28T16:10:00.000Z",
"web_at": "2026-02-27T09:00:00.000Z"
}
},
"avg_time_ms_per_day": { "value": 5520000, "change_pct": -4.1, "compare_value": 5756000 },
"days_active": 21
}
],
"total_count": 18,
"next_cursor": "eyJsYXN0X2lkIjoidTJiM2M0ZDUifQ"
}

Without comparison period

{
"period": {
"start_date": "2026-02-01",
"end_date": "2026-02-28",
"compare_start_date": null,
"compare_end_date": null
},
"data": [
{
"user": {
"id": "u1a2b3c4-d5e6-7890-abcd-ef1234567890",
"username": "james.wilson",
"user_key": "james.wilson@example.com",
"last_activity": {
"at": "2026-02-28T17:42:00.000Z",
"desktop_at": "2026-02-28T17:42:00.000Z",
"web_at": null
}
},
"avg_time_ms_per_day": { "value": 6060000, "change_pct": null, "compare_value": null },
"days_active": 24
}
],
"total_count": 18,
"next_cursor": "eyJsYXN0X2lkIjoidTFhMmIzYzQifQ"
}

Empty Result

{
"period": {
"start_date": "2026-02-01",
"end_date": "2026-02-28",
"compare_start_date": null,
"compare_end_date": null
},
"data": [],
"total_count": 0,
"next_cursor": null
}

Period

FieldTypeNullableDescription
start_datestringNoStart of the primary period (YYYY-MM-DD)
end_datestringNoEnd of the primary period (YYYY-MM-DD)
compare_start_datestringYesStart of comparison period. null if no comparison requested.
compare_end_datestringYesEnd of comparison period. null if no comparison requested.

AppUserUtilization

FieldTypeNullableDescription
userUserRefNoLightweight user reference with identity and last-activity fields
avg_time_ms_per_dayMetricWithDeltaDtoNoAverage active time in milliseconds per day for this user within this app and period
days_activeintegerNoNumber of distinct days in the primary period where this user used the app

DB source:

DTO FieldDB Aggregation
userJoined via app_usage_reports.user_idUserRef fields from users
avg_time_ms_per_day.valueSUM(total_active_ms) / COUNT(DISTINCT activity_date) for this app + user within the primary period
avg_time_ms_per_day.change_pct((current - comparison) / comparison) * 100 using the same aggregation over the comparison period
avg_time_ms_per_day.compare_valueSame aggregation as value applied to the comparison period. null when no comparison period is requested.
days_activeCOUNT(DISTINCT activity_date) for this app + user within the primary period

Pagination

This endpoint uses cursor-based pagination.

  1. Omit cursor on the first request
  2. If next_cursor is not null, pass its value as cursor on the next request
  3. Repeat until next_cursor is null

Constraints

  • Max date range: 366 days for both primary and comparison periods. Requests exceeding this return 400.
  • Comparison symmetry: Both compare_start_date and compare_end_date must be provided together, or both omitted.
  • Timezone: All dates are in the client's configured timezone.
  • granularity is required. There is no default.

Error Responses

StatusDescription
400Invalid parameters (bad date format, range exceeds 366 days, mismatched comparison params, missing granularity, unknown sort_by value)
401Authentication required
403Insufficient permissions for this client
404App or client not found
500Server error

Example Error Response

{
"error": {
"code": "invalid_parameter",
"message": "Unknown sort_by: avgDailyTime. Valid values: avg_time, avg_time_change, days_active, username",
"details": {
"sort_by": "avgDailyTime"
}
}
}

Notes

  • Use page_size=5 to render a "Top App Users" preview. Use the same endpoint with normal pagination for the full list.
  • days_active is a primary-period value only. It does not use MetricWithDeltaDto.
  • When department_ids is provided, only users in those departments are included.