# RightRank > RightRank aggregates AI model benchmarks, normalizes scores, and recommends models for a task. Base URL: https://rightrank.com/api/v1 Responses are JSON. No authentication is required. OpenAPI 3.1 spec for tool use: https://rightrank.com/api/v1/openapi.json Browsers may call the API from any origin (CORS `Access-Control-Allow-Origin: *`). Rate limit: 300 requests per minute per IP across the API, announced in the `RateLimit-Policy: 300;w=60` header. Over the limit the response is 429 with `{"error": "..."}` and a `Retry-After` header in seconds. ## Dimension vocabulary Use these exact dimension names with rankings and when interpreting recommendations: Text dimensions: general, reasoning, coding, agentic, multimodal, safety, speed, long-context, specialized, language. Media dimensions: text-to-image, image-editing, text-to-video, image-to-video. `multimodal` measures image and video understanding by language models. The media dimensions measure image and video generators (for example FLUX, Imagen, Veo, Sora) by human-preference arena ELO. ## Models GET /api/v1/models?page=1&per_page=100 Lists canonical models. The catalog is historical and non-destructive, so older models remain discoverable. `per_page` is capped at 100. Pagination metadata is returned in the `X-Total-Count`, `X-Page`, and `X-Per-Page` headers. Add `scored=1` to require a score or `benchmark=slug` to rank by one benchmark. Use `q=opus 4.5` to search: every word must appear in the name, slug, or a source's model ID. Use `provider_model_id=claude-haiku-4-5-20251001` to look up the canonical model for an exact identifier returned by a provider API. Every item includes `dimensions_available`, `dimensions_missing`, and `coverage` (`measured`, `of`, and `fraction`) across the dimensions of the model's kind: the four media dimensions when all of its results are media results, all fourteen when it has both text and media results, and otherwise the ten text dimensions. A language model is never counted as missing a media dimension, and an image generator is never counted as missing a text dimension. Example item: {"slug":"anthropic-claude-opus-5-5","name":"Claude Opus 5.5","provider":"Anthropic","provider_model_ids":["claude-opus-5-5"],"base_model_slug":null,"variants":["anthropic-claude-opus-5-5-adaptive-reasoning-max-effort"],"pricing":{"input_per_million_tokens":15.0,"output_per_million_tokens":75.0,"cached_input_per_million_tokens":1.5,"cache_write_per_million_tokens":18.75,"batch_input_per_million_tokens":7.5,"batch_output_per_million_tokens":37.5,"source":"openrouter","captured_at":"2026-09-24T06:00:05.804Z"},"benchmarks_scored":5,"dimensions_available":["coding","general","speed"],"dimensions_missing":["reasoning","multimodal","safety","specialized","agentic","language","long-context"],"coverage":{"measured":3,"of":10,"fraction":0.3}} GET /api/v1/models/:slug Returns model metadata, current pricing, lifecycle metadata, benchmark results grouped by dimension, provider-reported historical results with provenance, and coverage across the published dimension vocabulary. Lifecycle fields include `release_date`, `release_date_source`, `knowledge_cutoff`, `expiration_date`, `availability_status`, `availability_source`, and `availability_checked_at`. Release dates prefer official provider reports, provider snapshot IDs, curated evaluation feeds, repository upload dates, then catalog timestamps; the selected evidence is named in `release_date_source`. Availability describes the named source's latest observation; withdrawn models remain visible for historical comparison. Direct-provider lifecycle observations take precedence over OpenRouter observations, and the newest observation wins within a source. Each independent dimension entry preserves the benchmark-native `value` and units in `scoring_method`; do not compare or average raw values across benchmarks. `normalized_value` is direction-adjusted onto a 0-100 scale relative to the current minimum and maximum recorded for that benchmark (on a log scale for speed benchmarks, whose values span orders of magnitude), so higher is always better. Provider-reported scores are annotations and do not affect rankings. Because the comparison set can change as results are ingested, use `/rankings` or `/recommend` for model selection. Run configurations such as reasoning effort, thinking budget, or image quality tier are variants: benchmark sources score each configuration separately, so each variant is its own model with its own scores. `base_model_slug` names the base API model of a variant (null for a base model), and a base model lists its variants' slugs in `variants`. A variant reports its base model's `provider_model_ids` and, when token-priced, its base model's pricing; an image quality tier keeps its own per-image price when a source lists one, and takes a unit it lacks from its base model. Call the provider with the base model's ID and the configuration as a request parameter. Example: {"slug":"anthropic-claude-haiku-4-5","provider":"Anthropic","provider_model_ids":["claude-haiku-4-5","claude-haiku-4-5-20251001"],"benchmarks_scored":5,"dimensions_available":["general","coding","speed"],"dimensions_missing":["reasoning","multimodal","safety","specialized","agentic","language","long-context"],"coverage":{"measured":3,"of":10,"fraction":0.3},"dimensions":{"coding":[{"benchmark":"terminal-bench","value":45.0,"normalized_value":72.4,"scoring_method":"percentage","higher_is_better":true}]}} ## Pricing List rows, model detail, rankings, and recommendations return the same `pricing` object: USD per million tokens for `input`, `output`, `cached_input` (cache read), `cache_write`, `batch_input`, and `batch_output`; USD `per_image` and `per_video_second` for media generators; plus `source`, `captured_at`, and `withdrawn_on`. A price is `null` when the source does not publish it. When no price is known, every price is `null` and `reason` says why: `subscription_only` (no API, for example Midjourney), `conversion_unknown` (billed per token with no published tokens per image, for example MAI-Image), `open_weights_only` (weights with no first-party API price), or `no_priced_offer`. `source` is `provider` (official first-party prices), `openrouter`, or `artificial_analysis`, each ingested every 6 hours; every run records its token prices, or its media prices, with one shared `captured_at`. A source's price counts only if it comes from that source's latest run of that kind, so a price a source no longer lists is ignored. Among those, a snapshot with token prices wins (it carries the model's media price too), then `provider` over `openrouter` over `artificial_analysis`; `per_image` and `per_video_second` are picked separately, each from the best of those snapshots that has it. When a media unit comes from another source than `source`, `sources` names the source of each media unit, for example `{"per_image": "provider", "per_video_second": "openrouter"}`. A price of a withdrawn offer has `withdrawn_on` set to the date the provider removed it and `captured_at` set to the date the price took effect (for example Sora 2 Pro at $0.30 per 720p second from 2025-10-06 until 2026-09-24). It is history, not a current offer. It overrides reseller prices for that model, because resellers cannot serve a model its provider removed, and rankings and recommendations do not use it for `value` or affordability. A model that no source currently lists keeps its newest recorded price. ## Speed sources The `speed` dimension has two sources, named in each score's `source`: `artificial_analysis` and `rightrank_probe`. RightRank probes active models on the 1st of each month (deprecated and retiring models every 90 days) through OpenRouter, pinned to the model's first-party provider with no fallbacks. Each model gets 5 streamed runs of a fixed prompt that asks for about 500 tokens, with `max_tokens` 2048 and the model's default reasoning, and 5 runs of a request with one tool, with `max_tokens` 200. `max_tokens` includes reasoning tokens; OpenAI pro models ignore it. The probe benchmarks are TTFT, Time to First Answer Token, Output Tokens/sec, Generation Tokens/sec incl. Reasoning, Total Time, Tool Call TTFT, and Tool Call Total Time, each suffixed "(RightRank Probe)". They follow Artificial Analysis definitions: TTFT ends at the first token, including reasoning; Time to First Answer Token ends at the first answer token, after any thinking; Tool Call TTFT ends at the first tool-call token, not at prose or reasoning; Output Tokens/sec counts tokens after the first token, and for reasoning models only answer tokens after the first answer token, because hidden or summarized reasoning is not streamed. Output Tokens/sec is left out when the answer arrives in fewer than 10 chunks; some reasoning models (for example OpenAI pro models) deliver the whole answer at once, which measures the network, not the model. Generation Tokens/sec incl. Reasoning is a RightRank-only measure: every generated token, reasoning included, divided by the whole request time; compare it across reasoning models, and use Output Tokens/sec to compare with Artificial Analysis. A model whose endpoint cannot call tools still gets text results. Each run has an outcome: `ok`; `truncated` (an answer cut off at `max_tokens`); `no_answer_within_budget` (`max_tokens` spent, often on hidden reasoning, before any answer); or `no_answer` (no answer for another reason, for example prose instead of a tool call). A run without an answer gives no TTFT, Time to First Answer Token or Output Tokens/sec value, so it cannot rank as fast; its Generation Tokens/sec and Total Time still count. `value` is the median. `p90` is the slow tail: the 90th percentile for times and the 10th percentile for tokens/sec. `metadata` holds `p90`, `runs` (runs with a value), `outcomes` (outcome counts of the latest probe's runs in that scenario, for example `{"ok":4,"no_answer_within_budget":1}`), `max_tokens`, `region`, and `route` (for example `openrouter:anthropic`), `samples` (each run's value in the latest probe), and `history` (`at`, `median`, and `p90` of the last 12 probes, oldest first). Benchmark pages show `ok` runs of attempted runs, for example 4/5. Models without a first-party provider on OpenRouter are not probed. A monthly spend cap applies, so the most expensive models can be missing. A missing or zero measurement is not stored, and a probe that gives no value for a metric removes the model's earlier probe score for it. ## Media sources `text-to-image` has Text-to-Image Arena ELO from Artificial Analysis and Chatbot Arena Text-to-Image from LMArena. `image-editing`, `text-to-video`, and `image-to-video` have the Image Editing, Text-to-Video, and Image-to-Video Arena ELO from Artificial Analysis. All are ingested every 6 hours. Artificial Analysis scores carry `metadata` with `rank`, `ci95` (for example `-12/12`), and `appearances`. Media prices come from official provider price pages (`provider`) and the OpenRouter image and video APIs (`openrouter`), synced every 6 hours, 40 minutes after the Artificial Analysis and 10 minutes after the LMArena ingestion, so new generators get prices in the same cycle. Prices attach only to models that a benchmark source already lists. `provider` prices are a curated table of official API prices from Google (Vertex AI and Gemini API), OpenAI, Runway, Black Forest Labs, BytePlus, Alibaba Cloud, Kling, PixVerse, MiniMax, and xAI, each with its source page in the code; official prices win over OpenRouter. `per_image` is the lowest listed price for one image of about 1 megapixel; for quality tiers (GPT Image) it is the medium tier. Prices billed per megapixel count as one image. Prices billed per output token are converted with the provider's published tokens per image (Gemini image models and GPT Image models); other token-billed models have no `per_image`. `per_video_second` is the lowest listed 720p price, or the default-resolution price when no 720p price is listed, without audio when that is cheaper, and without 4K, video input, or continuation surcharges. Seedance video tokens are converted at 720p and 24 frames per second, and Gemini Omni video tokens at the published tokens per 720p second. Generators that no source prices (for example Midjourney, which has no API, and MAI-Image) have null prices and a `reason`. Media rankings and cost minimization compare `per_image` for image dimensions and `per_video_second` for video dimensions. GET /api/v1/pricing?page=1&per_page=100 Lists the current `pricing` object of every priced model, with `model`, `model_slug`, `provider`, `provider_model_ids`, and `variant_of`. Paginated like `/models`. ## Benchmarks GET /api/v1/benchmarks Lists benchmark definitions. Filter with `category=dimension`. Example item: {"slug":"terminal-bench","name":"Terminal-Bench","category":"coding","higher_is_better":true,"models_scored":42} GET /api/v1/benchmarks/:slug Returns one benchmark with `description`, `scoring_method`, `source`, `url`, `models_scored`, the recorded raw `minimum` and `maximum`, and `last_scored_at`. GET /api/v1/benchmarks/:slug/leaderboard?limit=50 Alias of `/rankings/:slug`. ## Providers GET /api/v1/providers Lists providers with a stable `slug`, the `name` used as `provider` on other items, `url`, and `models` (catalog model count). ## Provider-reported evaluations GET /api/v1/provider_reports Lists dated provider evaluation reports with the original source URL. These historical, provider-reported results are stored separately from independent benchmark scores and do not affect composite rankings. GET /api/v1/provider_reports/:slug Returns every captured result from one report, including the evaluated model, benchmark, category, value, unit, run configuration, internal-evaluation flag, and notes. ## Dimensions GET /api/v1/dimensions Reports global data availability for every published dimension. `populated: false` means no model has a result in that dimension, rather than that every model performed poorly. Example item: {"name":"agentic","benchmarks":10,"benchmarks_with_results":5,"models_scored":42,"populated":true} ## Rankings GET /api/v1/rankings Returns current top models grouped by dimension. GET /api/v1/rankings/:benchmark_or_dimension?limit=50 Ranks models for one benchmark or dimension. `limit` is capped at 500. Variants rank as their own rows; `variant_of` names the base model slug (null for a base model), and the same field appears on `/recommend` items. Dimension rankings include `cost` in `cost_unit` (`million_tokens` for input plus output, `image`, or `video_second`) and `value`, the average normalized score per unit of cost. Example item: {"rank":1,"model":"Claude Opus 5.5","model_slug":"anthropic-claude-opus-5-5","provider":"Anthropic","provider_model_ids":["claude-opus-5-5"],"variant_of":null,"score":94.2} ## Recommendations GET /api/v1/recommend?task=coding&minimize=cost&limit=10 Maps free-text task and minimization terms onto the published dimensions. This is the preferred endpoint for choosing a model across benchmarks. `recommendation_score` is a normalized 0-100 task-fit score; higher is better. Cost minimization weights performance at 80% and affordability at 20%; affordability compares prices in the unit of the most-weighted requested dimension (tokens, images, or video seconds), and a model without a price in that unit gets none. Top-level `measurement_status` is `complete`, `partial`, or `unavailable`; `dimensions_available` and `unmeasured_categories` identify whether the requested dimensions have any results. An unavailable request returns an explanatory `message` and an empty recommendation list. Each result includes `dimensions_missing`, a 0-1 `coverage_fraction`, and `coverage` counts for the dimensions requested by the task, so callers can distinguish an unmeasured requested dimension from a low score. Example: {"categories":{"coding":1},"minimize":"cost","measurement_status":"complete","dimensions_available":["coding"],"unmeasured_categories":[],"recommendations":[{"model":"Claude Opus 5.5","model_slug":"anthropic-claude-opus-5-5","provider_model_ids":["claude-opus-5-5"],"variant_of":null,"recommendation_score":92.4,"category_scores":{"coding":98.1},"dimensions_missing":[],"coverage_fraction":1.0,"coverage":{"measured":1,"of":1,"fraction":1.0}}]}