AI App Users
GET /clients/{client_id}/analytics/apps/ai/users
This endpoint is superseded by the generic App Utilization with ?category_ids=<ai_id>. usage_level is now available on that endpoint.
Replacement:
GET /clients/{client_id}/analytics/apps/utilization?category_ids=<ai_id>
Note: the user count field is named unique_users on the replacement (was user_count here).
Returns a paginated list of AI applications ranked by user count for the requested period. Each row contains a lightweight app reference alongside the user count, comparison-period change percentage, and a usage level classification.
This endpoint powers the AI App Users table. For the summary card metrics, use AI App Users Summary.
For what qualifies as an "AI App", see AI Apps Overview. For how usage_level is computed, see Usage Level.
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 |
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. |
sort_by | string | No | user_count | Sort field: canonical_name, user_count |
sort_order | string | No | desc | Sort direction: asc, desc |
page_size | integer | No | 50 | Items per page. Max: 200 |
cursor | string | No | - | Pagination cursor from a previous response |
Comparison period
When both compare_start_date and compare_end_date are provided, user_count.change_pct contains the percentage change from the comparison period to the primary period. When omitted, user_count.change_pct is null.
Providing only one of the two comparison parameters returns 400.
Response
| Field | Type | Description |
|---|---|---|
data | AiAppUsageItem[] | Array of AI app usage objects |
total_count | integer | Total number of AI apps matching the current filters |
next_cursor | string | null | Cursor for the next page. null when on the last page. |
Example Requests
Basic list for February 2026
curl -X GET "https://api.example.com/v2/clients/aa7cf840-9ca9-46a3-9778-9015d6580d50/analytics/apps/ai/users?start_date=2026-02-01&end_date=2026-02-28" \
-H "Authorization: Bearer YOUR_API_TOKEN"
With comparison, sorted by name
curl -X GET "https://api.example.com/v2/clients/aa7cf840-9ca9-46a3-9778-9015d6580d50/analytics/apps/ai/users?start_date=2026-02-01&end_date=2026-02-28&compare_start_date=2026-01-01&compare_end_date=2026-01-31&sort_by=canonical_name&sort_order=asc" \
-H "Authorization: Bearer YOUR_API_TOKEN"
Example Responses
With comparison period
{
"data": [
{
"app": {
"id": "a1b2c3d4-0001-4000-8000-000000000001",
"canonical_name": "ChatGPT",
"logo": "https://cdn.example.com/logos/chatgpt.png",
"type": "browser",
"is_favorite": false,
"is_approved": true
},
"user_count": { "value": 52, "change_pct": 12.5, "compare_value": 46 },
"usage_level": "heavy"
},
{
"app": {
"id": "a1b2c3d4-0002-4000-8000-000000000002",
"canonical_name": "Jasper",
"logo": "https://cdn.example.com/logos/jasper.png",
"type": "browser",
"is_favorite": false,
"is_approved": false
},
"user_count": { "value": 40, "change_pct": 8.1, "compare_value": 37 },
"usage_level": "heavy"
},
{
"app": {
"id": "a1b2c3d4-0003-4000-8000-000000000003",
"canonical_name": "Bard",
"logo": "https://cdn.example.com/logos/bard.png",
"type": "browser",
"is_favorite": true,
"is_approved": true
},
"user_count": { "value": 35, "change_pct": -2.8, "compare_value": 36 },
"usage_level": "medium"
},
{
"app": {
"id": "a1b2c3d4-0004-4000-8000-000000000004",
"canonical_name": "Claude",
"logo": "https://cdn.example.com/logos/claude.png",
"type": "browser",
"is_favorite": false,
"is_approved": false
},
"user_count": { "value": 28, "change_pct": null, "compare_value": null },
"usage_level": "light"
}
],
"total_count": 4,
"next_cursor": null
}
Without comparison period
When no comparison dates are provided, user_count.change_pct is null:
{
"data": [
{
"app": {
"id": "a1b2c3d4-0001-4000-8000-000000000001",
"canonical_name": "ChatGPT",
"logo": "https://cdn.example.com/logos/chatgpt.png",
"type": "browser",
"is_favorite": false,
"is_approved": true
},
"user_count": { "value": 52, "change_pct": null, "compare_value": null },
"usage_level": "heavy"
}
],
"total_count": 4,
"next_cursor": "eyJsYXN0X2lkIjoiYTFiMmMzZDQifQ"
}
Empty Result
{
"data": [],
"total_count": 0,
"next_cursor": null
}
AiAppUsageItem
Per-app usage metrics for AI applications in the requested period.
{
"app": {
"id": "a1b2c3d4-0001-4000-8000-000000000001",
"canonical_name": "ChatGPT",
"logo": "https://cdn.example.com/logos/chatgpt.png",
"type": "browser",
"is_favorite": false,
"is_approved": true
},
"user_count": { "value": 52, "change_pct": 12.5, "compare_value": 46 },
"usage_level": "heavy"
}
| Field | Type | Nullable | Description |
|---|---|---|---|
app | AppRef | No | Lightweight app reference with identity fields |
user_count | MetricWithDeltaDto | No | Distinct users who used this AI app during the period |
usage_level | string | No | Usage classification: heavy, medium, or light. See Usage Level. |
DB source:
| DTO Field | DB Aggregation |
|---|---|
app | Joined via app_usage_reports.application_id → apps → catalog_applications, filtered to AI category |
user_count.value | COUNT(DISTINCT app_usage_reports.user_id) WHERE activity_date BETWEEN start_date AND end_date |
user_count.change_pct | ((current - comparison) / comparison) * 100 using the same aggregation over the comparison date range |
user_count.compare_value | The same aggregation as user_count.value applied to the comparison date range. null when no comparison period is requested. |
usage_level | Derived from Usage Score formula. See AI Apps Overview. |
Pagination
This endpoint uses cursor-based pagination.
- Omit
cursoron the first request - If
next_cursoris notnull, pass its value ascursoron the next request - Repeat until
next_cursorisnull
Error Responses
| Status | Description |
|---|---|
| 400 | Invalid parameters (bad date format, range exceeds 366 days, mismatched comparison params, unknown sort_by value) |
| 401 | Authentication required |
| 403 | Insufficient permissions for this client |
| 404 | Client not found |
| 500 | Server error |
Related Endpoints
- AI App Users Summary -- Summary card metrics for AI app users
- New AI Tools -- Recently discovered AI apps
- App Utilization -- Utilization metrics across all apps (not AI-specific)