Skip to main content

App Utilization Summary

GET /clients/{client_id}/analytics/apps/utilization/summary

Returns aggregate counts for the App Metrics dashboard cards: total apps with activity, apps first seen this period (discovered), apps that went quiet after prior activity (dropped off), and dimensional breakdowns by categories, users, and departments. Accepts is_approved and category_ids filters to scope all counts to a subset of apps.

For the paginated app metrics table, use App Utilization. For top app rankings, use App Utilization Rankings.

Path Parameters

ParameterTypeDescription
client_idstring (uuid)Unique identifier for the client organization

Query Parameters

ParameterTypeRequiredDefaultDescription
granularitystringYes-Aggregation granularity: daily, weekly, monthly, quarterly
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.
is_approvedbooleanNo-Filter by approval status: true (approved only), false (unapproved only)
category_idsstringNo-Comma-separated catalog category UUIDs to filter by
department_idsstringNo-Comma-separated department UUIDs to scope usage data to

Comparison period

When both compare_start_date and compare_end_date are provided, the change_pct field inside each metric object contains the percentage change from the comparison period to the primary period. When omitted, all change_pct fields are null.

Providing only one of the two comparison parameters returns 400.

Response

Returns an AppUtilizationSummary object.

Example Requests

Basic summary for February 2026

curl -X GET "https://api.example.com/v2/clients/aa7cf840-9ca9-46a3-9778-9015d6580d50/analytics/apps/utilization/summary?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/summary?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 category (e.g. AI apps)

curl -X GET "https://api.example.com/v2/clients/aa7cf840-9ca9-46a3-9778-9015d6580d50/analytics/apps/utilization/summary?granularity=monthly&start_date=2026-02-01&end_date=2026-02-28&category_ids=a7b8c9d0-e1f2-3456-abcd-789012345678" \
-H "Authorization: Bearer YOUR_API_TOKEN"

Unapproved apps only

curl -X GET "https://api.example.com/v2/clients/aa7cf840-9ca9-46a3-9778-9015d6580d50/analytics/apps/utilization/summary?granularity=monthly&start_date=2026-02-01&end_date=2026-02-28&is_approved=false" \
-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"
},
"apps_used": { "value": 107, "change_pct": -10.1, "compare_value": 119 },
"apps_discovered": { "value": 2, "change_pct": 100.0, "compare_value": 1 },
"apps_dropped_off": { "value": 1, "change_pct": null, "compare_value": null },
"categories_used": { "value": 15, "change_pct": -6.3, "compare_value": 16 },
"users": { "value": 87, "change_pct": -3.3, "compare_value": 90 },
"departments": { "value": 8, "change_pct": 0.0, "compare_value": 8 }
}

Without comparison period

{
"period": {
"start_date": "2026-02-01",
"end_date": "2026-02-28",
"compare_start_date": null,
"compare_end_date": null
},
"apps_used": { "value": 107, "change_pct": null, "compare_value": null },
"apps_discovered": { "value": 2, "change_pct": null, "compare_value": null },
"apps_dropped_off": { "value": 1, "change_pct": null, "compare_value": null },
"categories_used": { "value": 15, "change_pct": null, "compare_value": null },
"users": { "value": 87, "change_pct": null, "compare_value": null },
"departments": { "value": 8, "change_pct": null, "compare_value": null }
}

AppUtilizationSummary

FieldTypeNullableDescription
periodPeriodNoResolved date range
apps_usedMetricWithDeltaDtoNoTotal distinct apps with at least one app_usage_reports row in the period
apps_discoveredMetricWithDeltaDtoNoApps first seen during this period — no rows in app_usage_reports for this client before start_date
apps_dropped_offMetricWithDeltaDtoNoApps with rows before start_date but zero rows within the current period
categories_usedMetricWithDeltaDtoNoDistinct catalog categories across apps with activity in the period
usersMetricWithDeltaDtoNoDistinct users with app activity in the period
departmentsMetricWithDeltaDtoNoDistinct departments with app activity in the period

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.

DB source:

DTO FieldDB Aggregation
apps_used.valueCOUNT(DISTINCT application_id) from app_usage_reports where activity_date BETWEEN start_date AND end_date
apps_discovered.valueCount of distinct application_id where MIN(activity_date) for this client falls within start_dateend_date
apps_dropped_off.valueCount of distinct application_id with rows before start_date but no rows between start_date and end_date
categories_used.valueCount of distinct catalog_categories.id joined through catalog_application_catalog_categories for apps with activity in the period
users.valueCOUNT(DISTINCT app_usage_reports.user_id) in the period
departments.valueCount of distinct departments via user-department assignments for users with activity in the period
*.change_pct((current - comparison) / comparison) * 100 using the same logic over the comparison date range
*.compare_valueThe same aggregation as *.value applied to the comparison date range. null when no comparison period is requested.

Discovery and Drop-off Logic

Discovered: An app is "discovered" in a period if the earliest activity_date in app_usage_reports for that app + client combination falls within start_dateend_date. Equivalently, no rows exist for that app before start_date. This is the same "first seen" logic used by New AI Tools, applied to all apps instead of only AI-categorized apps.

Dropped off: An app has "dropped off" if it has at least one row in app_usage_reports before start_date but zero rows where activity_date falls within start_dateend_date. These apps had prior usage but went quiet during the current period.

Note: An app cannot be both discovered and dropped off in the same period.

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)
401Authentication required
403Insufficient permissions for this client
404Client not found
500Server error

Example Error Response

{
"error": {
"code": "invalid_parameter",
"message": "compare_start_date requires compare_end_date to be provided",
"details": {
"compare_start_date": "2026-01-01",
"compare_end_date": null
}
}
}