Codex config.toml: Custom Provider, Base URL, and API Key
Configure Codex CLI and Codex App with config.toml, auth.json, a BetterToken API Key, and the Responses Base URL. Includes setup, examples, and common fixes.
Codex CLI and Codex App share config.toml and auth.json for local tasks. This setup uses a BetterToken API Key through OpenAI Responses.
Locate and back up your files
If you use a custom CODEX_HOME, edit config.toml and auth.json in that directory. Otherwise use ~/.codex on macOS / Linux or %USERPROFILE%\.codex on Windows. CLI and App must use the same directory. WSL has its own user directory.
Fully quit Codex before editing. Back up both files to a private location. Create missing files if needed. Replace existing settings instead of appending duplicate keys or tables; keep unrelated settings.
Minimum working configuration
Edit config.toml
This guide uses user-level config.toml. Put root keys before all TOML tables, not inside [projects."<path>"]; that table stores project trust_level. The selected provider ID must match its table name. For file authentication, remove env_key and experimental_bearer_token from the selected provider.
model_provider = "bettertoken"model = "gpt-6-astra"cli_auth_credentials_store = "file"
[model_providers.bettertoken]name = "BetterToken"base_url = "https://bettertoken.ai/v1"wire_api = "responses"requires_openai_auth = truesupports_websockets = falseThis example uses GPT-6 Astra (gpt-6-astra). For another model, copy its complete ID from the model plaza and replace model. GPT, Kimi, and GLM use the same file-auth structure; automatic setup is available for GPT.
Edit auth.json
auth.json is in the same directory as config.toml. If auth.json does not exist, create it in that directory. Set its contents to the following JSON, replace YOUR_API_KEY with your BetterToken API Key, and save the file.
{ "auth_mode": "apikey", "OPENAI_API_KEY": "YOUR_API_KEY"}Configuration parameters
| Parameter | Purpose and location | Defaults and examples |
|---|---|---|
model_provider | User config root; selects the provider ID defined below. | Defaults to openai; this guide uses bettertoken. |
model | Root; the full Model ID from the model plaza. | Example: gpt-6-astra; replace as needed. |
cli_auth_credentials_store | Root; chooses the login credential store. | This guide sets file to read auth.json in the same directory. |
name | Provider table; a display name only. | BetterToken is not a Model ID. |
base_url | Provider table; the model API Base URL. | Use https://bettertoken.ai/v1; Codex appends /responses. |
wire_api | Provider table; the request protocol. | Only responses is currently supported; it is also the default. |
requires_openai_auth | Provider table; uses OpenAI authentication and its credential store. | Defaults to false; this guide uses true. It is not a switch that preserves login files. |
supports_websockets | Provider table; Responses WebSocket support. | Defaults to false; this guide keeps HTTP/SSE transport. |
auth_mode | In auth.json; selects the authentication mode. | Set to apikey here; this replaces official ChatGPT authentication. |
OPENAI_API_KEY | In auth.json; the API authentication credential. | Replace YOUR_API_KEY with your BetterToken API Key. |
File authentication here switches to API Key mode. To keep your official account, use official-login preservation; do not mix the two modes. They differ by authentication goal, not by CLI, App, or Extension.
Optional tuning
For an organization-managed token helper, see command-backed provider authentication. It is an alternative to this file-authentication example: a provider auth table cannot be combined with env_key, experimental_bearer_token, or requires_openai_auth. Use the helper and configuration supplied by your administrator.
These three settings are optional tuning, not connection requirements. Merge them into the existing [model_providers.bettertoken] table when needed; do not create a duplicate table.
request_max_retries = 4stream_max_retries = 8stream_idle_timeout_ms = 300000| Parameter | Purpose and location | Defaults and examples |
|---|---|---|
request_max_retries | Provider table; maximum HTTP request retries. | Default: 4; adjust for your connection. |
stream_max_retries | Provider table; reconnection retries after a stream interruption. | Default: 5; 8 is an optional custom value. |
stream_idle_timeout_ms | Provider table; stream inactivity timeout in milliseconds. | Default: 300000; this is an idle timeout, not a total task deadline. |
Configuration layers and legacy keys
Do not put model or reasoning settings inside [projects."<path>"]. Project-specific models can use root keys in a trusted project’s .codex/config.toml; provider and authentication settings remain in user config. Current named profiles use NAME.config.toml under CODEX_HOME, selected with codex --profile NAME, not legacy [profiles.NAME] tables or the root profile selector.
Restart and verify
Save both files. In the terminal, start a new Codex CLI session directly:
codexFully quit Codex App, including background processes, then reopen it and create a new local task. Send a short prompt in each client you use. A normal response verifies that client’s connection.
Troubleshooting
For 401, 403, or a sign-in prompt, check the active directory, the Key in auth.json, auth_mode = apikey, cli_auth_credentials_store = file, and requires_openai_auth = true. For provider or model errors, check the matching provider ID, https://bettertoken.ai/v1, wire_api = responses, and the model’s availability. If changes do not apply, check configuration overrides and confirm CLI and App use the same CODEX_HOME.
Related docs
- Complete Codex setup guide
- Configure a custom Base URL in the VS Code Codex extension
- model_provider, base_url, and wire_api explained
- Codex CLI sandbox and approval mode
- What is AGENTS.md?

