Last updated

Add a Custom Model to Codex — user-models.json & Generic Providers

Custom models in Codex mean adding your own endpoints to the Codex picker through Codex Router’s custom provider and generic providers. Every other provider owns one address; custom owns none — each model names its own endpoint, its own auth, and its own metadata.

What the custom provider is

One custom provider can hold a free community endpoint, a friend’s self-hosted server, and a paid API key at once. A model that needs a key says so on its own row. The provider is never selected for you and never part of the default set, because what it holds is whatever somebody put in it.

Enable it — this costs nothing and asks for nothing:

./bin/model-router codex providers enable custom

On Windows use ./model-router.ps1 codex with the same commands.

The no-credential allowlist boundary

An endpoint reached with no credential is the one thing a registry fragment cannot introduce on its own. Its address has to be allowlisted in src/model-registry.mjs, exactly as an anonymous provider’s is. Otherwise adding a JSON file under config/custom/ would be enough to send your prompts to any host on the internet with nothing to authenticate them.

An endpoint that carries a key, or one that stays on loopback, needs no allowlist entry — the key or the address is already the boundary. That is the deliberate line between “convenient” and “unsafe”.

Generic providers

Generic providers let you register an OpenAI-compatible service as a provider without waiting for a registry entry. For example, a Perplexity search sidecar:

./bin/model-router codex providers generic add perplexity-search \
  --name "Perplexity Search" \
  --base-url https://api.perplexity.ai \
  --adapter openai-chat
./bin/model-router codex providers generic credential perplexity-search set

The credential command never accepts the key as an argument; it prompts for it. The descriptor, credential reference and any per-model binding are private, atomic state.

Search sidecars

For a routed model with no verified search, Codex can use an explicit search sidecar. The binding names one exact routed model and one provider, and is refused for a model that already owns a search capability:

./bin/model-router codex search-sidecar set PROVIDER/MODEL perplexity-search
./bin/model-router codex search-sidecar status PROVIDER/MODEL

Fully quit and reopen Codex after changing a binding so its model catalog refreshes. Removing the generic provider also removes its credential and every dependent sidecar binding.

Curation and verification commands

Discovery, curation and verification build on the same protected user-model state:

CommandPurpose
./bin/discover-models <provider>List what a provider’s live catalog exposes
./bin/curate-models <provider>Select models and metadata to publish
./bin/test-model 'PROVIDER/MODEL' --live --yesLive, quota-consuming check
./bin/refresh-catalogRebuild the merged catalog Codex reads

Curated entries are stored in user-models.json, survive updates, stay editable in place, and are removable by re-running curation and deselecting.

An example free custom model

The registry ships one free custom example: Qwen3.8-27-free-victor on a shared Hugging Face Inference Endpoint. It offers a 262,144-token context, image input, tool calling and roughly 30 requests per minute per IP. Its owner says it will be retired once launch interest fades, so treat it as a model to try, not one to depend on.

The endpoint carries no credential. Use these free routes at your own risk: nobody has agreed to serve you, access is a published exception rather than an entitlement, and it can be narrowed, rate-limited or withdrawn without notice.

FAQ

What is the custom provider in Codex Router? The custom provider owns no fixed address. Each of its models names its own endpoint, auth and metadata, so one provider can hold a free community endpoint, a self-hosted server and a paid API key at once.

Why do some custom endpoints need an allowlist? An endpoint reached with no credential must be allowlisted in src/model-registry.mjs. Otherwise adding a JSON file could send prompts to any host with nothing to authenticate them. A key-carrying or loopback endpoint needs no allowlist entry.

How do I verify a custom model? Use ./bin/test-model ‘PROVIDER/MODEL’ —live —yes for a live, quota-consuming check, then fully quit and reopen Codex so the catalog refreshes.

Related: models overview, installation, how it works, picker troubleshooting.