Catalog curation

Third-party OpenAI-compatible clients (Jan, Chatbox, and most others) offer exactly the models GET /v1/models returns. The full catalogue is hundreds of entries, which makes those pickers unusable. Catalog curation lets you store two allowlists on your account so the listing shows a short, relevant selection instead.

Curation is account-wide: every API key on the account sees the same curated listing. An unauthenticated request (no API key) always sees the full catalogue.

The two lists

Model allowlist: public model IDs ({provider}/{creator}/{model}). When non-empty, only these models are listed.

Any ID /v1/chat/completions accepts is accepted here, in the same form. That includes the version-less shorthand: writing mistral/mistralai/mistral-small allowlists whichever version that name currently resolves to, and keeps tracking it as new versions land. Your entry is stored exactly as you wrote it, so a shorthand stays a shorthand and is not silently rewritten to today’s version.

Adding a region makes the entry a pin: mistral/mistralai/mistral-small/fr-par lists that model with its regions[] narrowed to fr-par alone. Without a region, the model lists with every region it serves and auto-routing picks one per request.

Region allowlist: locodes (e.g. fi-hel) and/or two-letter country codes (e.g. de, which matches every locode in Germany). When non-empty, each listed model’s regions[] is trimmed to the matching regions; a model left with no region drops out of the listing. A global region always survives, because it names the absence of a region commitment rather than a place, so a model served only globally stays listed under any region list.

One caveat: eu is a provider bloc code, not a country. An eu entry matches only regions published under the literal eu code. To curate EU-wide, list the countries you want (de, fr, fi, …).

The lists apply independently: use either one alone, or both.

Namespaced entries follow their own rules:

  • auto/<creator>/<model> entries appear exactly when their underlying model backs one of your allowlisted IDs. Every routable model has one, including models served by a single provider. The region list never affects them, because auto-routing picks its own region per request.
  • alias/<name> entries are always listed. An alias is itself curation: you created it on purpose, so no list needs to repeat that decision.

Managing the lists

In the app: the Model Catalog page, with pickers for models and regions.

On the API, GET/PUT /v1/catalog with your API key:

Bash
curl https://api.lowrouter.ai/v1/catalog \
  -H "Authorization: Bearer $LOWROUTER_API_KEY" \
  -X PUT -H "Content-Type: application/json" \
  -d '{
    "model_allowlist": [
      "aws-bedrock/openai/gpt-oss-20b",
      "anthropic/anthropic/claude-sonnet-5"
    ],
    "region_allowlist": ["ie-dub", "de"]
  }'

That listing shows two models: the Bedrock one trimmed to its Dublin and Frankfurt regions (ie-dub by locode, de-fra via the country code), and the Anthropic one whole, since it is served only from global, which always survives a region list.

PUT replaces both lists wholesale, so send the entire desired state. An empty (or absent) list means “show everything”, so {"model_allowlist": [], "region_allowlist": []} resets the account to the full catalogue.

Every entry is validated: a model ID must be one the router would route, and a region must be one currently served. Anything else comes back as a 400 naming each offending entry, and nothing is stored, so a typo can never silently curate the wrong thing.

Entries you already have stored are exempt from re-validation: if a model you allowlisted is later delisted, it never blocks saving the rest of your selection. A stale entry hides nothing; remove it whenever you like (once removed, it validates as new again).

Display-only, not a security boundary

Curation changes what GET /v1/models advertises, and nothing else. A hidden model ID still resolves on GET /v1/models/{id} and still routes on completions. Do not use these lists to restrict what a key is allowed to call. An enforced per-key allowlist (requests to hidden models rejected with a 403) is a separate, planned feature.

Interaction with other filters

The ?jurisdiction= and ?modality= query filters apply on top of curation: the listing is first curated to your lists, then faceted by the request. A model your lists admit can still be excluded by a facet, and vice versa.