OpenRouter logo

Skill

openrouter-analytics-schema

query OpenRouter analytics schema

Covers LLM Reporting Analytics

Description

Discover the OpenRouter analytics schema — available metrics, dimensions, filter operators, and granularities. Use when you need to know what analytics data is queryable, what dimensions you can break down by, or how to map a user's question to the right metric/dimension combination.

SKILL.md

OpenRouter Analytics Schema Discovery

Discover what analytics data is available for querying. The meta endpoint returns live, always-current definitions of metrics, dimensions, filter operators, and granularities.

Prerequisites

Discovery Endpoint

GET https://openrouter.ai/api/v1/analytics/meta
Authorization: Bearer sk-or-v1-...

Or via the openrouter-analytics skill scripts:

cd <openrouter-analytics-skill-path>/scripts && npx tsx discover-schema.ts

Response Shape

{
  "data": {
    "metrics": [
      { "name": "request_count", "display_label": "Request Count", "is_rate": false, "display_format": "number" }
    ],
    "dimensions": [
      { "name": "model", "display_label": "Model" }
    ],
    "operators": [
      { "name": "eq", "value_type": "scalar" }
    ],
    "granularities": [
      { "name": "day", "display_label": "Day" }
    ]
  }
}

Understanding Metrics

Each metric has:

FieldMeaning
nameIdentifier to use in query requests
display_labelHuman-readable label
is_rateWhether this is a ratio/rate (averaged, not summed)
display_formatHow the value should be formatted: number, currency, percent, latency, or throughput

Time Range Limits

Most volume and cost metrics support time ranges up to 365 days with daily granularity. Latency/throughput metrics and some dimensions (provider, origin, country, finish_reason, external_user, context_length_bucket, generation_id) are limited to 31-day time ranges. If a query times out, try narrowing the time range or removing latency/throughput metrics and per-generation dimensions.

Metric Categories

Volume metrics (how much):

  • request_count — number of API requests (up to 365 days)
  • tokens_total, tokens_prompt, tokens_completion — token counts (up to 365 days)
  • reasoning_tokens — tokens used for extended thinking (up to 365 days)
  • cached_tokens — tokens served from cache (up to 365 days)
  • byok_request_count — number of BYOK requests (up to 365 days)
  • guardrail_invoked_count — count of requests that triggered guardrails (31-day limit)
  • response_cached_count — count of responses served from cache (31-day limit)

Cost metrics (how much money):

  • total_usage — total cost in USD, including BYOK inference cost (up to 365 days). Computed as sum(usage) + sum(byok_usage_inference) so it reflects true spend for both credits and BYOK users.
  • byok_usage — BYOK (bring your own key) inference cost in USD (up to 365 days)
  • credits_usage — all charges billed to OpenRouter credits in USD, including BYOK platform fees (up to 365 days)
  • openrouter_usage — non-BYOK inference spend in USD; excludes requests made with user-provided keys (31-day limit)
  • byok_fees — BYOK platform fees in USD; the platform fee portion of credits_usage charged on BYOK requests (31-day limit). credits_usage includes both non-BYOK inference charges and these BYOK platform fees.
  • usage_upstream — provider-side (upstream) cost in USD (up to 365 days)
  • usage_cache — cache cost component in USD (up to 365 days)
  • usage_data — data logging cost adjustment in USD; typically negative when a data logging discount applies (up to 365 days)
  • usage_web — web search cost in USD (up to 365 days)
  • usage_upstream_web — provider-side web search cost in USD (up to 365 days)
  • usage_file — file processing cost in USD (31-day limit)
  • usage_upstream_file — provider-side file processing cost in USD (31-day limit)
  • usage_web_fetch — web fetch cost in USD (31-day limit)
  • usage_upstream_web_fetch — provider-side web fetch cost in USD (31-day limit)

Performance metrics (how fast):

  • avg_latency, p50_latency, p90_latency, p99_latency — response latency in milliseconds
  • avg_throughput, p50_throughput, p90_throughput, p99_throughput — tokens per second

Efficiency metrics (how well):

  • cache_hit_rate — ratio of cached tokens to prompt tokens (0–1)
  • guardrail_invoked_rate — ratio of requests that triggered guardrails
  • response_cached_rate — ratio of responses served from cache

Understanding Dimensions

Each dimension has:

FieldMeaning
nameIdentifier to use in query requests
display_labelHuman-readable label

Dimensions are what you break down by — "show me spend by model" means dimensions: ["model"].

You can combine up to 2 dimensions in a single query (e.g., ["model", "provider"]).

Label Resolution

Some dimensions have their raw IDs automatically resolved to human-readable labels in query results. Data rows contain the resolved display names directly:

DimensionResolved to
api_key_idKey name/label
appApp title or origin URL
userUser name or email address
workspaceWorkspace name

All other dimensions (e.g., model, provider, country) are returned as-is without resolution.

Rows with an empty user value represent traffic not attributed to a specific org member (e.g., API keys created at the org level).

Dimension Categories

Available with all time ranges:

  • model — the OpenRouter model ID (permaslug)
  • variant — model variant (e.g., standard, extended)
  • api_key_id — which API key made the request
  • user — the creator user ID (for org-level queries)
  • workspace — workspace ID
  • app — application ID

Limited to 31-day time ranges:

  • generation_id — unique ID for each generation (use to drill down to individual requests, then inspect via the openrouter-generations skill)
  • provider — upstream provider name
  • origin — request origin/source
  • country — request country
  • finish_reason — why the generation ended (stop, length, etc.)
  • external_user — custom user ID passed by the caller
  • context_length_bucket — bucketed context length (1K, 10K, 100K, etc.)

