Aggregate active Session count, active Identity count, total active time, and Credits by Template over a whole-hour interval.
GET /api/v1/forward/usage/templates
Aggregate active Session count, active Identity count, total active time, and Credits by Template over a whole-hour interval.
Legacy parameter retirement notice The new API version is available. Usestart_atandend_atto query usage over whole-hour intervals. The legacy Unix millisecond timestamp parametersstart_timeandend_time, along with the legacy calculation based on Session creation time, will be retired and no longer supported on October 18, 2026 (Beijing time). The period before that date is a compatibility period. Complete your migration before retirement. During the compatibility period, requests using only the legacy timestamp parameters retain their original behavior, includingduration_secondsas an integer number of seconds. Requests using the new whole-hour interval parameters returnactive_secondsinstead, a number in seconds with no fixed number of decimal places, and no longer returnduration_seconds. Mixing the two parameter sets returns HTTP 400. After retirement, legacy timestamp requests will no longer be supported and will not be automatically converted to requests using the new whole-hour interval parameters. The endpoint URL remains unchanged.
Headers
| Header | Required | Description |
|---|---|---|
Authorization | Yes | Bearer <PAT or administrator SAT>; SATs bound to an Identity are not supported. |
Query parameters
Both China and Global use Beijing time (Asia/Shanghai, UTC+08:00). Start and end times must fall exactly on the hour and use the format YYYY-MM-DDTHH:00:00.
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
start_at | string | Yes | — | Query start time, inclusive. Can be supplied only once. |
end_at | string | Yes | — | Query end time, exclusive. Must be later than the start time, with a maximum interval of 744 hours. Can be supplied only once. Must not be later than 00:00:00 on the day after the request date in Beijing time. Hours whose calculations are not yet complete are excluded from the results. |
limit | integer | No | 20 | Number of groups per page, from 1 to 100. Each pagination parameter can be supplied only once. |
after_id | string | No | — | Cursor for the next page. Use the previous page's last_id. Mutually exclusive with before_id. |
before_id | string | No | — | Use the current page's first_id to retrieve the previous page. Mutually exclusive with after_id. |
identity_id | string | No | — | Filter by one Identity. |
identity_ids | string/string[] | No | — | Filter by multiple Identities. Supports comma-separated values or repeated query parameters. |
template_id | string | No | — | Filter by one Template. |
template_ids | string/string[] | No | — | Filter by multiple Templates. Supports comma-separated values or repeated query parameters. |
[start_at, end_at): it includes the start hour and excludes the end hour. For example, 2026-09-14T09:00:00 → 2026-09-14T12:00:00 covers three hours: 09:00–10:00, 10:00–11:00, and 11:00–12:00. The interval can span multiple dates, but both endpoints must fall exactly on the hour and cannot be equal. The API returns grouped totals for the entire interval, not separate hourly results.
Example request
Query usage from 09:00 to 12:00 on September 14, 2026 (three hours, Beijing time), filtered to two Templates and two Identities and grouped by Template. Replace the example IDs with actual resource IDs.
tmpl_123 or tmpl_456 and the Identity is either idn_abc or idn_efg.
Example response
HTTP 200 OK
The values below illustrate the response structure and assume that both Templates have matching records.
template_id. For example, the tmpl_123 row aggregates only matching records for the two Identities above, and active_identities is the deduplicated count of those Identities that actually have matching records. Results are not returned separately for all four Template and Identity combinations. Groups are sorted by the returned credits in descending order, then by ID in ascending order when Credits are equal, and paginated according to limit.
Templates with no matching records are omitted; no zero-filled groups are added. If there are no matching records at all, the response contains data: [] and has_more: false, with both first_id and last_id set to null. Credits that have not been collected for an existing group are treated as 0.
Response fields
| Field | Type | Description |
|---|---|---|
type | string | Always template_usage.list. |
start_at | string | Requested start time in YYYY-MM-DDTHH:00:00 format, inclusive and interpreted in Beijing time. |
end_at | string | Requested end time in YYYY-MM-DDTHH:00:00 format, exclusive and interpreted in Beijing time. |
has_more | boolean | Whether more results are available in the current pagination direction. The initial query checks the forward direction. |
first_id | string/null | Public ID of the first group on this page. Use as before_id to retrieve the previous page. null for an empty page. |
last_id | string/null | Public ID of the last group on this page. Use as after_id to retrieve the next page. null for an empty page. |
data | array | Template usage list. Each page returns at most limit matching groups, and each group aggregates the entire query interval. |
data[].type | string | Always template_usage. |
data[].template_id | string | Template ID for this row. |
data[].active_identities | integer | Deduplicated count of non-empty Identity IDs with activity under this Template anywhere in the query window. |
data[].session_count | integer | Deduplicated count of Sessions in this group with activity in the query window. |
data[].active_seconds | number | Total active time in seconds across all sessions in this group within the query interval. Milliseconds are summed first, then divided by 1000 to convert to seconds. There is no fixed number of decimal places and no additional rounding or truncation. Returns 0 when the duration is zero. |
data[].credits | number | Sum of model Credits and runtime Credits in this group, rounded down to two decimal places after aggregation. Credits that have not been collected are treated as 0. |
Data updates
In Beijing time, calculation of the previous hour's usage starts after minute 05 of each hour. The data becomes queryable once calculation is complete. For example, calculation of usage for [09:00, 10:00) starts after 10:05. Results aggregate only hours within the requested interval whose calculations are complete. Hours whose calculations are not yet complete are excluded, so later queries may return updated results. Data is complete from September 7, 2026 at 22:00:00 Beijing time onward.
Error codes
| HTTP | Type | Code | Trigger |
|---|---|---|---|
| 400 | invalid_request_error | — | Required times are missing, empty, or repeated; the format is invalid; a time is not exactly on the hour; the start is not earlier than the end; the interval exceeds 744 hours; the end is later than midnight on the day after the request date in Beijing time; or timezone, start_date, or end_date is supplied. |
| 400 | invalid_request_error | — | Legacy timestamp parameters are mixed with new whole-hour interval parameters. A parameter with an empty value still counts as supplied. |
| 400 | invalid_request_error | — | In a request using the new whole-hour interval parameters, limit is invalid or outside 1–100, pagination parameters are repeated, both after_id and before_id are supplied, or a cursor exceeds 64 bytes, is not valid UTF-8, or contains control characters. |
| 400 | invalid_request_error | — | During the compatibility period, legacy timestamp parameters fail the original validation rules. |
| 401 | authentication_error | — | Valid credentials are missing or have expired. |
| 403 | permission_error | — | The current credentials lack the permissions required by the API. |
| 500 | api_error | — | The server-side query failed. |

