Public read-only interface
Get checked model demand and public model facts. Read the API contract before you use the model records.
01 / Scope
The models route returns ranked OpenRouter demand and checked model facts. It also returns availability states, source details, and page information. The about route defines the current agent contract.
The separate /api/supply feed contains provider supply and supply history. This feed is outside the formal v1 agent schema. It is not part of the /api/v1/models response. This API does not identify underserved models. Demand or missing data does not prove a supply opportunity.
02 / Start
curl "https://model-demand-analytics.vercel.app/api/v1/about"curl "https://model-demand-analytics.vercel.app/api/v1/models?sort=tokens_30d&order=desc&limit=10"curl "https://model-demand-analytics.vercel.app/api/v1/models?model_id=qwen%2Fqwen3-8b"curl "https://model-demand-analytics.vercel.app/api/v1/models?model_id=openai%2Fgpt-oss-120b%3Afree"Decimal quantities use strings. Thus, clients can preserve exact values. This short sample does not include model records.
{
"schema_version": "model-demand.agent-api.v1",
"generated_at": "2026-08-25T12:00:00Z",
"evaluation_cutoff": "2026-08-24T23:59:59Z",
"freshness": {
"state": "fresh",
"fresh_until": "2026-08-26T13:01:00Z",
"reason": "within_expected_update_window"
},
"window": {
"start_date": "2026-07-26",
"end_date": "2026-08-24",
"days": 30
},
"source": {
"name": "OpenRouter",
"url": "https://openrouter.ai/rankings",
"terms_url": "https://openrouter.ai/docs/cookbook/administration/data-api",
"checked_at": "2026-08-25T11:00:00Z",
"license": "CC BY 4.0",
"attribution": "Source: OpenRouter (openrouter.ai/rankings), as of 2026-08-24. Licensed under CC BY 4.0."
},
"query": {
"mode": "list",
"model_id": null,
"sort": "tokens_30d",
"order": "desc",
"limit": 10,
"offset": 0
},
"pagination": {
"total_matching_models": 0,
"offset": 0,
"limit": 10,
"returned_count": 0,
"has_next_page": false
},
"models": []
}03 / Query
All parameters are optional. model_id selects an exact lookup. Do not combine it with list parameters. Unknown or repeated parameters return an invalid-query response.
model_id | string | none | any exact model ID | exact lookup only |
sort | string | tokens_30d | tokens_30d, latest_rank, total_parameters, active_parameters, smallest_quant_checkpoint_bytes, full_sequence_attention_bytes | list mode |
order | string | desc | asc, desc | list mode |
limit | integer | 25 | any integer | 1 to 100 |
offset | integer | 0 | any integer | 0 to 9,007,199,254,740,991 |
04 / Fields
Units are exact contract values. A fraction is a share from 0 to 1. It is not a percentage. Byte values are not GiB values.
schema_version | string | none | no | The version of the model response schema. |
generated_at | string | UTC timestamp | no | The time when the accepted public export was generated. |
evaluation_cutoff | string | UTC timestamp | no | The latest evidence time included in the accepted export. |
freshness | object | none | no | The export freshness result. |
freshness.state | string | none | no | The fresh or stale export state. |
freshness.fresh_until | string | UTC timestamp | yes | The freshness deadline when one is available. |
freshness.reason | string | none | no | The stable reason for the freshness state. |
window | object | none | no | The completed UTC demand window. |
window.start_date | string | UTC date | no | The first window date. |
window.end_date | string | UTC date | no | The last window date. |
window.days | integer | days | no | The fixed 30-day window length. |
source | object | none | no | The demand source and attribution. |
source.name | string | none | no | The demand source name. |
source.url | string | none | no | The public demand source URL. |
source.terms_url | string | none | no | The demand source terms URL. |
source.checked_at | string | UTC timestamp | no | The time when the source terms were checked. |
source.license | string | none | no | The source data license. |
source.attribution | string | none | no | The required source attribution. |
query | object | none | no | The normalized effective query. |
query.mode | string | none | no | The list or exact_model query mode. |
query.model_id | string | none | yes | The exact model ID when requested. |
query.sort | string | none | yes | The effective list sort field. |
query.order | string | none | yes | The effective list sort order. |
query.limit | integer | models | no | The effective result limit. |
query.offset | integer | models | no | The effective result offset. |
pagination | object | none | no | The result page information. |
pagination.total_matching_models | integer | models | no | The number of models that match the query. |
pagination.offset | integer | models | no | The page offset. |
pagination.limit | integer | models | no | The page limit. |
pagination.returned_count | integer | models | no | The number of models in this response. |
pagination.has_next_page | boolean | none | no | True when another result page is available. |
models | array | none | no | The public model result records. |
models[] | object | none | no | One public model result record. |
models[].model_id | string | none | no | The stable public model ID. |
models[].model_release_id | string | none | no | The stable public release ID. |
models[].first_visible_date | string | UTC date | no | The first completed date when the model was visible in the demand data. |
models[].latest_rank | object | none | no | The latest available daily rank. |
models[].latest_rank.value | integer | rank | yes | The latest rank. Null means that the value is unavailable. |
models[].latest_rank.state | string | none | no | The latest-rank availability state. |
models[].latest_rank.reason | string | none | yes | The public reason when the latest rank is unavailable. |
models[].latest_tokens | object | none | no | The latest daily token count. |
models[].latest_tokens.value | string | tokens | yes | The latest daily token count. Null means that the value is unavailable. |
models[].latest_tokens.unit | string | none | no | The fixed unit for models[].latest_tokens. |
models[].latest_tokens.state | string | none | no | The availability state for models[].latest_tokens. |
models[].latest_tokens.reason | string | none | yes | The public reason when models[].latest_tokens is unavailable. |
models[].tokens_7d | object | none | no | The exact 7-day token total. |
models[].tokens_7d.value | string | tokens | yes | The exact 7-day token total. Null means that the value is unavailable. |
models[].tokens_7d.unit | string | none | no | The fixed unit for models[].tokens_7d. |
models[].tokens_7d.state | string | none | no | The availability state for models[].tokens_7d. |
models[].tokens_7d.reason | string | none | yes | The public reason when models[].tokens_7d is unavailable. |
models[].tokens_30d | object | none | no | The exact 30-day token total. |
models[].tokens_30d.value | string | tokens | yes | The exact 30-day token total. Null means that the value is unavailable. |
models[].tokens_30d.unit | string | none | no | The fixed unit for models[].tokens_30d. |
models[].tokens_30d.state | string | none | no | The availability state for models[].tokens_30d. |
models[].tokens_30d.reason | string | none | yes | The public reason when models[].tokens_30d is unavailable. |
models[].share_7d | object | none | no | The exact 7-day demand share. |
models[].share_7d.value | string | fraction | yes | The exact 7-day demand share. Null means that the value is unavailable. |
models[].share_7d.unit | string | none | no | The fixed unit for models[].share_7d. |
models[].share_7d.state | string | none | no | The availability state for models[].share_7d. |
models[].share_7d.reason | string | none | yes | The public reason when models[].share_7d is unavailable. |
models[].share_30d | object | none | no | The exact 30-day demand share. |
models[].share_30d.value | string | fraction | yes | The exact 30-day demand share. Null means that the value is unavailable. |
models[].share_30d.unit | string | none | no | The fixed unit for models[].share_30d. |
models[].share_30d.state | string | none | no | The availability state for models[].share_30d. |
models[].share_30d.reason | string | none | yes | The public reason when models[].share_30d is unavailable. |
models[].share_prior_7d | object | none | no | The exact prior 7-day demand share. |
models[].share_prior_7d.value | string | fraction | yes | The exact prior 7-day demand share. Null means that the value is unavailable. |
models[].share_prior_7d.unit | string | none | no | The fixed unit for models[].share_prior_7d. |
models[].share_prior_7d.state | string | none | no | The availability state for models[].share_prior_7d. |
models[].share_prior_7d.reason | string | none | yes | The public reason when models[].share_prior_7d is unavailable. |
models[].trend | object | none | no | The 7-day demand-share trend. |
models[].trend.direction | string | none | no | The trend direction. |
models[].trend.state | string | none | no | The trend availability state. |
models[].trend.reason | string | none | yes | The reason when trend is unavailable. |
models[].trend.relative_change | string | ratio | yes | The exact relative share change. |
models[].trend.percentage_point_change | string | percentage points | yes | The exact absolute share change. |
models[].facts | object | none | no | The versioned public model facts. |
models[].facts.total_parameters | object | none | no | The total_parameters model fact. |
models[].facts.total_parameters.value | string | parameters | yes | The exact total_parameters value. Null means that the value is unavailable. |
models[].facts.total_parameters.unit | string | none | no | The fixed unit for total_parameters. |
models[].facts.total_parameters.state | string | none | no | The public evidence state for total_parameters. |
models[].facts.total_parameters.reason | string | none | yes | The public reason when total_parameters is unavailable. |
models[].facts.total_parameters.source_url | string | none | yes | The pinned public source URL for total_parameters. |
models[].facts.active_parameters | object | none | no | The active_parameters model fact. |
models[].facts.active_parameters.value | string | parameters | yes | The exact active_parameters value. Null means that the value is unavailable. |
models[].facts.active_parameters.unit | string | none | no | The fixed unit for active_parameters. |
models[].facts.active_parameters.state | string | none | no | The public evidence state for active_parameters. |
models[].facts.active_parameters.reason | string | none | yes | The public reason when active_parameters is unavailable. |
models[].facts.active_parameters.source_url | string | none | yes | The pinned public source URL for active_parameters. |
models[].facts.architecture_type | object | none | no | The architecture_type model fact. |
models[].facts.architecture_type.value | string | architecture | yes | The exact architecture_type value. Null means that the value is unavailable. |
models[].facts.architecture_type.unit | string | none | no | The fixed unit for architecture_type. |
models[].facts.architecture_type.state | string | none | no | The public evidence state for architecture_type. |
models[].facts.architecture_type.reason | string | none | yes | The public reason when architecture_type is unavailable. |
models[].facts.architecture_type.source_url | string | none | yes | The pinned public source URL for architecture_type. |
models[].facts.base_checkpoint_bytes | object | none | no | The base_checkpoint_bytes model fact. |
models[].facts.base_checkpoint_bytes.value | string | bytes | yes | The exact base_checkpoint_bytes value. Null means that the value is unavailable. |
models[].facts.base_checkpoint_bytes.unit | string | none | no | The fixed unit for base_checkpoint_bytes. |
models[].facts.base_checkpoint_bytes.state | string | none | no | The public evidence state for base_checkpoint_bytes. |
models[].facts.base_checkpoint_bytes.reason | string | none | yes | The public reason when base_checkpoint_bytes is unavailable. |
models[].facts.base_checkpoint_bytes.source_url | string | none | yes | The pinned public source URL for base_checkpoint_bytes. |
models[].facts.bf16_weights_bytes | object | none | no | The bf16_weights_bytes model fact. |
models[].facts.bf16_weights_bytes.value | string | bytes | yes | The exact bf16_weights_bytes value. Null means that the value is unavailable. |
models[].facts.bf16_weights_bytes.unit | string | none | no | The fixed unit for bf16_weights_bytes. |
models[].facts.bf16_weights_bytes.state | string | none | no | The public evidence state for bf16_weights_bytes. |
models[].facts.bf16_weights_bytes.reason | string | none | yes | The four automatic-discovery missing-size reasons are: closed_weights: A checked official source says that the release has no public weights. weights_access_unknown: No exact public checkpoint link exists. No checked source says that the weights are closed. open_checkpoint_unavailable: An exact checkpoint claim exists. The collector cannot collect the repository. size_calculation_failed: The collector collected the checkpoint. The checked facts do not support one size. Legacy public BF16 reasons can also occur. |
models[].facts.bf16_weights_bytes.source_url | string | none | yes | The pinned public source URL for bf16_weights_bytes. |
models[].facts.smallest_quant_checkpoint_bytes | object | none | no | The smallest_quant_checkpoint_bytes model fact. |
models[].facts.smallest_quant_checkpoint_bytes.value | string | bytes | yes | The exact smallest_quant_checkpoint_bytes value. Null means that the value is unavailable. |
models[].facts.smallest_quant_checkpoint_bytes.unit | string | none | no | The fixed unit for smallest_quant_checkpoint_bytes. |
models[].facts.smallest_quant_checkpoint_bytes.state | string | none | no | The public evidence state for smallest_quant_checkpoint_bytes. |
models[].facts.smallest_quant_checkpoint_bytes.reason | string | none | yes | The public reason when smallest_quant_checkpoint_bytes is unavailable. |
models[].facts.smallest_quant_checkpoint_bytes.source_url | string | none | yes | The pinned public source URL for smallest_quant_checkpoint_bytes. |
models[].facts.smallest_quant_format | object | none | no | The smallest_quant_format model fact. |
models[].facts.smallest_quant_format.value | string | format | yes | The exact smallest_quant_format value. Null means that the value is unavailable. |
models[].facts.smallest_quant_format.unit | string | none | no | The fixed unit for smallest_quant_format. |
models[].facts.smallest_quant_format.state | string | none | no | The public evidence state for smallest_quant_format. |
models[].facts.smallest_quant_format.reason | string | none | yes | The public reason when smallest_quant_format is unavailable. |
models[].facts.smallest_quant_format.source_url | string | none | yes | The pinned public source URL for smallest_quant_format. |
models[].facts.smallest_quant_bit_width | object | none | no | The smallest_quant_bit_width model fact. |
models[].facts.smallest_quant_bit_width.value | string | bits | yes | The exact smallest_quant_bit_width value. Null means that the value is unavailable. |
models[].facts.smallest_quant_bit_width.unit | string | none | no | The fixed unit for smallest_quant_bit_width. |
models[].facts.smallest_quant_bit_width.state | string | none | no | The public evidence state for smallest_quant_bit_width. |
models[].facts.smallest_quant_bit_width.reason | string | none | yes | The public reason when smallest_quant_bit_width is unavailable. |
models[].facts.smallest_quant_bit_width.source_url | string | none | yes | The pinned public source URL for smallest_quant_bit_width. |
models[].facts.attention_bytes_per_token | object | none | no | The attention_bytes_per_token model fact. |
models[].facts.attention_bytes_per_token.value | string | bytes_per_token | yes | The exact attention_bytes_per_token value. Null means that the value is unavailable. |
models[].facts.attention_bytes_per_token.unit | string | none | no | The fixed unit for attention_bytes_per_token. |
models[].facts.attention_bytes_per_token.state | string | none | no | The public evidence state for attention_bytes_per_token. |
models[].facts.attention_bytes_per_token.reason | string | none | yes | The public reason when attention_bytes_per_token is unavailable. |
models[].facts.attention_bytes_per_token.source_url | string | none | yes | The pinned public source URL for attention_bytes_per_token. |
models[].facts.full_sequence_attention_bytes | object | none | no | The full_sequence_attention_bytes model fact. |
models[].facts.full_sequence_attention_bytes.value | string | bytes | yes | The exact full_sequence_attention_bytes value. Null means that the value is unavailable. |
models[].facts.full_sequence_attention_bytes.unit | string | none | no | The fixed unit for full_sequence_attention_bytes. |
models[].facts.full_sequence_attention_bytes.state | string | none | no | The public evidence state for full_sequence_attention_bytes. |
models[].facts.full_sequence_attention_bytes.reason | string | none | yes | The public reason when full_sequence_attention_bytes is unavailable. |
models[].facts.full_sequence_attention_bytes.source_url | string | none | yes | The pinned public source URL for full_sequence_attention_bytes. |
models[].facts.recurrent_state_bytes | object | none | no | The recurrent_state_bytes model fact. |
models[].facts.recurrent_state_bytes.value | string | bytes | yes | The exact recurrent_state_bytes value. Null means that the value is unavailable. |
models[].facts.recurrent_state_bytes.unit | string | none | no | The fixed unit for recurrent_state_bytes. |
models[].facts.recurrent_state_bytes.state | string | none | no | The public evidence state for recurrent_state_bytes. |
models[].facts.recurrent_state_bytes.reason | string | none | yes | The public reason when recurrent_state_bytes is unavailable. |
models[].facts.recurrent_state_bytes.source_url | string | none | yes | The pinned public source URL for recurrent_state_bytes. |
models[].facts.calculation_sequence_length | object | none | no | The calculation_sequence_length model fact. |
models[].facts.calculation_sequence_length.value | string | tokens | yes | The exact calculation_sequence_length value. Null means that the value is unavailable. |
models[].facts.calculation_sequence_length.unit | string | none | no | The fixed unit for calculation_sequence_length. |
models[].facts.calculation_sequence_length.state | string | none | no | The public evidence state for calculation_sequence_length. |
models[].facts.calculation_sequence_length.reason | string | none | yes | The public reason when calculation_sequence_length is unavailable. |
models[].facts.calculation_sequence_length.source_url | string | none | yes | The pinned public source URL for calculation_sequence_length. |
models[].supply | object | none | no | The model supply state and reserved summary. |
models[].supply.state | string | none | no | The fixed supply state. |
models[].supply.reason | string | none | yes | The public reason when supply is unavailable. |
models[].supply.summary | object | none | yes | The supply summary. It is null unless supply is available. |
models[].supply.summary.route_id | string | none | no | The exact public route ID. |
models[].supply.summary.route_type | string | none | no | The paid, free, batch, or thinking route type. |
models[].supply.summary.collection_finished_at | string | UTC timestamp | no | The supply collection finish time. |
models[].supply.summary.history_ready | boolean | none | no | True when the required supply history is ready. |
models[].supply.summary.listed_endpoints | object | none | no | The listed_endpoints supply metric. |
models[].supply.summary.listed_endpoints.value | integer | endpoints | yes | The listed_endpoints value. Null means that the metric is unavailable. |
models[].supply.summary.listed_endpoints.unit | string | none | no | The fixed unit for listed_endpoints. |
models[].supply.summary.listed_endpoints.state | string | none | no | The availability state for listed_endpoints. |
models[].supply.summary.listed_endpoints.reason | string | none | yes | The public reason when listed_endpoints is unavailable. |
models[].supply.summary.listed_providers | object | none | no | The listed_providers supply metric. |
models[].supply.summary.listed_providers.value | integer | providers | yes | The listed_providers value. Null means that the metric is unavailable. |
models[].supply.summary.listed_providers.unit | string | none | no | The fixed unit for listed_providers. |
models[].supply.summary.listed_providers.state | string | none | no | The availability state for listed_providers. |
models[].supply.summary.listed_providers.reason | string | none | yes | The public reason when listed_providers is unavailable. |
models[].supply.summary.median_input_price_per_million | object | none | no | The median_input_price_per_million supply metric. |
models[].supply.summary.median_input_price_per_million.value | string | usd_per_million_tokens | yes | The median_input_price_per_million value. Null means that the metric is unavailable. |
models[].supply.summary.median_input_price_per_million.unit | string | none | no | The fixed unit for median_input_price_per_million. |
models[].supply.summary.median_input_price_per_million.state | string | none | no | The availability state for median_input_price_per_million. |
models[].supply.summary.median_input_price_per_million.reason | string | none | yes | The public reason when median_input_price_per_million is unavailable. |
models[].supply.summary.median_output_price_per_million | object | none | no | The median_output_price_per_million supply metric. |
models[].supply.summary.median_output_price_per_million.value | string | usd_per_million_tokens | yes | The median_output_price_per_million value. Null means that the metric is unavailable. |
models[].supply.summary.median_output_price_per_million.unit | string | none | no | The fixed unit for median_output_price_per_million. |
models[].supply.summary.median_output_price_per_million.state | string | none | no | The availability state for median_output_price_per_million. |
models[].supply.summary.median_output_price_per_million.reason | string | none | yes | The public reason when median_output_price_per_million is unavailable. |
models[].supply.summary.median_latency_ms | object | none | no | The median_latency_ms supply metric. |
models[].supply.summary.median_latency_ms.value | string | milliseconds | yes | The median_latency_ms value. Null means that the metric is unavailable. |
models[].supply.summary.median_latency_ms.unit | string | none | no | The fixed unit for median_latency_ms. |
models[].supply.summary.median_latency_ms.state | string | none | no | The availability state for median_latency_ms. |
models[].supply.summary.median_latency_ms.reason | string | none | yes | The public reason when median_latency_ms is unavailable. |
models[].supply.summary.median_throughput_tokens_per_second | object | none | no | The median_throughput_tokens_per_second supply metric. |
models[].supply.summary.median_throughput_tokens_per_second.value | string | tokens_per_second | yes | The median_throughput_tokens_per_second value. Null means that the metric is unavailable. |
models[].supply.summary.median_throughput_tokens_per_second.unit | string | none | no | The fixed unit for median_throughput_tokens_per_second. |
models[].supply.summary.median_throughput_tokens_per_second.state | string | none | no | The availability state for median_throughput_tokens_per_second. |
models[].supply.summary.median_throughput_tokens_per_second.reason | string | none | yes | The public reason when median_throughput_tokens_per_second is unavailable. |
models[].supply.summary.median_uptime_percent | object | none | no | The median_uptime_percent supply metric. |
models[].supply.summary.median_uptime_percent.value | string | percent | yes | The median_uptime_percent value. Null means that the metric is unavailable. |
models[].supply.summary.median_uptime_percent.unit | string | none | no | The fixed unit for median_uptime_percent. |
models[].supply.summary.median_uptime_percent.state | string | none | no | The availability state for median_uptime_percent. |
models[].supply.summary.median_uptime_percent.reason | string | none | yes | The public reason when median_uptime_percent is unavailable. |
models[].supply.summary.maximum_context_tokens | object | none | no | The maximum_context_tokens supply metric. |
models[].supply.summary.maximum_context_tokens.value | integer | tokens | yes | The maximum_context_tokens value. Null means that the metric is unavailable. |
models[].supply.summary.maximum_context_tokens.unit | string | none | no | The fixed unit for maximum_context_tokens. |
models[].supply.summary.maximum_context_tokens.state | string | none | no | The availability state for maximum_context_tokens. |
models[].supply.summary.maximum_context_tokens.reason | string | none | yes | The public reason when maximum_context_tokens is unavailable. |
models[].supply.summary.quantizations | array | none | no | The sorted unique quantization names. |
05 / Limits
generated_at is the time when the accepted export was generated. evaluation_cutoff is the latest evidence time in that export. fresh_until is the freshness deadline. Check freshness.state and its reason before you report results.
Demand data contains the OpenRouter top 50 models. Models outside the cutoff do not have separate rows. Missing detail is unknown, not zero.
Unavailable values are unknown. They are not zero. Keep the value, state, and reason together. Do not replace a null value with a number.
Use /api/export when you need daily demand history. The models route returns the checked aggregates for agent queries.
06 / Agents
Select and copy this text into Codex.
Use the public Model Demand Analytics site and API to answer my question about OpenRouter model demand, model size, model facts, or provider supply.
Read https://model-demand-analytics.vercel.app/api/v1/about first. Use https://model-demand-analytics.vercel.app/api/v1/models for ranked demand and checked model facts. Use https://model-demand-analytics.vercel.app/api/export when you need daily demand history. Use https://model-demand-analytics.vercel.app/api/supply when you need provider supply or supply history. This feed is outside the formal v1 agent schema. Use the website only when the API does not contain the required field.
Preserve null or unavailable values as unknown, not zero. State generated_at, evaluation_cutoff, the data window, freshness, and source limits. Separate direct data from inference. Do not call a model underserved or a supply opportunity from the current data because no approved quantitative rule exists. If the available data cannot answer my question, say so.
My question:Select and copy this text into Claude.
Use the public Model Demand Analytics site and API to answer my question about OpenRouter model demand, model size, model facts, or provider supply.
Read https://model-demand-analytics.vercel.app/api/v1/about first. Use https://model-demand-analytics.vercel.app/api/v1/models for ranked demand and checked model facts. Use https://model-demand-analytics.vercel.app/api/export when you need daily demand history. Use https://model-demand-analytics.vercel.app/api/supply when you need provider supply or supply history. This feed is outside the formal v1 agent schema. Use the website only when the API does not contain the required field.
Preserve null or unavailable values as unknown, not zero. State generated_at, evaluation_cutoff, the data window, freshness, and source limits. Separate direct data from inference. Do not call a model underserved or a supply opportunity from the current data because no approved quantitative rule exists. If the available data cannot answer my question, say so.
My question: