Codex Desktop
Connect the Codex desktop app to PleumRouter through the user-level config.toml.
Codex Desktop is OpenAI's Codex as an icon app, and it reads the same user file as the CLI, ~/.codex/config.toml. The difference from the CLI is that the app cannot read variables you export in a shell, so the key goes inside the file. For the terminal version, see Codex CLI.
Quick start#
Install the Codex app
Download it from the OpenAI Codex app page. Codex inside the ChatGPT desktop app uses the same config file.
Create an API key
In the dashboard's API keys page, create a
plm_key. A separate key for the app is easy to revoke.pleum wire codexcreates a dedicated key for you.Write config.toml
Pick one. It is the file in your home folder, not one inside a project.
pleum wire codexCreates a dedicated `plm_` key and adds the provider block to `~/.codex/config.toml`.
npm i -g pleumrouter pleum login pleum wire codex # creates a dedicated plm_ key and edits ~/.codex/config.tomlReplace only the key in `Authorization` with your own and save.
model = "gpt-6-sol" model_provider = "pleum" [model_providers.pleum] name = "PleumRouter" base_url = "https://apirouter.pleum.ai/v1" wire_api = "responses" supports_websockets = false [model_providers.pleum.http_headers] Authorization = "Bearer plm_xxxxxxxxxxxxxxxx" # macOS/Linux: ~/.codex/config.toml # Windows: C:\Users\<you>\.codex\config.tomlFully quit and reopen the app
If it lingers in the Dock or tray it still reads the old settings. Quit it completely and reopen it; a reply to one turn means you are connected.
Why use PleumRouter with Codex Desktop?#
- Pay only for what you use from prepaid credits. Credits are deducted separately from the tool maker's subscription.
- Set budgets and limits per key. Daily, weekly and monthly budgets, model allow-lists and team budgets help you manage what an agent spends.
- One key, many models. Pick Claude, GPT, Gemini or open models; automatic retries and fallback cover provider outages; usage shows up in the dashboard.
How it works#
Like the CLI, the app posts OpenAI Responses API requests (POST /v1/responses) to {base_url}/responses. It does not inherit shell environment variables, so it authenticates with a plm_ key in the Authorization: Bearer header under http_headers instead of env_key. pleum wire codex writes the file this way. PleumRouter's behavior and compatibility are the same as Codex CLI.
Configuration reference#
| Setting | Notes |
|---|---|
| Config file~/.codex/config.toml | Put provider settings in this file in your home folder, not in a .codex/config.toml inside a project. On Windows it is C:\Users\<you>\.codex\config.toml. |
| model_provider"pleum" | Points at the [model_providers.pleum] block. |
| base_urlhttps://apirouter.pleum.ai/v1 | Ends at /v1. The app appends /responses. |
| wire_api"responses" | Only the Responses API is used. |
| http_headers.Authorization"Bearer plm_xxxxxxxxxxxxxxxx" | Puts the key in the file. The app cannot read shell variables. |
| supports_websocketsfalse | PleumRouter does not support the WebSocket transport. Leaving it out can make the desktop app fail. |
Choosing models#
Put a PleumRouter catalog ID in model (the example is gpt-6-sol). Look up exact IDs in the model catalog or with GET /v1/models.
These steps assume OpenAI models. Other makers' models connect too, but tool-calling quality can vary by model.
Compatibility#
| Feature | Status | Notes |
|---|---|---|
| Streaming, function tools, image input | Yes | Uses the same /v1/responses endpoint as Codex CLI. Only function tools are converted. |
| Built-in tools (web_search etc.) | No | Not supported; they are skipped in the request. |
| Server compact | No | /v1/responses/compact returns 501. Use local compact. |
| WebSocket transport | No | Keep supports_websockets = false. |
| Key from a shell variable | No | The app cannot read export lines in a shell profile. Use http_headers in the file. |
If you would rather not keep the key in the file#
Use env_key = "PLEUM_API_KEY" in the provider block instead of http_headers, and register the variable where the app can see it: launchctl setenv PLEUM_API_KEY plm_xxxxxxxxxxxxxxxx on macOS, setx PLEUM_API_KEY plm_xxxxxxxxxxxxxxxx on Windows. Fully quit and reopen the app afterwards; on macOS, launchctl setenv is lost on reboot.
Troubleshooting#
| Symptom | Cause and fix |
|---|---|
| Auth error (401) | The app cannot read shell export lines. Put the key in the file with http_headers, or use the variable registration above, then fully quit and reopen the app. |
| Changes have no effect | The app may not have fully quit. Also check that the provider settings are in ~/.codex/config.toml in your home folder, not in a file inside a project. |
| 404 Not Found | Check that base_url is https://apirouter.pleum.ai/v1. Most of the time /v1 is missing or doubled. |
| model not found / Unknown model | The model ID is not in the catalog. Confirm it with GET /v1/models. |
A Model metadata … not found warning appears | The ID is not in Codex's built-in model list, so it falls back to default metadata. It still works, but values such as context length use defaults and performance can suffer. |
| The connection keeps dropping | Check that supports_websockets = false is present. |
Worried pleum wire codex will overwrite other settings | On the first run it backs up the original once as config.toml.pleum.bak. While connected, your existing model and model_provider values are replaced with PleumRouter's, and pleum unwire codex puts them back. |
Cost & security tips#
- Set a budget on the key. A coding agent calls the model many times per task and resends long context. Daily, weekly or monthly budgets on your API key make costs easier to predict.
- Keep the key out of git. Make sure a key in your shell profile or config file never gets committed, and if you suspect a leak, revoke it in the dashboard and issue a new one.
- Check where sensitive code goes. Prompts and code are sent to the provider of the model you pick. Use Data residency and PII masking to control that.