selan.ai Gateway Reactor
Apps

Docs · Codex

Run Codex on your company's accounts

One command instead of codex, and every argument passes through. Same keys, same limits, same Usage and Logs as everything else. For how the pieces fit together, start at the docs.

Get started

What do I need before I start?

Codex is a prerequisite. Selan launches it; it does not bundle it. Without it on your PATH you get:

codex not found on PATH; install Codex CLI from https://developers.openai.com/codex

You also need the selan binary and a session. If you have neither yet, both are two commands: see Install and Sign in. Nothing about signing in is Codex-specific — one session serves every client.

A ChatGPT subscription is not required to run Codex through Selan. Codex 0.156 and later fetch your company's model list without one. Older versions only ask for it while signed in to ChatGPT.

How do I run Codex through Selan?

selan codex

That is the whole change: selan codex instead of codex. Every argument passes through verbatim, so anything you ran before still runs — flags, subcommands, codex exec, all of it.

Codex then talks to your company's gateway rather than your own ChatGPT account. Your requests spend against whatever provider keys an owner connected, show up as you in Usage, and appear in Logs with the model that served them.

What does Selan write to my Codex config?

The first time you run it, Selan adds a provider block to ~/.codex/config.toml and tells you it did:

note: wrote selan's provider block to /Users/you/.codex/config.toml

Said once, and only when something changed — not on every launch. This is what lands:

# >>> selan managed — do not edit, `selan codex` rewrites this block >>>
[model_providers.selan]
name = "Selan"
base_url = "https://gw.selan.ai/openai/v1"
model_catalog_url = "https://gw.selan.ai/openai/v1/models"
wire_api = "responses"
request_max_retries = 1
stream_max_retries = 2
env_http_headers = { "x-selan-model" = "SELAN_MODEL", "x-selan-repo" = "SELAN_REPO" }
env_key = "SELAN_CODEX_TOKEN"
env_key_instructions = "Run `selan codex` — it exports this for the session."
# <<< selan managed <<<
  • Only the block between the markers is ours. The rest of your config is left alone: your own providers, profiles and settings stay exactly as you wrote them.
  • Do not edit inside the markers. selan codex rewrites the block whenever it changes — a new gateway URL, say — and your edit goes with it.
  • The credential is not in the file. env_key names a variable, and selan codex exports it for that launch and no longer.
  • A bare codex fails closed. Run Codex by hand and the variable is not set, so it stops rather than quietly spending your company's account. That is deliberate, and it is why the block names a variable instead of a command.

On the dev channel the block is [model_providers.selan-dev] and sits beside the production one. Both can live in the same file.

Does Codex get my company's connectors?

Yes. selan codex brings the same connectors selan claude does, and they appear in Codex's /mcp beside your own servers.

  • Most are passed for that launch only. Nothing is written to your config for them. Selan's own connectors use your session and need no sign-in; another shows Not logged in until you run selan codex mcp login name once.
  • A connector on your company's own OAuth client (Google, Slack Personal, HubSpot) is written to a second block in ~/.codex/config.toml, because Codex reads a client secret from nowhere else. The file is readable by you alone, the block is rewritten on every launch, so a connector your company switches off is gone on the next one, and selan logout removes it. These sign in on http://localhost:53280/callback; a mcp_oauth_callback_port of your own wins, and the launch says so.
  • Your own server wins. A server you define under the same name, in your config or with -c, replaces the company's.
  • Codex speaks streamable HTTP only, so a connector served over SSE alone is left out.

A Codex sign-in to a Google connector lasts about an hour: Codex cannot ask Google for a refresh token. Sign in again when it lapses.

Choosing a model

Which models are in Codex's /model picker?

Type /model in Codex and your company's own models are in the list, in place of the built-in one. Pick one the way you pick any other, with no flag to pass.

Select model
Switch between models. Your pick becomes the default for new sessions.
>1. GPT-6.1 Sol Workhorse model for coding and everyday work.
2. GPT-6 Astra Frontier intelligence for the most demanding work.
3. GPT-5.6 Terra Older balanced model for straightforward work.
4. Claude Sonnet 5 Most efficient for everyday tasks
↑/↓ to move · enter to select
Every row is a model in your company's Codex picker, with its description, or its context window where it has none. Row 4 is a Claude model an owner added to the Codex picker; Selan translates between the two protocols, so it answers like any other row.

A pick means the model, not one provider's copy of it. If your company has the same model on more than one account, choosing it here leases them in the order an owner set, so a provider that is out of quota falls through to the next instead of failing the request.

While Codex is signed in to ChatGPT, a launch that names no model starts on the one you last chose, with --model or in /model. Selan remembers it per company. Before you have chosen one, the launch starts on the first model in the list.

