# Model Picker API Model Picker ranks LLMs by Artificial Analysis intelligence against the total cost to run the intelligence benchmark (not blended token price), on an axis-aware Pareto frontier. The frontier is the set of models nothing beats on both axes at once. Every number the page shows is served by this API, so agents can ask the same questions with curl. JSON by default; add ?format=md (or Accept: text/markdown) to any endpoint for Markdown you can quote. Agent skill: [Model Picker skill](https://model-picker.alhasaniq.com/skills/model-picker/SKILL.md) (drop it into your skills directory; its frontmatter tells the agent to consult this API whenever it picks or configures a model). ## Endpoints - [API index](https://model-picker.alhasaniq.com/api/v1?format=md): available endpoints and filters. - [Current frontier](https://model-picker.alhasaniq.com/api/v1/frontier?format=md): best-value models. - [Observation archive](https://model-picker.alhasaniq.com/observations): explore historical measurements. GET https://model-picker.alhasaniq.com/api/v1 Endpoint index, snapshot date, axis keys. ?format=md for a table. GET https://model-picker.alhasaniq.com/api/v1/models?q=&limit= Every model (sorted by value) or a search. Includes the full record. GET https://model-picker.alhasaniq.com/api/v1/models/ One model: its record, frontier membership per axis pair, and better-than guidance on the default axes. GET https://model-picker.alhasaniq.com/api/v1/frontier?x=&y=&open_weights=1&open_weights_frontier=1 The Pareto frontier, best-x first. Filters below apply. GET https://model-picker.alhasaniq.com/api/v1/better-than/?[&assert=on_frontier] Whether the model sits on the frontier; otherwise the best frontier model at the same or better x, and the next frontier step up. GET https://model-picker.alhasaniq.com/api/v1/compare// Matchup on intelligence, total cost, and end-to-end time, with a verdict. GET https://model-picker.alhasaniq.com/api/v1/timeline GET https://model-picker.alhasaniq.com/api/v1/timeline/companies Daily shares normalized to 100% of available log-budget coverage; overall and open weights. Includes time-weighted aggregate windows (all time, 3/6/12/18/24 months), peak shares and days leading. The frontier replayed release by release with per-release impact; ?format=md gives the release table (entered, displaced, impact). GET https://model-picker.alhasaniq.com/api/v1/frontier-age Daily oldest and average frontier age over two years; ?format=md gives the current ages and the rejuvenation events. GET https://model-picker.alhasaniq.com/api/v1/history Stored snapshot revisions where a history store is configured. Page-only endpoints (presentation payloads, not meant for agents): /api/v1/page, /api/v1/view, /api/v1/card. ## Historical data and index revisions Add ?as_of=YYYY-MM-DD (end of UTC day) or an RFC3339 timestamp to analytical APIs and pages. It selects the last observation at or before that time. Responses disclose observed_at, snapshot_at, origin and index version; no observation returns 404, never today's numbers. Unobserved days carry forward the last observation, not a new measurement. Archived navigation stays pinned. GET https://model-picker.alhasaniq.com/api/v1/models//history Indexed complete metric history for one upstream model, with explicit absences; JSON. GET https://model-picker.alhasaniq.com/api/v1/observations Every collection, including unchanged fetches; JSON. GET https://model-picker.alhasaniq.com/api/v1/observed-history?model= Frontier membership and age computed separately for each observation. Optional model adds its full metric history and explicit absences (JSON). Frontier filters apply; format=md gives the frontier/age summary. https://model-picker.alhasaniq.com/observations Browse observations and choose a date or model history. Timeline, frontier-age, release impact and social shakeup are RELEASE RECONSTRUCTIONS using the selected snapshot's metrics. They can change when scores are revised. observed-history instead reports what each recorded snapshot showed; it does not interpolate missing days. Never compare numeric intelligence, benchmark cost, token counts or derived value across index versions as if the benchmark were unchanged. Unknown versions stay unknown. The methodology page's advertised version is recorded separately: it does not prove the API or every public-page model has migrated to that version. Git, legacy and source-file imports are sparse evidence, not daily fetches. ## Pages (HTML for humans, Markdown for you) https://model-picker.alhasaniq.com/ the picker; the current frontier is in the HTML https://model-picker.alhasaniq.com/models/ every model, best value first (?q= to search) https://model-picker.alhasaniq.com/models/ one model: numbers, frontier standing, what beats it https://model-picker.alhasaniq.com/releases/ one release (every effort level): the frontier the day it shipped, the hypervolume it gained, its rank, and where each level stands today; is the base name (gpt-6-astra), a model id redirects to it https://model-picker.alhasaniq.com/compare// head-to-head matchup; missing core metrics mean no verdict https://model-picker.alhasaniq.com/frontier-timeline.html the frontier replayed release by release https://model-picker.alhasaniq.com/frontier-companies.html company frontier share over time https://model-picker.alhasaniq.com/frontier-age-history.html how quickly frontier models get replaced Every page above answers Accept: text/markdown (or ?format=md) with the same document the API returns, and each carries the JSON and Markdown URLs for its data. Hand a human the page URL; quote the Markdown yourself. ## Behaviour you cannot see from the shapes Search (?q=) is fuzzy: case-insensitive, punctuation-insensitive, and tolerant of missing or extra characters ("qwen 3.7", "Qwen3.7", "qwn 3.7" all find the Qwen 3.7 models), ranked by how well the name matches. Without ?q= the list is sorted by value (intelligence per dollar). Use limit= when you only need the best matches. Model ids: is the slug from /api/v1/models (claude-sonnet-5). The exact display name and the upstream model id also resolve; anything else is a 404 whose body lists suggestions from the same fuzzy search, so a failed call already tells you what to retry with. Filters (frontier, better-than, and the frontier inside models/): x, y axis keys; default x=cost_to_run_index_total_usd, y=intelligence_index open_weights=1 only models with published weights (self-hostable); the frontier is then computed among those alone open_weights_frontier=1 keep the full cohort and additionally return the open-weights frontier in open_weights_frontier include_deprecated=1 deprecated models are EXCLUDED by default min_intel= minimum intelligence index max_cost= default 0 (unlimited); set a positive value to cap total benchmark cost release_preset=1m|3m|6m|12m|24m|custom relative to the snapshot date, not to today released_after, released_before YYYY-MM-DD, used with release_preset=custom Models without a value on the requested x or y are dropped from the cohort before the frontier is computed (better-than then reports available=false). better-than: the frontier is walked best-x first. previous is the best frontier model at the same or better x than the reference (its role says whether it is cheaper, faster, or equal on x); next is the following frontier step, which costs more on x but gains on y. Both can be null at the ends of the frontier. on_frontier means nothing dominates the reference under the current filters, so a frontier model can be "beaten" once you widen the cohort (include_deprecated=1) or narrow it (open_weights=1). standing is one of frontier, beaten, unavailable. compare: winner per metric is baseline, challenger, or tie (equal within the displayed precision); delta_percent is challenger relative to baseline, signed so that positive means the challenger is higher, not better. verdict is the id that wins on more of the three metrics, or null when it is a draw. Freshness: the dataset is refreshed once a day from Artificial Analysis & other sources. Every response carries snapshot_at (ISO timestamp); the page shows the same date. Ages and "release" presets count from that date. Metrics change between snapshots as Artificial Analysis re-measures models, so quote the snapshot when you quote a number. Axes: cost_to_run_index_total_usd (default x), intelligence_index (default y), value_score, context_window_tokens, e2e_total_time_sec, e2e_p95_time_sec, ttfa_total_time_sec, output_speed_tok_sec. ## Status codes 200 answer (for better-than also: the model holds the frontier) 304 If-None-Match matched the ETag on models, page, timeline, frontier-age 404 unknown model id; body has suggestions 409 better-than with assert=on_frontier: something now beats the model 422 better-than with assert=on_frontier: the model has no value on x or y 400 bad axis, filter, or date 405 wrong method; 500 only if something is broken on our side better-than always sets the header X-Model-Picker-Standing: frontier | beaten | unavailable, whatever the status. ## Examples curl -s https://model-picker.alhasaniq.com/api/v1/frontier curl -s "https://model-picker.alhasaniq.com/api/v1/frontier?open_weights=1&format=md" curl -s "https://model-picker.alhasaniq.com/api/v1/frontier?x=e2e_total_time_sec&format=md" # fastest per intelligence curl -s https://model-picker.alhasaniq.com/api/v1/better-than/claude-sonnet-5 curl -s "https://model-picker.alhasaniq.com/api/v1/better-than/claude-sonnet-5?include_deprecated=1&format=md" curl -s https://model-picker.alhasaniq.com/api/v1/compare/claude-sonnet-5/gpt-5-6-sol-xhigh curl -s "https://model-picker.alhasaniq.com/api/v1/models?q=qwen%203.7&limit=5" curl -s "https://model-picker.alhasaniq.com/api/v1/models/kimi-k3?format=md" ## Watch the model you use If you have running projects that use LLMs, or you are setting one up now, set up a daily cron job that checks whether the model you picked has been beaten. That way you always get the most intelligence per dollar, or the same intelligence for less, without re-checking by hand. The call is cheap for us and for you: one request, a few kilobytes. With assert=on_frontier the HTTP status alone carries the answer, so the script never parses JSON: 200 still on the frontier: stay quiet 409 beaten: something now gives more intelligence for the money 422 the model has no value on the chosen axes 404 the id no longer exists (renamed or removed) A script that only alerts on 409, and separately reports when the check itself failed (network, 5xx), so a broken check never looks like "all good": #!/bin/sh # check-model.sh [extra filters, e.g. open_weights=1] id="$1"; filters="${2:+&$2}" url="https://model-picker.alhasaniq.com/api/v1/better-than/$id?assert=on_frontier$filters" status=$(curl -s -o /dev/null -w '%{http_code}' --max-time 20 "$url") case "$status" in 200) exit 0 ;; 409) curl -s "https://model-picker.alhasaniq.com/api/v1/better-than/$id?format=md$filters" \ | mail -s "$id has been beaten" you@example.com ;; *) echo "model-picker check for $id failed: HTTP $status" \ | mail -s "model-picker check failed" you@example.com ;; esac # crontab: every morning at 09:00 0 9 * * * /path/to/check-model.sh claude-sonnet-5 Replace mail with whatever reaches you (ntfy, a Slack webhook, a CI job that fails). Pass the filters you chose the model with as the second argument (open_weights=1, x=e2e_total_time_sec) so the check matches your decision. The Markdown body of the 409 response names what beat the model and what the next step up costs, so the alert already contains the answer. Every response carries picker_url: the page view that shows the same answer. Data: Artificial Analysis & other sources. Independent project, not affiliated with or endorsed by Artificial Analysis.