App Utilization Rankings
GET /clients/{client_id}/analytics/apps/utilization/rankings
Returns the top-ranked app for three metrics — interactions, active time, and active users — plus the biggest movers for each. Serves the "Top App by Interactions", "Top App by Time", and "Top App by Active Users" dashboard widgets.
For the paginated app metrics table, use App Utilization. For aggregate card counts (apps used, discovered, dropped off), use App Utilization Summary.
Path Parameters
| Parameter | Type | Description |
|---|---|---|
client_id | string (uuid) | Unique identifier for the client organization |
Query Parameters
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
granularity | string | Yes | - | Aggregation granularity: daily, weekly, monthly, quarterly. Determines how metrics are averaged within the period (e.g. interactions per day vs. per week). |
start_date | string | Yes | - | Start of period (YYYY-MM-DD) |
end_date | string | Yes | - | End of period, inclusive (YYYY-MM-DD) |
compare_start_date | string | No | - | Comparison period start (YYYY-MM-DD). Must be provided with compare_end_date. |
compare_end_date | string | No | - | Comparison period end, inclusive (YYYY-MM-DD). Must be provided with compare_start_date. |
category_ids | string | No | - | Comma-separated catalog category UUIDs to filter by |
department_ids | string | No | - | Comma-separated department UUIDs to scope usage data to |
Granularity and metric values
granularity affects how the value on each ranked app is computed:
by_interactions: Average session count per granularity unit (e.g. per day fordaily, per week forweekly)by_time: Average active time in milliseconds per granularity unitby_active_users: Total distinct users for the full period (granularity does not affect this count)
Comparison period
When both compare_start_date and compare_end_date are provided, biggest_increase and biggest_decrease are populated and metric.change_pct is non-null on all ranked items. When omitted, biggest_increase and biggest_decrease are null and metric.change_pct is null.
Providing only one of the two comparison parameters returns 400.
Response
| Field | Type | Description |
|---|---|---|
period | Period | Resolved date range |
by_interactions | AppRanking | Ranking by average interactions per granularity unit |
by_time | AppRanking | Ranking by average active time per granularity unit |
by_active_users | AppRanking | Ranking by active user count |
Example Requests
Monthly rankings for February 2026
curl -X GET "https://api.example.com/v2/clients/aa7cf840-9ca9-46a3-9778-9015d6580d50/analytics/apps/utilization/rankings?granularity=monthly&start_date=2026-02-01&end_date=2026-02-28" \
-H "Authorization: Bearer YOUR_API_TOKEN"
With month-over-month comparison
curl -X GET "https://api.example.com/v2/clients/aa7cf840-9ca9-46a3-9778-9015d6580d50/analytics/apps/utilization/rankings?granularity=monthly&start_date=2026-02-01&end_date=2026-02-28&compare_start_date=2026-01-01&compare_end_date=2026-01-31" \
-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/utilization/rankings?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"
},
"by_interactions": {
"leader": {
"app": {
"id": "f1a2b3c4-d5e6-7890-abcd-ef1234567890",
"canonical_name": "MS Teams",
"logo": "https://cdn.example.com/logos/msteams.png",
"type": "desktop",
"is_favorite": true,
"is_approved": true
},
"metric": { "value": 210, "change_pct": 12.5, "compare_value": 187 }
},
"biggest_increase": {
"app": {
"id": "a2b3c4d5-e6f7-8901-bcde-f12345678901",
"canonical_name": "Kaseya",
"logo": "https://cdn.example.com/logos/kaseya.png",
"type": "browser",
"is_favorite": false,
"is_approved": true
},
"metric": { "value": 103, "change_pct": 45.1, "compare_value": 71 }
},
"biggest_decrease": {
"app": {
"id": "b3c4d5e6-f7a8-9012-cdef-123456789012",
"canonical_name": "Strategy Overview",
"logo": "https://cdn.example.com/logos/strategy.png",
"type": "browser",
"is_favorite": false,
"is_approved": false
},
"metric": { "value": 7, "change_pct": -34.2, "compare_value": 11 }
}
},
"by_time": {
"leader": {
"app": {
"id": "c4d5e6f7-a8b9-0123-defa-234567890123",
"canonical_name": "Datto",
"logo": "https://cdn.example.com/logos/datto.png",
"type": "desktop",
"is_favorite": false,
"is_approved": true
},
"metric": { "value": 8460000, "change_pct": 5.3, "compare_value": 8034000 }
},
"biggest_increase": {
"app": {
"id": "d5e6f7a8-b9c0-1234-efab-345678901234",
"canonical_name": "Slack",
"logo": "https://cdn.example.com/logos/slack.png",
"type": "desktop",
"is_favorite": true,
"is_approved": true
},
"metric": { "value": 5100000, "change_pct": 22.4, "compare_value": 4166000 }
},
"biggest_decrease": {
"app": {
"id": "e6f7a8b9-c0d1-2345-fabc-456789012345",
"canonical_name": "Zoom",
"logo": "https://cdn.example.com/logos/zoom.png",
"type": "desktop",
"is_favorite": false,
"is_approved": true
},
"metric": { "value": 1200000, "change_pct": -18.0, "compare_value": 1463000 }
}
},
"by_active_users": {
"leader": {
"app": {
"id": "f1a2b3c4-d5e6-7890-abcd-ef1234567890",
"canonical_name": "MS Teams",
"logo": "https://cdn.example.com/logos/msteams.png",
"type": "desktop",
"is_favorite": true,
"is_approved": true
},
"metric": { "value": 25, "change_pct": 8.0, "compare_value": 23 }
},
"biggest_increase": {
"app": {
"id": "a2b3c4d5-e6f7-8901-bcde-f12345678901",
"canonical_name": "Kaseya",
"logo": "https://cdn.example.com/logos/kaseya.png",
"type": "browser",
"is_favorite": false,
"is_approved": true
},
"metric": { "value": 18, "change_pct": 38.5, "compare_value": 13 }
},
"biggest_decrease": null
}
}
Without comparison period
When no comparison dates are provided, biggest_increase and biggest_decrease are null and metric.change_pct is null on the leader:
{
"period": {
"start_date": "2026-02-01",
"end_date": "2026-02-28",
"compare_start_date": null,
"compare_end_date": null
},
"by_interactions": {
"leader": {
"app": {
"id": "f1a2b3c4-d5e6-7890-abcd-ef1234567890",
"canonical_name": "MS Teams",
"logo": "https://cdn.example.com/logos/msteams.png",
"type": "desktop",
"is_favorite": true,
"is_approved": true
},
"metric": { "value": 210, "change_pct": null, "compare_value": null }
},
"biggest_increase": null,
"biggest_decrease": null
},
"by_time": {
"leader": {
"app": {
"id": "c4d5e6f7-a8b9-0123-defa-234567890123",
"canonical_name": "Datto",
"logo": "https://cdn.example.com/logos/datto.png",
"type": "desktop",
"is_favorite": false,
"is_approved": true
},
"metric": { "value": 8460000, "change_pct": null, "compare_value": null }
},
"biggest_increase": null,
"biggest_decrease": null
},
"by_active_users": {
"leader": {
"app": {
"id": "f1a2b3c4-d5e6-7890-abcd-ef1234567890",
"canonical_name": "MS Teams",
"logo": "https://cdn.example.com/logos/msteams.png",
"type": "desktop",
"is_favorite": true,
"is_approved": true
},
"metric": { "value": 25, "change_pct": null, "compare_value": null }
},
"biggest_increase": null,
"biggest_decrease": null
}
}
Period
| Field | Type | Nullable | Description |
|---|---|---|---|
start_date | string | No | Start of the primary period (YYYY-MM-DD) |
end_date | string | No | End of the primary period (YYYY-MM-DD) |
compare_start_date | string | Yes | Start of comparison period. null if no comparison requested. |
compare_end_date | string | Yes | End of comparison period. null if no comparison requested. |
AppRanking
| Field | Type | Nullable | Description |
|---|---|---|---|
leader | RankedApp | No | App with the highest value for this metric in the period |
biggest_increase | RankedApp | Yes | App with the largest positive metric.change_pct. null if no comparison requested or no app increased. |
biggest_decrease | RankedApp | Yes | App with the largest negative metric.change_pct. null if no comparison requested or no app decreased. |
RankedApp
| Field | Type | Nullable | Description |
|---|---|---|---|
app | AppRef | No | Lightweight app reference |
metric | MetricWithDeltaDto | No | Metric value and optional comparison delta. Units depend on the ranking: interactions/granularity-unit (by_interactions), milliseconds/granularity-unit (by_time), distinct user count (by_active_users). |
DB source:
| DTO Field | DB Aggregation |
|---|---|
app | Joined via app_usage_reports.application_id → apps → catalog_applications |
by_interactions.leader.metric.value | SUM(total_session_count) / COUNT(DISTINCT granularity_unit) for the top app in the period |
by_time.leader.metric.value | SUM(total_active_ms) / COUNT(DISTINCT granularity_unit) for the top app in the period |
by_active_users.leader.metric.value | COUNT(DISTINCT user_id) for the top app in the period |
metric.change_pct | ((current - comparison) / comparison) * 100 using the same aggregation over the comparison date range |
metric.compare_value | The same aggregation as metric.value applied to the comparison date range. null when no comparison period is requested. |
biggest_increase | App with the highest positive metric.change_pct across all apps (not necessarily the leader) |
biggest_decrease | App with the lowest (most negative) metric.change_pct across all apps |
Constraints
- Max date range: 366 days for both primary and comparison periods. Requests exceeding this return
400. - Comparison symmetry: Both
compare_start_dateandcompare_end_datemust be provided together, or both omitted. - Timezone: All dates are in the client's configured timezone.
granularityis required. There is no default — the granularity unit affects how averages are computed and must be explicit.
Error Responses
| Status | Description |
|---|---|
| 400 | Invalid parameters (bad date format, range exceeds 366 days, mismatched comparison params, missing granularity, unknown granularity value) |
| 401 | Authentication required |
| 403 | Insufficient permissions for this client |
| 404 | Client not found |
| 500 | Server error |
Example Error Response
{
"error": {
"code": "invalid_parameter",
"message": "granularity is required",
"details": null
}
}
Notes
- The leader is determined by the highest
metric.valuein the primary period, not the highestmetric.change_pct. An app can be the leader inby_interactionswithout appearing inbiggest_increase. biggest_increaseandbiggest_decreaseare chosen from all apps in the period, not just from the top N — an app with a small absolute value can appear here if its percentage change is large.- When
department_idsis provided, all metrics are scoped to usage from users in those departments. by_timevalues are milliseconds. Divide by 3,600,000 for hours. "Per day" or "per user" averages are presentation concerns — compute them client-side from thevalueand the date range.
Related Endpoints
- App Utilization Summary -- Card counts: apps used, discovered, dropped off
- App Utilization -- Paginated per-app metrics table
- App Activity -- Daily time-series for a single app