Codex 0.156 and later ask for this list whether or not they are signed in to ChatGPT. selan codex turns on Codex's model discovery for each launch. Older versions only ask while signed in to ChatGPT; otherwise you keep the built-in list. The models are still there and still leased the same way, you just pick them with --model instead. Which models are in the list is set on the Codex tab of Settings → Model pickers. A GPT model joins it when it is first switched on; an owner adds any other model by hand. An empty Codex picker leaves Codex on its own built-in models.

If a model you expected is not there

  • Quit and relaunch first. The list is fetched at startup and cached for five minutes, so a model switched on while you were working shows up on the next start, not when you reopen /model.
  • Then ask an owner to add it. A model has to be switched on in Settings → Models and be in the Codex picker in Settings → Model pickers. Only GPT models go into the Codex picker by themselves; a Claude model or any other model is added there by hand. Connecting a provider key does not put anything in anyone's picker by itself.

Want a model your company has not curated? Name it directly — see naming a model.

Which models can appear in Codex?

Codex speaks one protocol, the one named on the wire_api line in the block above. Where the provider serving a model speaks another one, Selan translates each request and its answer between the two, so a model from any provider your company connects can be in Codex's list.

ProviderIn Codex
OpenAI — subscription or API key Yes. These are Codex's own models.
OpenRouter Yes.
nexos.ai Yes, its Claude models included. Selan translates those, since nexos.ai serves them on the other protocol.
Ollama Yes. Codex talks to Ollama's own Responses API.
Vertex AI Yes, Claude and Gemini models alike, translated the same way.

Every one of these reaches Claude Code as well, so a list that looks short here is usually the Codex picker rather than the provider: ask an owner to add the model on the Codex tab of Settings → Model pickers.

How do I start Codex on a named model?

You do not need the picker to choose. Name a model on the command line and Codex starts on it:

selan codex --model openrouter:moonshotai/kimi-k3

The shape of the name decides how far Selan will go to serve it:

  • With a provider in front — openrouter:moonshotai/kimi-k3 — it runs on that provider and no other. If that account is out of quota, the request fails rather than moving.
  • Without one — gpt-5.6-sol — it means the model itself, and Selan leases your company's accounts for it in the order an owner set, falling through on failure. This is what a pick in the picker does.

Either way the model has to be one your company connected. This path skips the curated list, not the provider keys.

Going further

How do I run Codex without approval prompts?

seland is the same binary under a second name, and it launches Codex with its approval prompts and its sandbox both off, after one enter to confirm:

seland codex

The confirmation line says what the launch skips:

seland codex · sandbox off · permission prompts off · ~/src/app  [Enter] Launch  [Ctrl-C] Cancel
The sandbox goes too. Codex can reach outside its workspace. To keep a sandbox, name one with Codex's own -s (--sandbox): seland codex -s workspace-write keeps it and turns off only the prompts. Name your own approvals with -a (--ask-for-approval) and seland skips nothing, and the line says nothing skipped.

For the same thing in Claude Code, and for the cases where running unattended is the point — CI, containers, cron — see seland and Running unattended. The token and environment variables described there work the same for Codex.

What differs from Claude Code, and how do I check usage?

Most of the main docs applies to both. These are the parts that do not:

  • No statusline. The spend and headroom line Selan installs is Claude Code's. Run selan usage for the same numbers.
  • No context limit, and no --autocompact. The window your company sets is applied by Claude Code when it compacts a conversation. Codex manages its own context and Selan does not touch it.
  • No 1M-context variant. Claude Code's picker offers some models twice, at 200k and at 1M. Codex gets each model once, at the window its provider reports.

Everything else carries across: the same session, your company's connectors, the same spend limits, the same secret scanning before a request leaves your machine, the same Logs, and repository attribution when you run inside a git checkout.

What if selan codex did not work?

  • codex not found on PATH — Codex itself is not installed. Install it, then run selan codex again.
  • The picker shows OpenAI's built-in list. Your Codex is older than 0.156 and not signed in to ChatGPT, so it never asked for one. Update Codex, or see the note above — naming a model still works.
  • A model is missing from the list. Relaunch first, then check it can reach Codex at all, then ask an owner to switch it on.
  • Codex starts on the wrong model. While Codex is signed in to ChatGPT, a launch that names no model starts on the one you last chose. Name another with --model, and the next launch starts on that one. If the remembered model is no longer yours to use, the launch says starting on another model instead.
  • A bare codex refuses to start. That is the design — the credential only exists for the length of a selan codex launch. Run it through Selan.
  • Something else. The error messages are collected in Reference, and you can always ask us.