QuantTrail API
Send a computer's hardware and what it is for. Get back the local AI models that run well on it, how much memory and context they need, and the commands to download them.
https://quanttrailpicker.com
Getting started
Introduction
The QuantTrail API answers one question: which local AI models run well on this machine, for this job, and how do I get them? It knows about 266 open models (Qwen, Gemma, Llama, Mistral, DeepSeek, Phi, Granite and more), their download sizes in every GGUF format, the memory each needs at a given context length, and where to download them.
You send hardware and a use. You get ranked models with memory estimates, where they run (GPU, unified memory, GPU and RAM, CPU or phone), expected speed, the largest context that fits and, if you ask, ready-made ollama pull and hf download commands. QuantTrail does not host or proxy model files.
| Base URL | https://quanttrailpicker.com |
| Format | JSON in, JSON out. POST bodies must be Content-Type: application/json, up to 16,384 bytes |
| Authentication | Optional API key in X-QuantTrail-Key (authentication) |
| Versioning | v1 changes are additive: new fields and routes, never removed or renamed ones |
| Machine-readable | OpenAPI 3.1 |
Most apps need one call: Get picks for a use. For filters (licenses, formats, families, speed) use Rank models. Building it into an app: the integration guide has detection scripts, a client and a checklist.
Authentication
Calls work without a key, within the anonymous limits. With a key, requests use your account level's limits instead. There are two credentials; do not mix them up.
| Credential | Looks like | Opens | Send as |
|---|---|---|---|
| API key | qt_u3f9a0c12b4d5_ and 40 hex characters | Every public /v1 route, with your level's limits and model families | X-QuantTrail-Key: <key>, or Authorization: Bearer <key> |
| Session token | A Supabase Auth access token (JWT) from signing in | Your account routes: /v1/me, keys, saved computers, voting | Authorization: Bearer <token> |
Get a key on the API page: sign in with a confirmed account, name the key, pick its model family, and copy it. It is shown once; QuantTrail keeps only a hash. If you lose it or it leaks, roll it: the old key stops working at once.
- Keep keys on a machine you control: your server, a desktop app's local settings, a home server. Never in a web page, a browser bundle, a mobile app package or a public repository. Browser and phone clients should call your server, which calls QuantTrail.
- A wrong, rolled or revoked key gets
401 invalid_key. It is not served anonymously instead, so a misconfigured app notices at once. - Keys do nothing on
/v1/meroutes. A stolen key cannot make keys or see the account. - Session tokens expire after about an hour; the website refreshes them. Scripts can sign in with
@supabase/supabase-jsusingauth.urlandauth.keyfrom meta.
The operator's own applications use application keys with per-minute, per-day and allowance limits; refusals add 403 quota_exhausted.
Levels and limits
A key's limits come from its account's level, read on every request, so a level change applies at once. Live values come from plans; these are the current ones.
| Level | Price | Keys | Requests a week | Requests a minute, per key | Model families per key |
|---|---|---|---|---|---|
| Free | 0 | 1 | 1,000 | 10 | 1 |
| Basic 5 | 5 USD a month | 2 | 10,000 | 30 | 3 |
| Basic 10 | 10 USD a month | 3 | 50,000 | 60 | all |
| Basic 15 | 15 USD a month | 5 | 150,000 | 120 | all |
| Basic Lifetime | 250 USD once | 10 | no limit | 120 | all |
- Every level can use every filter, and every key can carry its own limits. Levels differ in keys, volume and families.
- Weekly requests are counted across all of an account's keys, Monday 00:00 UTC to Sunday. Over:
429 weekly_limit. - Per minute is per key, in UTC calendar minutes. Over:
429 rate_limitedwithRetry-After. - Every
/v1request sent with a key counts, catalog reads included;/v1/meroutes never do. Refused requests count too, so do not retry in a loop. - Model families: a Free or Basic 5 key sees only its families everywhere. Other models are left out of lists and answer
404. A key's families can change once every 7 days. - Paid levels are not on sale yet; the operator sets levels by hand.
Without a key, /v1/recommend, /v1/picks and /v1/requirements are limited per client address: a call less than 1 second after the previous one is held about 2 seconds, then answered. Every 10th early call starts a timeout (60 seconds, then 120, then 180) answered with 429 rate_limited and Retry-After. After 30 quiet minutes the client is forgotten.
Key limits
Any key, on any level, can be limited to what one app needs. Set the limits on the API page (Limits for this key) or with Create a key and Update a key. Every request made with the key then sees only models and formats inside them, on every route: lists, picks, rankings, fit checks, requirements and model pages. A model outside them answers 404, and a candidate outside them comes back in unknown_candidates.
| Limit | Keeps |
|---|---|
families | Models in these families. Required on Free (1) and Basic 5 (up to 3), locked for 7 days after a change; optional elsewhere and changeable at any time |
family_kind | "brand" keeps the general-purpose families, "specialized" the ones built for one job or size band (the kind in families) |
quants | Only these formats. Other formats are not listed, ranked or estimated. A known (untracked) format is used when the request names it in quants |
tasks | Models that support at least one of these tasks |
support_levels | Models in these release-date levels |
origins, vendors | Models from these origins or companies |
license: "permissive" | Models with a permissive license |
allow_gated: false | Models without a Hugging Face click-through |
Limits combine with the request: a request can narrow further with its own filters, never widen. When a Free or Basic 5 account moves to a level without a family limit, the family its level forced stops applying and the key opens to every family; families chosen as a limit keep applying.
Errors
Errors are JSON with a stable error code. field names the request field to fix; message explains in plain English.
| Status | error | Meaning |
|---|---|---|
| 400 | invalid_request | A field is wrong, unknown, missing or duplicated. Unknown fields are refused on purpose. Fix it; do not retry unchanged |
| 401 | invalid_key | Key malformed, rolled or revoked |
| 401 | sign_in_required | Account route without a valid session token |
| 403 | quota_exhausted | Application key allowance used up |
| 404 | not_found | Unknown route, hidden model, or a model outside your key's families |
| 405 | method_not_allowed | Wrong method (HEAD included) |
| 409 | key_limit, preset_limit | Too many keys or saved computers |
| 410 | gone | Retired route |
| 413 | payload_too_large | Body over 16,384 bytes |
| 415 | unsupported_media_type | POST without Content-Type: application/json |
| 429 | rate_limited | Too fast; wait Retry-After seconds |
| 429 | weekly_limit | Weekly requests used; resets Monday 00:00 UTC |
| 429 | families_locked, vote_locked | Changed too recently; message says when it opens |
| 500 | internal_error | Server fault; retry later with backoff |
| 503 | sign_in_unavailable, plans_unavailable, votes_disabled | A dependency is down or a feature is off |
A 403 with an HTML body reading "error code: 1010" comes from Cloudflare, not the API: your HTTP library's default User-Agent was refused (Python's urllib is one). Send your own User-Agent.
CORS and caching
- CORS is open to every origin on
/v1: methods GET, POST, OPTIONS; request headersContent-Type,Authorization,X-QuantTrail-Key. - Browsers can read
X-QuantTrail-App,X-RateLimit-Remaining-Minute,X-RateLimit-Remaining-Day,X-Quota-RemainingandRetry-After. Server code can read every header. - Recommendations, votes and account routes are
no-store. Hardware lookups, survey and highlights cache up to 5 minutes; other catalog GETs up to an hour. POST answers and errors never cache. - An answer only changes when the catalog changes (
updated_atin meta, a few times a day) or the hardware does. Caching each answer for an hour per machine is plenty.
Privacy
Requests, hardware and addresses are not stored or logged, with two exceptions the caller controls:
- Phone and board survey. When
hardware.device_modelnames a phone, tablet or board andstore_deviceis notfalse, the model name as sent, the RAM and the hardware class are kept for review (at most three per client session) andsurvey.messagethanks the caller. Desktops are never recorded. Sendstore_device: falseunless your users agreed. - Saved computers, only when a signed-in account saves one.
Votes keep only the hardware class. Keys are stored as hashes. The rate limiter names its counter with a hash of the address.
Objects
The hardware object
Every recommendation route takes the same hardware object. Send everything you know: each field improves the answer, and hardware_resolved.estimate.notes says what was assumed. What you send always wins over a matched device, then a matched chip, then memory type and speed.
Required: platform and ram_gb, unless tier or a device_model found in devices is sent.
Fields
tierstringA hardware class: low, mid, high or max (tiers). Fills every field from a preset; use it when the user does not know their hardware.
platformstringOperating system. Required unless tier or a known device_model is sent.
ram_gbnumberInstalled system RAM in GB (the marketed size: 32, not 31.7). Required unless tier or a known device_model is sent.
cpu_coresintegerLogical processors. Fewer than 6 slows CPU speed estimates one step.
gpu_namestringGraphics card name or WebGL renderer string. A match in GPUs fills gpu and vram_gb you did not send. An unknown name without vram_gb counts as no GPU, with a hint.
gpustringKind of the strongest graphics adapter. apple requires macos. unified is a shared-memory PC (AMD Strix Halo, NVIDIA DGX Spark and similar).
vram_gbnumberDedicated video memory. Used only for nvidia, amd and intel; 90% of it is the GPU budget.
disk_free_gbnumberFree space where models will be stored. Larger downloads are dropped (insufficient_disk).
memory_bandwidth_gbpsnumberSystem memory bandwidth in GB/s. Gives a tokens-per-second estimate for CPU and phone fits. Beats every memory field below.
device_modelstringPhone, tablet or board name or model code (Galaxy S24, SM-S928B, Raspberry Pi 5). A match in devices fills platform, RAM (its smallest option), cores and bandwidth you did not send.
chipstringChip name (Snapdragon 8 Gen 3, Apple A18 Pro). A match in chips fills cores and bandwidth you did not send.
memory_typestringMemory type. With memory_speed_mts and memory_bus_bits it gives the bandwidth when no device or chip did.
memory_speed_mtsnumberMemory transfer rate in MT/s, for example 6000. A typical speed for memory_type is assumed when missing.
memory_bus_bitsintegerMemory bus width. Assumed 128 for DDR (two channels), 64 for LPDDR and phones.
The preferences object
Filters for Rank models and Hardware requirements. Every level may use every filter. If a list comes back empty, excluded counts the models each filter removed: task, context, license, family, vendor, origin, support, insufficient_memory, insufficient_disk, too_large, too_slow, below_smartness_min, not_in_candidates.
Fields
smartness_minnumberDrops formats whose smartness (model score minus the format penalty) is below this.
size_max_gbnumberDrops formats with a larger download.
prioritystringRanking weights: balanced 50% smartness, 30% speed; quality 70/15; speed 30/55; small puts 40% on a small download. See ranking.
min_speedstringDrops formats slower than this.
tasksarray of stringsTask ids from meta (chat, coding, reasoning, vision, tool_use, multilingual). A model must support every listed task.
context_tokensintegerContext length to plan memory for. Models with a smaller window are dropped.
originsarray of stringsVendor origins to keep: china, usa, other.
families_includearray of stringsOnly these model families (families).
families_excludearray of stringsLeave out these model families.
family_kindstringbrand keeps the general-purpose families (Gemma, Qwen, Llama); specialized keeps the families built for one job or one size band (code completion, small devices). The kind of each family is in families.
vendors_includearray of stringsOnly these companies (vendors).
vendors_excludearray of stringsLeave out these companies.
licensestringpermissive keeps Apache, MIT and similar licenses.
allow_gatedbooleanfalse drops models that need a license click-through on Hugging Face.
quant_minstringThe lowest tracked format to consider, by quality order from formats. The default leaves out IQ2_M, Q3_K_M and IQ4_XS; send IQ2_M for small machines.
support_levelsarray of stringsRelease-date levels from meta: current, limited_1, limited_b2, limited_b1, limited_a2, limited_a1. Empty means all.
quantsarray of stringsExact formats to consider, any tracked or known id from formats. Replaces quant_min. Known formats are estimated where the file was not seen.
The recommendation object
Each item in reasoning, speed, recommendations, popular and cpu_recommendations.
Fields
rankinteger1 is the best in its list.
id, namestringCatalog id and display name.
family, generation, vendor, vendor_name, origin, countrystringWhere the model comes from.
quantstringThe chosen format, for example Q4_K_M.
formatobjectid, label ("Balanced"), quality_level (1 to 5), size_pct, compression_pct, description.
params_bnumberBillions of parameters.
file_gb, size_sourcenumber, stringDownload size and whether it was measured from the repository or estimated.
est_memory_gbnumberMemory needed at the requested context: weights x 1.05, plus context, plus 0.5 GB (0.6 GB more for vision).
memory_breakdownobjectweights_gb, context_gb, overhead_gb.
max_context_tokensintegerThe most context that still fits the same memory, rounded down to 1,024. Use it for llama.cpp -c or Ollama num_ctx.
fitstringgpu (all on the graphics card), unified (Apple or shared memory), split (GPU and system RAM), cpu or mobile.
speedstringExpected generation speed class.
est_tokens_per_secondnumber or nullEstimated from memory bandwidth for CPU and phone fits; null otherwise.
smartness, effective_smartness, scorenumberHeuristic quality (1 to 10), after the format penalty, and the ranking score (0 to 100).
tasks, context_tokens, license, gatedmixedWhat the model is for, its window, its license and whether Hugging Face asks for a click-through.
supportobject{id, label, limited}: the release-date level.
min_tierstringThe lowest hardware class that runs it (Q4_K_M, slow or better).
votes, vote_nudgeobject, numberVotes from accounts with the same hardware class, and the points they add or take (up to 5).
downloadsintegerHugging Face downloads, last 30 days.
reasons, warningsarray of stringsPlain-English notes. Show warnings to the user.
linksobjecthuggingface, gguf, ollama addresses.
installobjectOnly with install: true. See the install object.
The install object
Added to each item when the request has install: true.
ollamaisnullwhen Ollama has no tag. Ollama picks its own format for a tag (usually Q4_K_M), which may differ fromquant.ggufisnullwithout a GGUF repository.file,file_urlandcurlarenulluntil the repository has been listed;clialways works (pip install -U huggingface_hub) and fetches every part of a split file (partsabove 1).- Gated models need the license accepted on Hugging Face and
HF_TOKENset where the download runs. - Every command works in Windows cmd, PowerShell and Linux or macOS shells.
How ranking works
For each model, every allowed format is checked against the hardware budgets; the best-scoring format represents the model, and models are sorted by score.
| Machine | GPU budget | System budget |
|---|---|---|
Discrete GPU (nvidia, amd, intel with VRAM) | 90% of VRAM | RAM minus 25% for the OS (3 to 8 GB) |
Mac (apple) or unified PC | 70% of RAM (75% from 36 GB) | none |
| No discrete GPU | none | RAM minus 25% for the OS (3 to 8 GB) |
| Android, iOS | none | 40%, 35% of RAM |
| fit | When | speed |
|---|---|---|
gpu | Fits the GPU budget | fast |
unified | Fits the unified budget | Apple: to 8B fast, to 32B moderate, else slow. Other: to 8B moderate, else slow |
split | Fits GPU plus system | moderate if the GPU holds 60% or more, else slow |
cpu, mobile | Fits system memory | From bandwidth: tokens/s = bandwidth x 0.5 / file size (20 fast, 8 moderate, 3 slow). Without it, by size and cores |
| priority | Smartness | Speed | Small download | Recent | Headroom |
|---|---|---|---|---|---|
balanced | 50% | 30% | 5% | 10% | 5% |
quality | 70% | 15% | 0% | 10% | 5% |
speed | 30% | 55% | 5% | 5% | 5% |
small | 30% | 20% | 40% | 5% | 5% |
Votes from accounts with the same hardware class add or take up to 5 points. Smartness is a heuristic from size, generation and published scores; speeds are estimates, not benchmarks on your machine.
Recommendations
Get picks for a use
POST/v1/picks
- Authentication
- Optional API key. Anonymous calls work within the anonymous limits.
- Counts toward
- Your key's minute and weekly limits; without a key, the anonymous hold.
The call most apps need. Returns two ranked lists for one use: reasoning, the smartest models that fit, and speed, the fastest that fit (moderate speed or better when possible). The same model can be in both.
Picks use fixed profiles and take no filters; use Rank models for those. They leave out base models whose instruct version is listed, re-quantized copies without a GGUF or Ollama download, and CPU-only fallbacks. dnd_dm keeps general chat models of 3B or more.
GET works too, with flat names: /v1/picks?use=chat&platform=windows&ram_gb=16&gpu=nvidia&vram_gb=8&install=true&store_device=false.
Body parameters
usestringRequiredThe job: coding, chat or dnd_dm. The operator can add uses; a wrong value lists the current ones.
context_tokensintegerContext length to plan for. Defaults per use: coding 16384, chat 8192, dnd_dm 16384.
limitintegerItems per list.
installbooleanAdd an install object with Ollama and Hugging Face download commands to each item.
store_devicebooleanPhone and board survey. When device_model names a phone, tablet or board, its name, RAM and class are kept for review unless this is false. Desktops are never recorded. See privacy.
Returns
use, profile, context_tokens, and two lists of recommendation objects, plus:
reasoningarrayUp to limit models, smartest first.
speedarrayUp to limit models, fastest first.
profileobjectlabel, tasks, min_params_b of the use.
hardware_resolvedobjectThe machine as understood: every hardware field, tier, gpu_budget_gb, system_budget_gb and estimate {device, chip, bandwidth_source, notes}. Show notes to the user; they say what was matched and assumed.
capacityobjectfast (GPU or unified budget) and total budgets with the largest model, in billions of parameters, that fits at Q4 and Q8.
hintsarray of stringsWhy a list is empty or degraded. Show them.
catalogobjectupdated_at and model_count.
surveyobject or nullnull unless a phone or board device_model was sent; then {stored, message}.
Errors
400 invalid_request | A field is wrong, unknown or missing; field names it. |
413 payload_too_large | Body over 16,384 bytes. |
415 unsupported_media_type | Send Content-Type: application/json. |
401 invalid_key | The key is malformed, rolled or revoked. |
429 rate_limited | Per-minute key limit, or an anonymous timeout. Wait Retry-After seconds. |
429 weekly_limit | The account used its weekly requests. |
Rank models
POST/v1/recommend
- Authentication
- Optional API key. Anonymous calls work within the anonymous limits.
- Counts toward
- Your key's minute and weekly limits; without a key, the anonymous hold.
One ranked list with every filter: tasks, priority, speed, formats, licenses, families, vendors, origins and release levels. Also returns the same models by downloads, CPU-only results, and how many models each filter removed.
GET takes every hardware and preference field flat, arrays comma-separated: /v1/recommend?platform=linux&ram_gb=64&gpu=nvidia&vram_gb=24&tasks=coding&quants=Q4_K_M,Q6_K&limit=3.
Body parameters
preferencesobjectcandidatesarray of stringsOnly these models. Matches a catalog id, a Hugging Face repo or an Ollama tag (qwen3:8b). Unmatched names come back in unknown_candidates.
include_cpubooleanAdd cpu_recommendations, the same search with the GPU ignored, when a discrete GPU is present.
detectedarray of stringsWhich of platform, cpu_cores, ram_gb, gpu your app detected rather than the user typed. Accepted; it does not change the ranking.
limitintegerItems per list.
installbooleanAdd an install object with Ollama and Hugging Face download commands to each item.
store_devicebooleanPhone and board survey. When device_model names a phone, tablet or board, its name, RAM and class are kept for review unless this is false. Desktops are never recorded. See privacy.
Returns
Lists of recommendation objects, plus:
recommendationsarrayBy score.
populararrayThe same models by downloads.
cpu_recommendationsarray or nullThe same search with the GPU ignored; null without a discrete GPU or with include_cpu: false.
excludedobjectModels removed per filter, for example {"task": 213, "license": 6}.
unknown_candidatesarray of stringscandidates that matched nothing.
hardware_resolvedobjectThe machine as understood: every hardware field, tier, gpu_budget_gb, system_budget_gb and estimate {device, chip, bandwidth_source, notes}. Show notes to the user; they say what was matched and assumed.
capacityobjectfast (GPU or unified budget) and total budgets with the largest model, in billions of parameters, that fits at Q4 and Q8.
hintsarray of stringsWhy a list is empty or degraded. Show them.
catalogobjectupdated_at and model_count.
surveyobject or nullnull unless a phone or board device_model was sent; then {stored, message}.
Errors
400 invalid_request | A field is wrong, unknown or missing; field names it. |
413 payload_too_large | Body over 16,384 bytes. |
415 unsupported_media_type | Send Content-Type: application/json. |
401 invalid_key | The key is malformed, rolled or revoked. |
429 rate_limited | Per-minute key limit, or an anonymous timeout. Wait Retry-After seconds. |
429 weekly_limit | The account used its weekly requests. |
Check one model
POST/v1/models/{id}/fit
- Authentication
- Optional API key. Anonymous calls work within the anonymous limits.
- Counts toward
- Your key's minute and weekly limits when a key is sent. Not limited without one.
Will this model run here, and in which format? Returns every format of one model on the given hardware, with memory, where it runs, speed and the context that fits, and the format the ranking would choose.
Path parameters
idstringRequiredCatalog model id, from list models.
Body parameters
context_tokensintegerContext to plan for.
Returns
model, context_tokens, hardware_resolved, and:
recommendedstring or nullThe format the ranking would choose.
notesarray of stringsPlain-English summary.
formatsarrayOne per tracked format: quant, label, quality_level, file_gb, est_memory_gb, fit (or none), speed, est_tokens_per_second, est_words_per_second, max_context_tokens, short_by_gb (0 when it fits), install.
Errors
400 invalid_request | A field is wrong, unknown or missing; field names it. |
413 payload_too_large | Body over 16,384 bytes. |
415 unsupported_media_type | Send Content-Type: application/json. |
401 invalid_key | The key is malformed, rolled or revoked. |
429 rate_limited | Per-minute key limit, or an anonymous timeout. Wait Retry-After seconds. |
429 weekly_limit | The account used its weekly requests. |
404 not_found | No such model, or outside your key's families. |
Hardware requirements
POST/v1/requirements
- Authentication
- Optional API key. Anonymous calls work within the anonymous limits.
- Counts toward
- Your key's minute and weekly limits; without a key, the anonymous hold.
The reverse question: what hardware does a model, or a set of preferences, need? Send exactly one of models or preferences.
Body parameters
modelsarray of stringsCatalog model ids. Unknown ids come back in unknown_models. Send models or preferences, not both.
preferencesobjectA preferences object. Send models or preferences, not both.
context_tokensintegerContext length to plan memory for. Models with a smaller window are dropped.
limitintegerItems per list.
Returns
catalog, and:
modelsarrayEach model with variants: quant, file_gb, est_memory_gb, min_vram_gb, min_ram_gb_cpu_only, min_unified_ram_gb (null when no common size is enough).
minimum_hardwareobjectFor the first model at Q4_K_M: vram_gb, ram_gb_cpu_only, unified_ram_gb, disk_gb.
unknown_modelsarray of stringsIds that matched nothing.
Errors
400 invalid_request | A field is wrong, unknown or missing; field names it. |
413 payload_too_large | Body over 16,384 bytes. |
415 unsupported_media_type | Send Content-Type: application/json. |
401 invalid_key | The key is malformed, rolled or revoked. |
429 rate_limited | Per-minute key limit, or an anonymous timeout. Wait Retry-After seconds. |
429 weekly_limit | The account used its weekly requests. |
Catalog
List models
GET/v1/models
- Authentication
- Optional API key. Anonymous calls work within the anonymous limits.
- Counts toward
- Your key's minute and weekly limits when a key is sent. Not limited without one.
Every active model with its formats. Filters combine.
Query parameters
familystringFamily id (families).
generationstringGeneration label.
vendorstringVendor id (vendors).
originstringchina, usa or other.
taskstringTask id.
qstringText in the id or name.
include_retiredstring1 adds retired models.
Returns
{catalog, models}. Each model: id, name, family, generation, vendor, vendor_name, origin, country, hf_repo, gguf_repo, ollama, params_b, downloads, likes, released_at, support, papers, base_model, context_tokens, license, license_class, gated, tasks, smartness, min_tier, status and variants (quant_id, file_gb, size_source, file_name, file_parts).
Errors
400 invalid_request | Unknown filter. |
401 invalid_key | The key is malformed, rolled or revoked. |
429 rate_limited | Per-minute key limit, or an anonymous timeout. Wait Retry-After seconds. |
429 weekly_limit | The account used its weekly requests. |
Get a model
GET/v1/models/{id}
- Authentication
- Optional API key. Anonymous calls work within the anonymous limits.
- Counts toward
- Your key's minute and weekly limits when a key is sent. Not limited without one.
One model with every format and a links block for further reading.
Path parameters
idstringRequiredCatalog model id.
Returns
The model fields from list models, plus links: model_card, files, discussions, vendor, gguf, ollama, papers, base_model, demos.
Errors
404 not_found | No such model, hidden, or outside your key's families. |
401 invalid_key | The key is malformed, rolled or revoked. |
429 rate_limited | Per-minute key limit, or an anonymous timeout. Wait Retry-After seconds. |
429 weekly_limit | The account used its weekly requests. |
List families
GET/v1/families
- Authentication
- Optional API key. Anonymous calls work within the anonymous limits.
- Counts toward
- Your key's minute and weekly limits when a key is sent. Not limited without one.
Model families with their vendor and active model count. Family ids are what keys are opened to and what families_include takes.
Returns
An array: id, label, vendor, kind (brand or specialized), default_context, generations, model_count.
Errors
401 invalid_key | The key is malformed, rolled or revoked. |
429 rate_limited | Per-minute key limit, or an anonymous timeout. Wait Retry-After seconds. |
429 weekly_limit | The account used its weekly requests. |
List vendors
GET/v1/vendors
- Authentication
- Optional API key. Anonymous calls work within the anonymous limits.
- Counts toward
- Your key's minute and weekly limits when a key is sent. Not limited without one.
Companies with country, origin and active model count.
Returns
An array: id, name, country, origin, model_count.
Errors
401 invalid_key | The key is malformed, rolled or revoked. |
429 rate_limited | Per-minute key limit, or an anonymous timeout. Wait Retry-After seconds. |
429 weekly_limit | The account used its weekly requests. |
List formats
GET/v1/formats
- Authentication
- Optional API key. Anonymous calls work within the anonymous limits.
- Counts toward
- Your key's minute and weekly limits when a key is sent. Not limited without one.
GGUF formats. tracked formats are used by default; known ones only when named in quants. position orders them by quality for quant_min.
Returns
An array: id, label, quality_level, description, bits_per_weight, smartness_penalty, position, status, size_pct, compression_pct.
Errors
401 invalid_key | The key is malformed, rolled or revoked. |
429 rate_limited | Per-minute key limit, or an anonymous timeout. Wait Retry-After seconds. |
429 weekly_limit | The account used its weekly requests. |
Get metadata
GET/v1/meta
- Authentication
- Optional API key. Anonymous calls work within the anonymous limits.
- Counts toward
- Your key's minute and weekly limits when a key is sent. Not limited without one.
Catalog freshness and every option list, for building forms. Check updated_at to know when cached answers are stale.
Returns
updated_at, model_count, active_models, retired_models, tasks, origins, quantizations (tracked), tiers, support_levels (id, label, before), platforms, gpu_kinds, vote_thresholds, auth (url, key for Supabase sign-in, or null).
Errors
401 invalid_key | The key is malformed, rolled or revoked. |
429 rate_limited | Per-minute key limit, or an anonymous timeout. Wait Retry-After seconds. |
429 weekly_limit | The account used its weekly requests. |
Top models by size class
GET/v1/top-models
- Authentication
- Optional API key. Anonymous calls work within the anonymous limits.
- Counts toward
- Your key's minute and weekly limits when a key is sent. Not limited without one.
The strongest models for five size classes, from phone to 128 GB, for chat and coding, ranked as a search would.
Returns
catalog_updated_at, uses, and classes: each with id, label, hardware and lists per use (rank, id, name, vendor_name, params_b, quant, file_gb, fit, speed, context_tokens, released_at, license, links).
Errors
401 invalid_key | The key is malformed, rolled or revoked. |
429 rate_limited | Per-minute key limit, or an anonymous timeout. Wait Retry-After seconds. |
429 weekly_limit | The account used its weekly requests. |
New and popular
GET/v1/highlights
- Authentication
- Optional API key. Anonymous calls work within the anonymous limits.
- Counts toward
- Your key's minute and weekly limits when a key is sent. Not limited without one.
The most recently released models mixed one-for-one with the most downloaded (last 30 days).
Returns
downloads_window_days and items: kind (new or popular), id, name, vendor_name, params_b, released_at, downloads, support, formats, smallest_gb, largest_gb, ready_download, ollama.
Errors
401 invalid_key | The key is malformed, rolled or revoked. |
429 rate_limited | Per-minute key limit, or an anonymous timeout. Wait Retry-After seconds. |
429 weekly_limit | The account used its weekly requests. |
Hardware lookups
Find a GPU
GET/v1/hardware/gpus
- Authentication
- Optional API key. Anonymous calls work within the anonymous limits.
- Counts toward
- Your key's minute and weekly limits when a key is sent. Not limited without one.
Graphics cards with kind and VRAM. Search for an autocomplete, or resolve a browser's WebGL renderer string to one card. Matching uses the longest name pattern contained in what you send.
Query parameters
qstringWords that must all appear in the name. Up to 20 results.
rendererstringA renderer string, for example ANGLE (NVIDIA, NVIDIA GeForce RTX 3060 Direct3D11). Returns {match}.
Returns
Without parameters, every card. gpus (or match): id, name, gpu_vendor, kind (discrete, integrated, apple, unified), vram_gb, match.
Errors
401 invalid_key | The key is malformed, rolled or revoked. |
429 rate_limited | Per-minute key limit, or an anonymous timeout. Wait Retry-After seconds. |
429 weekly_limit | The account used its weekly requests. |
Find a phone or board
GET/v1/hardware/devices
- Authentication
- Optional API key. Anonymous calls work within the anonymous limits.
- Counts toward
- Your key's minute and weekly limits when a key is sent. Not limited without one.
Phones, tablets and single-board computers with chip, RAM options and memory bandwidth. Send a name or model code as hardware.device_model and the API fills the rest. iOS identifiers such as iPhone17,1 do not match; send the marketing name or the chip.
Query parameters
qstringWords in the name or chip. Up to 10 results.
modelstringA name or model code. Returns {match}.
rendererstringA board's GPU renderer. Returns {match}.
Returns
devices (or match): id, name, kind (phone, tablet, board), platform, soc, ram_options_gb, bandwidth_gbps, cpu_cores, speed_class.
Errors
400 invalid_request | Unknown filter. |
401 invalid_key | The key is malformed, rolled or revoked. |
429 rate_limited | Per-minute key limit, or an anonymous timeout. Wait Retry-After seconds. |
429 weekly_limit | The account used its weekly requests. |
Find a chip
GET/v1/hardware/chips
- Authentication
- Optional API key. Anonymous calls work within the anonymous limits.
- Counts toward
- Your key's minute and weekly limits when a key is sent. Not limited without one.
Phone and board chips with memory type and bandwidth, for devices not in the device list.
Query parameters
qstringWords in the name. Up to 10 results.
namestringA chip name. Returns {match}.
Returns
chips (or match): id, name, memory_type, bandwidth_gbps, cpu_cores.
Errors
400 invalid_request | Unknown filter. |
401 invalid_key | The key is malformed, rolled or revoked. |
429 rate_limited | Per-minute key limit, or an anonymous timeout. Wait Retry-After seconds. |
429 weekly_limit | The account used its weekly requests. |
List hardware classes
GET/v1/hardware/tiers
- Authentication
- Optional API key. Anonymous calls work within the anonymous limits.
- Counts toward
- Your key's minute and weekly limits when a key is sent. Not limited without one.
The four hardware classes. Send hardware.tier for a quick answer when the machine is unknown; the class is also what votes and min_tier use.
Returns
An array: id, label, description, preset (what tier fills in) and minimums (what a machine needs to be in the class).
Errors
401 invalid_key | The key is malformed, rolled or revoked. |
429 rate_limited | Per-minute key limit, or an anonymous timeout. Wait Retry-After seconds. |
429 weekly_limit | The account used its weekly requests. |
Community
Get votes for a model
GET/v1/models/{id}/votes
- Authentication
- None; a session token adds your own vote.
Good and not-good votes from QuantTrail accounts, per hardware class. Never says who voted. With a session token the answer adds your own vote.
Path parameters
idstringRequiredCatalog model id.
Returns
model, total {up, down}, classes (tier, label, description, up, down), percent_after (the class size from which the website shows percentages) and yours ({tier, value, changeable_at} or null).
Errors
404 not_found | No such model. |
Vote on a model
POST/v1/models/{id}/votes
- Authentication
- Session token required (
Authorization: Bearer <token>).
One vote per account per model, with the hardware class it was tried on. A vote can change 48 hours after it was cast or last changed; sending the same vote again is accepted.
Path parameters
idstringRequiredCatalog model id.
Body parameters
valuestringRequiredWhether it was a good fit.
tierstringRequiredHardware class it ran on.
Returns
The same shape as Get votes, with yours filled in.
Errors
401 sign_in_required | No valid session token, or the email is not confirmed. |
503 sign_in_unavailable | The sign-in service did not answer. Retry later. |
429 vote_locked | Changed less than 48 hours ago; message gives the time. |
503 votes_disabled | Voting is switched off. |
Phone and board survey
GET/v1/survey
- Authentication
- Optional API key. Anonymous calls work within the anonymous limits.
- Counts toward
- Your key's minute and weekly limits when a key is sent. Not limited without one.
The most recommended models per phone and board class, from the survey. No counts, names or RAM.
Returns
classes: one per class with its top models.
Errors
401 invalid_key | The key is malformed, rolled or revoked. |
429 rate_limited | Per-minute key limit, or an anonymous timeout. Wait Retry-After seconds. |
429 weekly_limit | The account used its weekly requests. |
Account
List levels
GET/v1/plans
- Authentication
- Optional API key. Anonymous calls work within the anonymous limits.
- Counts toward
- Your key's minute and weekly limits when a key is sent. Not limited without one.
The account levels with their limits. Read this instead of hard-coding the numbers; the operator can change them.
Returns
plans: id, label, position, price_month_usd, price_year_usd, price_once_usd, keys_max, requests_per_week (null: no limit), requests_per_minute, families_max (null: every family), description; and payments.
Errors
401 invalid_key | The key is malformed, rolled or revoked. |
429 rate_limited | Per-minute key limit, or an anonymous timeout. Wait Retry-After seconds. |
429 weekly_limit | The account used its weekly requests. |
Get your account
GET/v1/me
- Authentication
- Session token required (
Authorization: Bearer <token>).
Your level, this week's use across all keys, and your keys.
Returns
email, level (a plan with billing and expires_at), is_admin, week {starts, used, limit}, keys, family_change_days, plans. Each key: id, name, hint, status (active or revoked), families (null: every family), limits (null: none; see key limits), requests_this_week, last_used_at, created_at, rolled_at, families_changeable_at.
Errors
401 sign_in_required | No valid session token, or the email is not confirmed. |
503 sign_in_unavailable | The sign-in service did not answer. Retry later. |
Create a key
POST/v1/me/keys
- Authentication
- Session token required (
Authorization: Bearer <token>).
Makes an API key. The key is in the answer once; copy it then. The API page does the same with a form.
Body parameters
namestringRequiredA name for you, up to 60 characters.
familiesarray of stringsFamily ids the key is for, up to the level's families_max. Required on levels with a family limit; optional elsewhere (empty: every family).
limitsobjectLimits on what the key can see, on any level: vendors, origins, tasks (a model must support at least one), support_levels, quants (lists of ids), family_kind ("brand" or "specialized"), license: "permissive" and allow_gated: false. Empty lists and "any" mean no limit there. null clears every limit. See key limits.
Returns
key (the only time it is shown), note, and the account summary from Get your account.
Errors
401 sign_in_required | No valid session token, or the email is not confirmed. |
503 sign_in_unavailable | The sign-in service did not answer. Retry later. |
400 invalid_request | Name or families missing, unknown or too many. |
409 key_limit | The level's key count is reached; revoke one first. |
Update a key
POST/v1/me/keys/{id}
- Authentication
- Session token required (
Authorization: Bearer <token>).
Renames a key, or changes its model families or limits. On levels with a family limit, families can change once every 7 days per key; everything else changes at once.
Path parameters
idstringRequiredThe key id, for example u3f9a0c12b4d5.
Body parameters
namestringNew name.
familiesarray of stringsNew family ids; empty for every family on a level without a family limit.
limitsobjectLimits on what the key can see, on any level: vendors, origins, tasks (a model must support at least one), support_levels, quants (lists of ids), family_kind ("brand" or "specialized"), license: "permissive" and allow_gated: false. Empty lists and "any" mean no limit there. null clears every limit. See key limits.
Returns
The account summary.
Errors
401 sign_in_required | No valid session token, or the email is not confirmed. |
503 sign_in_unavailable | The sign-in service did not answer. Retry later. |
404 not_found | Not one of your keys. |
429 families_locked | Families changed less than 7 days ago. |
Roll a key
POST/v1/me/keys/{id}/roll
- Authentication
- Session token required (
Authorization: Bearer <token>).
Replaces the secret. The old key stops working at once. Rolling a revoked key makes it active again if the level allows another active key.
Path parameters
idstringRequiredThe key id.
Returns
key (shown once), note and the account summary.
Errors
401 sign_in_required | No valid session token, or the email is not confirmed. |
503 sign_in_unavailable | The sign-in service did not answer. Retry later. |
404 not_found | Not one of your keys. |
409 key_limit | No free key slot for a revoked key. |
Revoke a key
POST/v1/me/keys/{id}/revoke
- Authentication
- Session token required (
Authorization: Bearer <token>).
Turns a key off. It stays in your list as revoked and frees a key slot.
Path parameters
idstringRequiredThe key id.
Returns
The account summary.
Errors
401 sign_in_required | No valid session token, or the email is not confirmed. |
503 sign_in_unavailable | The sign-in service did not answer. Retry later. |
404 not_found | Not one of your keys. |
Saved computers
GET/v1/me/presets
- Authentication
- Session token required (
Authorization: Bearer <token>).
Computers the account chose to save, up to 10. QuantTrail re-checks them as new models arrive and flags when a better one fits.
POST /v1/me/presetssaves one:name,hardware,task(defaultchat),context_tokens,preferences(priority,min_speed,quantsonly).409 preset_limitat 10.GETorPOST /v1/me/presets/{id}reads or changes one.POST /v1/me/presets/{id}/checkre-checks it now;POST /v1/me/presets/{id}/removeremoves it.POST /v1/me/presets/refreshre-checks every computer not checked for a day.
Returns
presets and limit. Each: id, name, hardware, task, context_tokens, preferences, best and largest (top three by score and by size: id, name, quant, score, params_b, file_gb, released_at, download, fit, speed), previous_best, checked_at, better_since, created_at.
Errors
401 sign_in_required | No valid session token, or the email is not confirmed. |
503 sign_in_unavailable | The sign-in service did not answer. Retry later. |
409 preset_limit | Ten computers saved already. |
Followed families
GET/v1/me/watches
- Authentication
- Session token required (
Authorization: Bearer <token>).
Model families the account follows, and the models new in them since it last looked.
POST /v1/me/watcheswith{"family": "qwen"}follows a family.POST /v1/me/watches/seenmarks everything as seen.POST /v1/me/watches/{family}/removestops following.
Returns
watches (family, label, since, seen_at) and new (id, name, family, vendor_name, params_b, released_at, first_seen_at, links).
Errors
401 sign_in_required | No valid session token, or the email is not confirmed. |
503 sign_in_unavailable | The sign-in service did not answer. Retry later. |
Service
Site settings
GET/v1/site
- Authentication
- Optional API key. Anonymous calls work within the anonymous limits.
- Counts toward
- Your key's minute and weekly limits when a key is sent. Not limited without one.
The donation message, donation links and contact address shown on the website.
Returns
donation_message, donations, contact_email.
Errors
401 invalid_key | The key is malformed, rolled or revoked. |
429 rate_limited | Per-minute key limit, or an anonymous timeout. Wait Retry-After seconds. |
429 weekly_limit | The account used its weekly requests. |
Health check
GET/health
- Authentication
- None.
Whether the service is up. Not counted, not limited.
Returns
ok, service, version.