1# Implementing model catalogs for gateways and clouds
2
3> For the complete documentation index, see [llms.txt](https://learn.chatgpt.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to the page URL.
4
5This page is for developers implementing the Codex Models format, which defines
6the model catalog and powers the model picker. If you build an inference
7provider, such as a gateway or cloud service, use this specification to let the
8Codex desktop app and CLI discover your models and use their instructions and
9capability settings.
10
11If you administer an enterprise and want to control the model catalog, see the
12[`model_catalog_url` configuration guidance](https://learn.chatgpt.com/docs/enterprise/roll-out-a-gateway#serve-a-remote-catalog).
13
14To support the format, implement an authenticated catalog endpoint. Fetch your
15upstream provider's current defaults for the requesting Codex version, apply
16your overrides, and return the resulting catalog.
17
18
19
20> Illustration: Cloud providers fetch OpenAI model defaults for the requesting Codex version. Gateways read catalogs from their cloud or upstream providers, then apply caller filtering, aliases, and supported settings. Codex reads the gateway catalog to show available models and use compatible settings. Reads are authenticated at each step, and catalog responses return toward Codex. Optional enterprise or custom model definitions can feed the gateway and need not originate from OpenAI.
21
22
23
24## Implement the catalog endpoint
25
26The default catalog endpoint is `/models` under the provider's `base_url`.
27For example, with `base_url = "https://gateway.example.com/v1"`, Codex requests:
28
29```http
30GET /v1/models?client_version=0.162.1
31Authorization: Bearer <PROVIDER_ACCESS_TOKEN>
32```
33
34Default discovery supports command-backed authentication and Codex-backend
35authentication, such as ChatGPT. For a custom provider using API-key authentication
36without command-backed authentication, set `model_providers.<id>.model_catalog_url`
37explicitly to enable remote discovery. An API key alone doesn't trigger discovery
38at the default path.
39
40Use `model_catalog_url` to choose a full catalog URL, such as
41`https://gateway.example.com/codex/models`. It can also point to the default
42`/v1/models` endpoint. Codex uses this URL directly without appending `/models`.
43For API-key discovery, keep `features.api_key_model_discovery` enabled; it is on
44by default. Custom headers alone don't enable discovery.
45
46Codex sends the selected provider's authentication and configured headers, and
47appends `client_version` and any provider `query_params`. Host the catalog on a
48service authorized to receive those credentials.
49
50Authenticate the caller, fetch the corresponding upstream defaults, apply your
51overrides, and return the complete `ModelsResponse` JSON directly. Give every
52entry a unique, nonempty `slug`. For an explicit `model_catalog_url`, Codex rejects
53redirects and responses larger than 1 MiB. Continue enforcing model access on
54inference requests.
55
56Remove any effective `model_catalog_json` setting from clients using the endpoint:
57the local file takes precedence and prevents remote fetching.
58
59## Match the client's schema
60
61Read the `client_version` query parameter on the catalog request. Codex sends its
62CLI version as `major.minor.patch`, with any prerelease suffix removed. For desktop
63clients, this is the bundled CLI version.
64
65Use the matching `rust-v<version>` tag in the public Codex repository, or the
66exact source commit for a custom build. These links use `rust-v0.162.1`; select
67the revision matching your client:
68
69- Read the [`ModelsResponse` and `ModelInfo` response types](https://github.com/openai/codex/blob/rust-v0.162.1/codex-rs/protocol/src/openai_models.rs) for the schema.
70- Inspect the [bundled `models.json`](https://github.com/openai/codex/blob/rust-v0.162.1/codex-rs/models-manager/models.json) for a complete example. This is catalog data, not a JSON Schema document.
71
72The bundled file is a release snapshot. Fetch current defaults before producing
73your catalog.
74
75## Fetch current upstream defaults
76
77Cloud providers serving OpenAI models fetch defaults from OpenAI. Gateways read
78their cloud or upstream provider's catalog so they retain the deployed model's
79settings and account and region availability. Pass the requesting Codex version
80at each step, and authenticate separately to each endpoint.
81
82To fetch defaults directly from OpenAI, call the Codex models endpoint with the
83same `client_version`. For example, with an OpenAI API key:
84
85```bash
86curl --fail --silent --show-error \
87 'https://chatgpt.com/backend-api/codex/models?client_version=0.162.1' \
88 -H "Authorization: Bearer $OPENAI_API_KEY"
89```
90
91For a ChatGPT integration, use the caller's ChatGPT access token and
92`ChatGPT-Account-ID` header when applicable. Use credentials authorized for the
93upstream endpoint; your gateway's own API key doesn't authenticate to OpenAI.
94
95Parse the full response, including its top-level `models` array. This endpoint
96returns Codex metadata such as instructions, reasoning defaults, tool settings,
97context limits, and service tiers. The public `/v1/models` endpoint doesn't
98supply this catalog.
99
100Refresh these defaults even when the Codex version hasn't changed. Keep requests
101scoped to the intended upstream identity and honor response cache controls:
102catalogs can depend on the caller's access. Keep your overrides separate so you
103can reapply them to fresh defaults.
104
105## Apply provider overrides
106
107Change field values while preserving the version's response structure:
108
109- Filter models to those the caller can use. Map each `slug` to a supported
110 inference route, and adjust `display_name`, `description`, or `priority`.
111 For an alias without a model migration, set `upgrade` to `null`.
112- Set reasoning options, context limits, input modalities, and service tiers to
113 values your model and route support. Keep defaults within the supported
114 choices. For a route without service tiers, clear `service_tiers` and
115 `additional_speed_tiers`, and set `default_service_tier` to `null`.
116- Preserve upstream instructions and tool settings unless you have tested a
117 replacement. Metadata doesn't add model capabilities or grant inference access.
118
119For Bedrock through LiteLLM, apply the
120[required catalog edits](https://learn.chatgpt.com/docs/enterprise/bedrock-through-litellm#prepare-the-client-catalog).
121Test the resulting catalog with each supported Codex version.
122
123## Use the public Rust types
124
125Use crates from the same public Git tag or commit as the client's schema:
126
127- Use [`codex-protocol`](https://github.com/openai/codex/tree/rust-v0.162.1/codex-rs/protocol) for `codex_protocol::openai_models::{ModelsResponse, ModelInfo}`. Parse with `serde_json::from_slice::<ModelsResponse>()`, edit `catalog.models`, and serialize the whole wrapper with `serde_json::to_vec()`. The wrapper handles compatibility fields for model instructions.
128- Use [`codex-models-manager::bundled_models_response()`](https://github.com/openai/codex/blob/rust-v0.162.1/codex-rs/models-manager/src/lib.rs) to load that revision's static bundled catalog as a `ModelsResponse`. It doesn't fetch current upstream defaults.