Usage report
The usage report returns how many requests and tokens your organization used over time, in fixed time buckets, split the way you choose: by model, workspace, API key, endpoint or billing source. Use it to feed internal dashboards, charge usage back to teams, or spot a key whose traffic suddenly jumps.
For money rather than tokens, use the cost report.
Today the Console’s Usage page shows the same underlying numbers for people (see Usage & cost), and Enterprise organizations have an analytics endpoint with dashboard totals. This report adds time buckets, grouping and filtering for any plan.
Endpoint
GET /v1/organizations/usage_report/messages
Authenticate with an admin key and send syntic-beta: admin-2026-11-01. Covers every request to model endpoints: chat completions, messages, batch items and model calls inside agent sessions.
Query parameters
| Parameter | Required | Description |
|---|---|---|
starting_at | Yes | Start of the range, RFC 3339. Rounded down to the bucket width. |
ending_at | No | End of the range (exclusive). Default: now. |
bucket_width | No | 1m, 1h or 1d. Default 1d. |
group_by[] | No | Repeat for several: model, workspace_id, api_key_id, endpoint, billing_source, user_id. Without it, each bucket has one total row. |
models[] | No | Only these models. |
workspace_ids[] | No | Only these workspaces. |
api_key_ids[] | No | Only these keys. |
billing_source | No | subscription (covered by the plan) or api_credit (paid from credits). |
limit | No | Buckets per page. Defaults and maximums below. |
after_id | No | The last_id from the previous response (next page). |
before_id | No | The first_id from the previous response (previous page). |
bucket_width | Default limit | Max limit | Data available for |
|---|---|---|---|
1m | 60 | 1,440 | The last 7 days |
1h | 24 | 168 | The last 90 days |
1d | 7 | 31 | The life of the organization |
Response
{
"data": [
{
"starting_at": "2026-11-04T00:00:00Z",
"ending_at": "2026-11-05T00:00:00Z",
"results": [
{
"model": "Amara S1.2",
"workspace_id": "wrkspc_01JC0A2C4E6G8J0L2N4Q",
"requests": 18204,
"input_tokens": 41200310,
"cached_input_tokens": 30988100,
"output_tokens": 2410022,
"reasoning_tokens": 0,
"server_tool_use": { "web_search_requests": 412, "web_fetch_requests": 37, "code_execution_seconds": 0 },
"errors": 61
}
]
}
],
"has_more": true,
"first_id": "bkt_01JC6Z9Y8X7W6V5T",
"last_id": "bkt_01JC7A0B2C4D6E8F"
}| Result field | Meaning |
|---|---|
| Grouping fields | Present only for the dimensions in group_by[]. |
requests | Requests that reached a model. |
input_tokens | Prompt tokens not served from the cache. |
cached_input_tokens | Prompt tokens served from the cache. Add the two for the full prompt size. |
output_tokens | Generated tokens, including reasoning tokens. |
reasoning_tokens | The part of output_tokens spent on reasoning, when reasoning is on. |
server_tool_use | Counts for built-in tools that are billed separately. |
errors | Requests that ended in an error and used no tokens. |
Empty buckets are returned with an empty results array so charts have no gaps. Data is complete about 5 minutes after the end of a bucket; the most recent bucket can still grow.
Pages use the same after_id / before_id cursors as every other list. Bucket ids are opaque: pass last_id back unchanged to get the next page.
Examples
# Daily tokens per model for the last week
curl -sS -G https://app.syntic.ai/v1/organizations/usage_report/messages \
-H "Authorization: Bearer $SYNTIC_ADMIN_KEY" \
-H "syntic-beta: admin-2026-11-01" \
--data-urlencode "starting_at=2026-10-29T00:00:00Z" \
--data-urlencode "bucket_width=1d" \
--data-urlencode "group_by[]=model"Errors
Errors use the error envelope.
| Status | type | code | When |
|---|---|---|---|
| 400 | invalid_request_error | invalid_time_range | starting_at is missing, after ending_at, or older than the bucket width allows. |
| 400 | invalid_request_error | invalid_group_by | Unknown grouping dimension. |
| 400 | invalid_request_error | limit_out_of_range | limit above the maximum for the bucket width. |
| 400 | invalid_request_error | invalid_cursor | after_id or before_id is malformed or from a different query. |
| 403 | permission_error | admin_key_required | An inference key was used. |
Build notes for the platform team
- Source is the usage event row written for every request; add composite indexes on organization and time, and keep a daily rollup table for
1dqueries. - Add
workspace_id,endpoint,reasoning_tokensand server-tool counters to the usage row as those features ship. - Never expose the upstream model id; group by the Syntic display name.