App Activity
GET /v2/clients/{client_id}/analytics/apps/{app_id}/activity
Returns a daily time-series of activity for a specific application. Supports multiple metrics covering active time, session count, and user count.
This endpoint uses a different data source than user/device activity. App metrics come from the app_usage_reports table (daily aggregated usage per user per app), not from heartbeats.
Use Case
Use this endpoint to:
- Display app usage trends on the app detail page (line chart, area chart)
- Track adoption with daily user counts
- Monitor engagement depth via active time and session count
- Filter activity to one or more departments by user department membership
- Compare usage across time periods
Path Parameters
| Parameter | Type | Description |
|---|---|---|
client_id | string (uuid) | Unique identifier for the client organization |
app_id | string (uuid) | Unique identifier for the application |
Query Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
start_date | string | Yes | Start of date range (YYYY-MM-DD) |
end_date | string | Yes | End of date range, inclusive (YYYY-MM-DD) |
metric | string | Yes | Metric to retrieve. See Available Metrics. |
department_ids | string | No | Comma-separated department UUIDs to scope usage data to by user department membership |
Available Metrics
| Metric | Label | Description | DB Aggregation |
|---|---|---|---|
active-time | Active Time | Average active time in milliseconds per user per day | SUM(app_usage_reports.total_active_ms) / COUNT(DISTINCT app_usage_reports.user_id) GROUP BY activity_date WHERE application_id = ? |
session-count | Sessions | Total sessions across all users | SUM(app_usage_reports.total_session_count) GROUP BY activity_date WHERE application_id = ? |
user-count | Daily Users | Distinct users who used the app per day | COUNT(DISTINCT app_usage_reports.user_id) GROUP BY activity_date WHERE application_id = ? |
Response
Returns an ActivityTimeSeries.
For active-time, value is in milliseconds. Consumers should format this for display (e.g. convert to hours/minutes).
Example Requests
Active time
curl -X GET "https://api.example.com/v2/clients/aa7cf840-9ca9-46a3-9778-9015d6580d50/analytics/apps/b2c3d4e5-f6a7-8901-bcde-f12345678901/activity?start_date=2026-01-01&end_date=2026-01-15&metric=active-time" \
-H "Authorization: Bearer YOUR_API_TOKEN"
Session count
curl -X GET "https://api.example.com/v2/clients/aa7cf840-9ca9-46a3-9778-9015d6580d50/analytics/apps/b2c3d4e5-f6a7-8901-bcde-f12345678901/activity?start_date=2026-01-01&end_date=2026-01-15&metric=session-count" \
-H "Authorization: Bearer YOUR_API_TOKEN"
User count
curl -X GET "https://api.example.com/v2/clients/aa7cf840-9ca9-46a3-9778-9015d6580d50/analytics/apps/b2c3d4e5-f6a7-8901-bcde-f12345678901/activity?start_date=2026-01-01&end_date=2026-01-15&metric=user-count" \
-H "Authorization: Bearer YOUR_API_TOKEN"
Scoped to departments
curl -X GET "https://api.example.com/v2/clients/aa7cf840-9ca9-46a3-9778-9015d6580d50/analytics/apps/b2c3d4e5-f6a7-8901-bcde-f12345678901/activity?start_date=2026-01-01&end_date=2026-01-15&metric=active-time&department_ids=d1a2b3c4-e5f6-7890-abcd-ef1234567890,e2b3c4d5-f6a7-8901-bcde-f12345678901" \
-H "Authorization: Bearer YOUR_API_TOKEN"
Example Responses
active-time
{
"metric": "active-time",
"label": "Active Time",
"period": {
"start_date": "2026-01-01",
"end_date": "2026-01-15"
},
"data": [
{ "date": "2026-01-01", "value": 14400000 },
{ "date": "2026-01-02", "value": 12600000 },
{ "date": "2026-01-03", "value": 16200000 },
{ "date": "2026-01-04", "value": 0 },
{ "date": "2026-01-05", "value": 0 },
{ "date": "2026-01-06", "value": 15300000 },
{ "date": "2026-01-07", "value": 13500000 },
{ "date": "2026-01-08", "value": 17100000 },
{ "date": "2026-01-09", "value": 14400000 },
{ "date": "2026-01-10", "value": 15900000 },
{ "date": "2026-01-11", "value": 0 },
{ "date": "2026-01-12", "value": 0 },
{ "date": "2026-01-13", "value": 16800000 },
{ "date": "2026-01-14", "value": 14100000 },
{ "date": "2026-01-15", "value": 15600000 }
]
}
session-count
{
"metric": "session-count",
"label": "Sessions",
"period": {
"start_date": "2026-01-01",
"end_date": "2026-01-15"
},
"data": [
{ "date": "2026-01-01", "value": 128 },
{ "date": "2026-01-02", "value": 115 },
{ "date": "2026-01-03", "value": 142 },
{ "date": "2026-01-04", "value": 0 },
{ "date": "2026-01-05", "value": 0 },
{ "date": "2026-01-06", "value": 131 },
{ "date": "2026-01-07", "value": 119 },
{ "date": "2026-01-08", "value": 147 },
{ "date": "2026-01-09", "value": 125 },
{ "date": "2026-01-10", "value": 138 },
{ "date": "2026-01-11", "value": 0 },
{ "date": "2026-01-12", "value": 0 },
{ "date": "2026-01-13", "value": 144 },
{ "date": "2026-01-14", "value": 121 },
{ "date": "2026-01-15", "value": 135 }
]
}
user-count
{
"metric": "user-count",
"label": "Daily Users",
"period": {
"start_date": "2026-01-01",
"end_date": "2026-01-15"
},
"data": [
{ "date": "2026-01-01", "value": 42 },
{ "date": "2026-01-02", "value": 38 },
{ "date": "2026-01-03", "value": 45 },
{ "date": "2026-01-04", "value": 0 },
{ "date": "2026-01-05", "value": 0 },
{ "date": "2026-01-06", "value": 41 },
{ "date": "2026-01-07", "value": 39 },
{ "date": "2026-01-08", "value": 47 },
{ "date": "2026-01-09", "value": 43 },
{ "date": "2026-01-10", "value": 46 },
{ "date": "2026-01-11", "value": 0 },
{ "date": "2026-01-12", "value": 0 },
{ "date": "2026-01-13", "value": 44 },
{ "date": "2026-01-14", "value": 40 },
{ "date": "2026-01-15", "value": 45 }
]
}
Error Responses
| Status | Description |
|---|---|
| 400 | Invalid parameters (bad date format, range exceeds 90 days, unknown metric) |
| 401 | Authentication required |
| 403 | Insufficient permissions for this client |
| 404 | App or client not found |
| 500 | Server error |
Example Error Response
{
"error": {
"code": "invalid_parameter",
"message": "Unknown metric: clicks. Valid values: active-time, session-count, user-count",
"details": {
"metric": "clicks"
}
}
}
Notes
- The response always includes every date in the range, even weekends or days with zero activity.
- All dates are in the client's configured timezone.
active-timevalues are the average active milliseconds per user for each day. Divide by 3,600,000 for hours.user-countcounts distinct users per day, not cumulative.- When
department_idsis provided, usage is scoped by matching user department membership. A user matching multiple selected departments should only contribute once to each day's totals. - Department scoping is based on department membership records and is not historical as-of activity date unless explicitly implemented that way.
- Data source is
app_usage_reports, which is partitioned by month. Queries spanning month boundaries read from multiple partitions transparently.
Related Endpoints
- App Utilization Detail -- Period-level summary metrics for this app
- App Utilization Users for One App -- Per-user breakdown within this app
- Get App -- App identity and metadata
- User Activity -- Activity time-series for a user
- Device Activity -- Activity time-series for a device