Classifier Dimensions

Beyond the standard dimensions above, you can group by classifier dimensions — dynamic labels produced by a user-created classifier (e.g., topic, sentiment, category).

  • Use the classifier_dimensions request field to group by classifier-produced values
  • Use the classifier_filters request field to filter on classifier values
  • The classifier must belong to your account (validated server-side)
  • Classifier dimensions/filters limit the query time range to 31 days
  • See the openrouter-analytics-query skill for the full request shape

Mapping Questions to Classifier Queries

Question patternRequest fieldsNotes
"Spend by topic"classifier_dimensions: { classifier_id, dimension_names: ["topic"] } + metrics: ["total_usage"]Single dimension → column aliased to topic
"Only billing-related requests"classifier_filters: { classifier_id, filters: [{ field: "category", operator: "eq", value: "billing" }] }Filters support eq, neq, in, not_in only
"Sentiment breakdown including unclassified"classifier_dimensions: { classifier_id, dimension_names: ["sentiment"], include_nulls: true }Includes rows without classification

Understanding Operators

Filter operators for the filters array in query requests:

OperatorValue TypeMeaning
eqscalarEquals
neqscalarNot equals
gtscalarGreater than
gtescalarGreater than or equal
ltscalarLess than
ltescalarLess than or equal
inarrayIn list
not_inarrayNot in list

Understanding Granularities

Time bucketing for time-series queries:

GranularityUse when
minuteLast few hours, real-time monitoring
hourLast 1–3 days
dayLast week to 3 months
weekLast 3–12 months
monthYear-scale trends

When no granularity is set, the query returns aggregate totals without time bucketing.

Mapping Questions to Queries

Use this guide to translate natural-language questions into the right metric/dimension/filter combination:

Question patternMetricsDimensionsNotes
"How much did I spend?"total_usageAdd granularity for trends
"Which models cost the most?"total_usagemodelOrder by total_usage desc
"How many requests?"request_countAdd model or api_key_id for breakdown
"How many tokens?"tokens_totalUse tokens_prompt / tokens_completion for split
"Which provider is fastest?"avg_latency, p90_latencyprovider31-day limit
"What's my cache hit rate?"cache_hit_ratemodelRate metric — shows per-model caching
"Which API key uses the most?"request_count, total_usageapi_key_id
"Usage over time"request_count or total_usageSet granularity: "day"
"Latency trends"p90_latencySet granularity: "hour", 31d limit
"Usage by country"request_countcountry31-day limit
"How can I save money?"total_usage, cache_hit_rate, tokens_totalmodelSee cost optimization in openrouter-analytics skill
"Show me individual requests"total_usage, tokens_totalgeneration_id31-day limit. Use returned IDs with openrouter-generations skill for full metadata and content
"How much BYOK spend?"byok_usagemodelUp to 365 days
"BYOK vs credits split?"byok_usage, credits_usageBoth up to 365 days
"BYOK platform fees?"byok_feesmodel31-day limit
"Non-BYOK inference spend?"openrouter_usagemodel31-day limit
"How many guardrail triggers?"guardrail_invoked_count, guardrail_invoked_ratemodel31-day limit
"How many cached responses?"response_cached_count, response_cached_ratemodel31-day limit
"Where does my spend go?"usage_upstream, usage_cache, usage_dataFull cost breakdown (up to 365 days)
"Web search costs?"usage_web, usage_upstream_webmodelUp to 365 days
"File processing costs?"usage_file, usage_upstream_filemodel31-day limit
"Web fetch costs?"usage_web_fetch, usage_upstream_web_fetchmodel31-day limit

Filter Value Reference

Several dimensions are label-resolved in query results — the response shows human-readable names, but filters must use the underlying ID. Here's where to find each:

DimensionFilter valueWhere to find it
api_key_idNumeric ID or 64-char SHA-256 hashNumeric ID: generation metadata (api_key_id field). Hash: GET /api/v1/keys (key_hash field). Hashes are auto-resolved server-side. If a hash can't be resolved, a sentinel value returns zero rows (no error).
userClerk user ID (e.g. user_abc123)User settings or org member list — not the display name/email shown in results.
workspaceWorkspace UUIDWorkspace settings page or GET /api/v1/workspaces — not the workspace name shown in results.
appNumeric app IDGeneration metadata (app_id field) or app settings — not the app title shown in results.
modelPermaslug (e.g. openai/gpt-4o)Model page URL or GET /api/v1/models — not the display name.

Other dimensions (provider, origin, country, finish_reason, external_user, etc.) are not enriched — filter values match what's returned in results.

Constraints

  • Maximum 2 dimensions per query
  • Maximum 20 filters per query
  • Maximum 10 classifier dimensions per query
  • Maximum 10 classifier filters per query
  • Maximum 10,000 rows returned per query (default 1,000)
  • group_limit (1–10,000): controls max rows per dimension combination. Auto-computed on time-series queries with dimensions to guarantee full time-window coverage. Set explicitly to cap per-group rows (e.g., top N per model per day).
  • Most volume/cost metrics: up to 365 days with daily granularity
  • Latency/throughput metrics and per-generation dimensions: up to 31 days
  • Classifier dimensions/filters: always limited to 31 days
  • Minute granularity: only available when the time window is ≤ 3 hours
  • Rate-limited to 64 requests per minute

© 2026 YourAI.tools. Every skill from an identity-verified publisher.

Independent catalog. Not affiliated with, endorsed by, or sponsored by Anthropic or any listed publisher. All trademarks belong to their respective owners.