Get Usage by Key
GET /api/open/v1/usage/keysRequest parameters
Section titled “Request parameters”| Parameter | In | Type | Required | Default | Description |
|---|---|---|---|---|---|
start_timestamp | query | integer | No | See below | Start time (inclusive), unix seconds |
end_timestamp | query | integer | No | See below | End time (inclusive), unix seconds |
group_by | query | string | No | key_name | Grouping: key_name aggregates by the Key name at the time of the request, merging Keys with the same name into one row; key_id returns one row per Key |
key_id | query | integer | No | — | Filter by Key ID, a positive integer; repeat the parameter for multiple values or separate them with commas. IDs of other users return an empty result |
key_name | query | string | No | — | Exact Key name at the time of the request; repeat the parameter for multiple values. Commas are not supported because names may contain commas |
p | query | integer | No | 1 | Page number, from 1 to 1000000 |
page_size | query | integer | No | 10 | Items per page, from 1 to 1000 |
sort_by | query | string | No | total_tokens | Sort field: key_count (only with group_by=key_name), prompt_tokens, completion_tokens, total_tokens, or amount |
order | query | string | No | desc | Sort direction: asc or desc |
Time range rules:
- Both omitted: the last 30 days.
- Only
start_timestamp: 30 days forward, capped at the current time. - Only
end_timestamp: 30 days backward. - The range can be at most 366 days.
Each multi-value parameter accepts at most 50 values; more returns 400 invalid_request. Explicitly supplied invalid p / page_size return 400; see Pagination.
Request example
Section titled “Request example”curl "https://www.routeapi.ai/api/open/v1/usage/keys?start_timestamp=1726400000&end_timestamp=1729000000&sort_by=total_tokens&order=desc&p=1&page_size=20" \ -H "Authorization: Bearer $ROUTEAPI_MANAGEMENT_KEY"Response example
Section titled “Response example”{ "success": true, "message": "", "data": { "items": [ { "key_name": "bot", "key_count": 2, "prompt_tokens": 5000, "completion_tokens": 1000, "total_tokens": 6000, "amount": 0.20 } ], "total": 1, "page": 1, "page_size": 20, "start_timestamp": 1726400000, "end_timestamp": 1729000000 }}With group_by=key_id, each Key gets its own row, carrying key_id and no key_count:
{ "success": true, "message": "", "data": { "items": [ { "key_id": 12, "key_name": "bot", "prompt_tokens": 3000, "completion_tokens": 600, "total_tokens": 3600, "amount": 0.12 }, { "key_id": 15, "key_name": "bot", "prompt_tokens": 2000, "completion_tokens": 400, "total_tokens": 2400, "amount": 0.08 } ], "total": 2, "page": 1, "page_size": 20, "start_timestamp": 1726400000, "end_timestamp": 1729000000 }}Response fields
Section titled “Response fields”| Field | Type | Description |
|---|---|---|
items[].key_id | integer | Only with group_by=key_id. The Key ID, usable with endpoints such as Get an API Key; 0 means usage not made through an API Key (for example, the Playground) |
items[].key_name | string | group_by=key_name: the Key name at the time of the requests. group_by=key_id: the Key’s current name; if the Key no longer exists or key_id is 0, the name from the Key’s most recent request within the range |
items[].key_count | integer | Only with group_by=key_name. Number of distinct Keys with this name that had consumption in the range |
items[].prompt_tokens | integer | Total input tokens for this row |
items[].completion_tokens | integer | Total output tokens for this row |
items[].total_tokens | integer | Input plus output tokens |
items[].amount | number | Amount consumed by this row (refunds deducted), in the site currency, two decimals |
total | integer | Number of rows: with group_by=key_name, the number of names; with group_by=key_id, the number of Keys (including the row where key_id is 0) |
page | integer | Current page number |
page_size | integer | Effective items per page |
start_timestamp | integer | Effective start time |
end_timestamp | integer | Effective end time |
Errors
Section titled “Errors”| HTTP | code | Scenario |
|---|---|---|
| 400 | invalid_request | Invalid group_by, sort_by, or order, sort_by=key_count with group_by=key_id, a key_id that is not a positive integer, a timestamp that is not numeric or is negative, an invalid range, invalid pagination parameters, or a multi-value parameter with more than 50 values |
| 429 | — | Per-user query rate limit exceeded (default 30/minute); the body may be empty |
For other common error codes, see Platform API errors.
- Key names may repeat:
group_by=key_namemerges Keys with the same name into one row; usegroup_by=key_idwhen you need to tell them apart. No Key value is returned. - Rows are sorted by the
sort_byfield; ties are ordered bykey_name(key_idwithgroup_by=key_id) ascending, so paging is stable. - Records store the Key name at the time of the request; renaming a Key does not rewrite past records. So with
group_by=key_name, usage before and after a rename appears as two rows; thekey_namefilter also matches the name at request time, whereasgroup_by=key_idreturns the current name, so the two may differ. - The sum of
amountacross rows equals the amount in Usage (ignoring rounding). - Only consumption (billing) logs are counted; failed requests are excluded.
- Token counts are raw counts, not millions.
- Amounts use the site display currency; see Get balance.
- Each row’s
amountis rounded independently, so the sum of rows may differ from a total by up to 0.01. - To export to Excel, page through this endpoint with the same filters and collect the
itemsarrays. - This endpoint shares the per-user query rate limit (default 30/minute) with Usage, Account logs, Export logs, and Usage by model. See Rate limits.