Models

A model is identified by an author/model id (the same scheme OpenRouter uses). The catalog aggregates every model offered by active providers. You pick the model, and provider routing decides which provider fulfills it.

Model ids

You can pass either form as the model field in a request body:

FormExampleNotes
author/modelopenai/gpt-4oRecommended. The segment before the first / is the model author.
bare modelgpt-4oAccepted; resolved against the catalog.

The author/model id refers to the model author (e.g. openai, anthropic), not to the provider fulfilling the request. Providers are addressed separately through the provider object.

Dot and hyphen forms

Some models write their version number with a dot upstream and a hyphen in the provider-native id. Onlist publishes one form as the public id and accepts the other as an alias, so both resolve to the same model:

Where it appearsExample
Public id: id, model page URL, sitemapanthropic/claude-opus-4.8
Alias, also accepted in the model fieldanthropic/claude-opus-4-8
canonical_slug in GET /v1/modelsanthropic/claude-opus-4-8

This matches OpenRouter, which publishes the same models under the dot form. Requesting the hyphen form works and is not deprecated; a model page opened at the hyphen URL redirects to the published one. If you persist model ids, persist canonical_slug: it does not move when the published form does.

Listing models

GET /v1/models returns the catalog in the OpenAI/OpenRouter list shape. It is public, no authentication required, and is cached for about 60 seconds. There is one entry per (author, model) aggregated across active, ready listings.

curl https://onlist.io/v1/models

A response looks like this:

{
  "object": "list",
  "data": [
    {
      "id": "anthropic/claude-opus-4.8",
      "name": "Anthropic: Claude Opus 4.8",
      "owned_by": "anthropic",
      "canonical_slug": "anthropic/claude-opus-4-8",
      "created": 1780680536,
      "context_length": 1000000,
      "pricing": { "prompt": "0.0000030000", "completion": "0.0000150000" },
      "supported_parameters": ["tools", "reasoning", "structured_outputs"]
    }
  ]
}

A few honest details about the fields:

  • pricing.prompt / pricing.completion are USD-per-token decimal strings (so "0.0000030000" is $3.00 per million prompt tokens).
  • pricing.overrides appears when the priced provider charges more for long prompts, in OpenRouter's shape: [{ "min_prompt_tokens": 200000, "prompt": "...", "completion": "..." }]. A request whose full prompt is longer than min_prompt_tokens is billed entirely at that entry's prices; pricing.prompt / pricing.completion stay the base (lowest) prices.
  • name is the human-readable display label (Anthropic: Claude Opus 4.8), not a copy of id.
  • canonical_slug is the provider-native form of the id. It stays put when id is published under an alias form, so it is the safer value to store.
  • created is the listing's created_at (when a provider listed the model on Onlist), not the model's release date, a deliberate divergence from OpenRouter.
  • The response carries an X-Onlist-Catalog-Version: 1 header pinning the catalog shape.

Anthropic shape

A request that carries the anthropic-version header gets the catalog in the Anthropic Models API shape instead, the same switch OpenRouter makes. This is what the Anthropic SDK's models.list() and Claude Code's gateway model discovery (CLAUDE_CODE_ENABLE_GATEWAY_MODEL_DISCOVERY=1) receive:

{
  "data": [
    {
      "id": "anthropic/openai/gpt-5.6-sol[1m]",
      "type": "model",
      "display_name": "OpenAI: GPT-5.6 Sol",
      "created_at": "2026-09-22T16:32:12Z",
      "max_input_tokens": 1050000,
      "max_tokens": 128000,
      "capabilities": null
    }
  ],
  "has_more": false,
  "first_id": "anthropic/openai/gpt-5.6-sol[1m]",
  "last_id": "anthropic/openai/gpt-5.6-sol[1m]"
}
  • Every id sits under anthropic/, because Claude Code drops models whose id mentions neither claude nor anthropic. Models with a context window of one million tokens or more end in [1m], which Claude Code reads as the window size.
  • Claude models use the hyphen form (anthropic/claude-opus-5-5) rather than the dotted public id, because Claude Code misreads the dotted form as an older model.
  • Every id in this list is accepted as-is in the model field, with or without [1m].
  • Models that cannot output text are left out. limit, after_id and before_id page the list as in the Anthropic API; without limit the whole list comes back.

