API reference
Usage and request logs
Usage summaries, time series, per-model breakdowns and the request log itself, for your organisation.
Requires a signed-in session; see Account API. What each field measures is explained in Usage and request logs.
Common filters
Every endpoint below takes these query parameters:
| Parameter | Meaning |
|---|---|
time_range | How far back to look: a number and a unit, s, m, h or d (30m, 24h, 7d). Default 24h, at most 365d. |
project_id | Only this project. |
key_id | Only this key. |
model_alias | Only this model id (on /analytics/requests, use model). |
If usage data is briefly unavailable, these endpoints answer 503 {"error": "analytics backend unavailable"}: retry, or use a shorter time_range.
GET /analytics/summary
Totals and averages over the window:
{
"time_range": "24h",
"total_requests": 1420,
"avg_e2e_latency_ms": 812.4,
"avg_ttft_ms": 143.2,
"avg_tokens_per_sec": 61.3,
"avg_tokens_per_sec_request": 48.9,
"total_token_usage": 9412338,
"total_prompt_tokens": 8120400,
"total_prompt_cached_tokens": 6230100,
"total_cost_pkr": 61.05
}-
total_prompt_tokensis the prompt tokens of token-priced requests, andtotal_prompt_cached_tokensthe part of them read from cache. The cached tokens are already insidetotal_token_usage: never add them to it. The share cached istotal_prompt_cached_tokens / total_prompt_tokens, whentotal_prompt_tokensis above 0. The same two fields appear in every attribution group. -
total_cost_pkrappears only when you filter bykey_id. -
avg_tokens_per_secis the generation speed of streamed replies;avg_tokens_per_sec_requestis output tokens per second over the whole request, for every chat request, streamed or not. -
Average latency counts successful requests only. Averages over a window with no requests are
null.
GET /analytics/timeseries
One metric over time, in buckets.
| Parameter | Meaning |
|---|---|
metric | Required. volume, latency, ttft, tok_s, tok_s_request, token_usage, cached_tokens (cached prompt tokens per bucket) or cost. |
interval | Bucket width, in the same format as time_range. Default 1h. A window can hold at most 500 buckets. |
group_by | project, key or model. |
{
"metric": "latency",
"interval": "1h",
"group_by": "model",
"time_range": "24h",
"data": [
{"bucket": "2026-08-25T19:00:00+05:00", "group": "paranine/gpt-oss-120b(Global)", "value": 1200.0}
]
}One row per bucket and group that had requests; empty buckets are left out rather than sent as zero. Buckets are in Pakistan time, so a daily bucket starts at midnight PKT. group is a project id, key id or model id: look up names with GET /projects and GET /keys?include_revoked=true.
GET /analytics/requests
The request log, newest first.
| Parameter | Meaning |
|---|---|
status_category | 2xx, 3xx, 4xx or 5xx. |
termination_reason | How the request ended, for example success or client_disconnect; see Errors and retries. |
min_cost_pkr | Only requests that cost at least this much, in rupees. |
search | Matches the request id or your X-P9-Meta-* tags. |
limit, offset | Paging: limit defaults to 50, at most 200. Use total to know when to stop. |
{
"total": 1420,
"limit": 50,
"offset": 0,
"requests": [
{
"req_id": "p9-1787578888306946000-0001",
"timestamp": "2026-08-24T17:34:56.789000+05:00",
"model": "paranine/gpt-oss-120b(Global)",
"status": 200,
"stream": true,
"key": {"id": "e02dcba3-…", "name": "checkout-summariser-prod"},
"project": {"id": "3dbb877d-…", "name": "Assistant"},
"metrics": {
"total_ms": 420,
"client_upload_ms": 4.1,
"gateway_processing_us": 1020,
"ttft_ms": 110,
"tpot_ms": 6.8,
"prompt_tokens": 45,
"prompt_cached_tokens": 30,
"tokens_generated": 40,
"total_tokens": 85,
"tokens_estimated": 0,
"usage_unit": "token",
"usage_amount": 85
},
"financials": {"cost_pkr": 0.04512, "is_byok": 0},
"status_detail": {"termination_reason": "success", "upstream_error": null},
"user_agent": "OpenAI/Python 1.51.0",
"metadata": {"user_tag": "emp-4092", "feature_tag": "ticket_summary"}
}
]
}| Field | Meaning |
|---|---|
req_id | The request's id, as in its X-Request-Id header. If you sent your own X-Request-ID, it's that. |
metrics.*_ms, gateway_processing_us | The request's timings. ttft_ms and tpot_ms are null for requests that didn't stream. |
metrics.tokens_estimated | 1 when the token counts were estimated because the stream ended early, otherwise 0. |
metrics.prompt_cached_tokens | How many of prompt_tokens were read from cache and billed at the cached-input rate. Part of prompt_tokens, never added to total_tokens, unlike cache_creation_input_tokens and cache_read_input_tokens, which are reported outside the prompt. 0 means nothing was cached; null means it was not reported. |
metrics.usage_unit, usage_amount | What the request was billed on, and how much (token for chat and embeddings). |
financials.is_byok | 1 when the request ran on your own provider key, otherwise 0. |
status_detail.upstream_error | When the model failed: upstream_timeout, upstream_unreachable or upstream_error. Otherwise null. |
metadata | Your X-P9-Meta-* tags. |
GET /analytics/attribution
Usage, cost and speed per model, key or project over the window, biggest spender first. Takes group_by (model, the default, key or project) plus the common filters. Cost is included for the whole organisation, not only for a single key.
Something unclear or wrong on this page? Tell us. Machine-readable copies: llms.txt.