Listing models for a key

GET /v1/models/user returns the same list narrowed to what one API key can actually call. It is the authenticated sibling of GET /v1/models: identical entry shape, the same X-Onlist-Catalog-Version: 1 header, projected from the same 60-second catalog snapshot.

Send the API key you already use for inference:

curl https://onlist.io/v1/models/user \
  -H "Authorization: Bearer YOUR_ONLIST_TOKEN"

A missing, unknown or revoked key returns 401. The endpoint is rate limited per credential, 60 requests per minute and 500 per day per account. When nothing survives the filters the body is {"object": "list", "data": []} — never null. A management key is accepted as well, but it stands for the whole account, which carries no model or provider restriction, so it gets the full catalog back.

Three filters run, in this order:

  1. Model access list. If the key carries a model allowlist (“Only allow selected models” in the key drawer), only the models on it are listed.
  2. Denied providers. A model drops out when every listing behind it belongs to a provider the key's routing policy denies.
  3. Allowed providers. If the key's routing policy sets a provider allowlist, only models with at least one allowed provider selling them are listed. This holds even when the key also has "fall back to every provider once the allowlist is exhausted" turned on, which is the default: the list expresses your intent, while the fallback is a runtime safety net for a request already in flight.

zdr and data_collection are per-request parameters rather than key settings, so they never narrow this list. See Provider routing.

This endpoint is for programs holding one specific key — typically the model picker of an IDE agent such as OpenCode or Cline — so the dropdown offers only models that key can really call, instead of surfacing a 403 after the user picks one. If you just pointed base_url at Onlist for ordinary chat calls, you do not need it: keep using the public GET /v1/models, which stays the full catalog and never shrinks because of a key.

The onlist/auto default

Caution

onlist/auto (and the OpenRouter alias openrouter/auto) resolve to one static platform-default model. They do not inspect your prompt and pick the best model per request. These sentinels are request-side routing values; they never appear in the GET /v1/models data[]. Sending an auto sentinel to an endpoint that doesn't support it returns 422.

Model variant suffixes

A : suffix on a model id means one of two things, and Onlist reads them the way OpenRouter does. Only the last : segment is inspected.

Routing shortcuts never change which model you get. They are stripped from the id and only reorder the eligible providers, or, for :online, turn on web search. Without a suffix you get the default Smart order: like OpenRouter's default, traffic is drawn in proportion to the inverse square of each provider's delivered price, adjusted for reliability and speed. See Default routing (Smart).

SuffixEffect
:floorLowest effective price first (same as provider.sort: "price").
:nitroFastest first by measured speed over the last 7 days, combining time to first token and throughput (same as provider.sort: "throughput").
:exactoHonored as the default ordering, which is already a composite quality score. No warning.
:onlineTurns on web search for the request, the same as plugins: [{"id": "web"}]: one search before the model answers. Chat Completions only; on other endpoints it is dropped with a warning. To let the model decide when and how often to search, declare the openrouter:web_search tool instead.
# Route to the cheapest provider for this model
curl https://onlist.io/v1/chat/completions \
  -H "Authorization: Bearer YOUR_ONLIST_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"model": "openai/gpt-4o:floor", "messages": [{"role": "user", "content": "hi"}]}'

Static variants are separate models, not options. Every other suffix, including :free, :batch, :thinking and anything Onlist does not recognize, stays in the model id and is routed to its own listing: deepseek/deepseek-v4:thinking and deepseek/deepseek-v4 are two different products.

Caution

If no provider sells that exact id, the request returns 404 no_listing_for_model. Onlist does not quietly drop the suffix and serve you the base model. There are no :free listings on Onlist today, so those ids have nothing behind them. Full table and the rules for combining the two kinds: Provider routing.

Next steps

  • Provider routing: Choose which provider fulfills a model: only, sort, allow, max_price.
  • Streaming: Stream responses over Server-Sent Events.
  • Web search: What :online, the web plugin and the openrouter:web_search tool do, and what they cost.
  • Usage & cost: Token usage, and where cost actually lives.
  • OpenAPI spec: Full request and response schemas, including GET /v1/models and GET /v1/models/user (YAML download).