Codex CLI Cost Tracking — What Exists, What's Missing, and How to Meter Every Session
Just want the answer? Codex CLI doesn't price sessions. Point it at a metering proxy and it does — five lines in ~/.codex/config.toml, same responses, every call priced:
[model_providers.acp]
name = "Agentic Control Plane"
base_url = "https://api.agenticcontrolplane.com/openai/v1"
env_key = "OPENAI_API_KEY"
wire_api = "responses"
env_http_headers = { "x-acp-key" = "ACP_KEY" }
Full Codex setup (both planes) → · get a workspace key → · free for individuals
OpenAI’s Codex CLI will happily spend money all day and never tell you how much. That’s not an oversight you’re missing a flag for — there is no built-in cost tracking, and the feature request for it (openai/codex #5085, an RFC for a full cost-and-usage module: real-time cost display, budgets, per-project attribution, export) was closed without shipping. A related ask, token/cost info in rollout files, is #3201.
This is the reference for what you can see natively, why it isn’t cost tracking, and the config that closes the gap.
What Codex shows natively
- Context-window usage in-session — the status line tracks how full the model’s context is. That’s a capacity gauge, not a bill.
- Token counts in rollout files — sessions leave records under
~/.codex/, and token information appears there in limited forms. Nothing prices them. - Your OpenAI dashboard — if you authenticate with an API key, usage lands in OpenAI’s billing views: aggregated by day and model, hours later, with no per-session, per-project, or per-agent attribution. If you sign in with a ChatGPT plan, there’s no meter at all — usage disappears into the subscription.
So the native answer to “what did that session cost?” is: wait for the invoice, subtract, guess.
Why token counts aren’t cost tracking
Three things a raw token counter can’t tell you, and per-call metering can:
- Dollars per session, at the moment they’re spent. A long
--full-autorun is exactly the case where nobody is watching — the cost of a runaway loop should surface while it’s running, not on next month’s statement. - Cache economics. Input tokens are not all priced equally — cached reads bill at a fraction of the full rate, so two sessions with identical token counts can differ several-fold in dollars. Whether your prompt prefix stays cache-stable across turns is invisible in a token total and obvious in per-call metering.
- Loop vs. leaf attribution. In agent sessions most spend is the orchestration loop re-reading its own context — across 210,840 metered calls on our data page, roughly 89% of spend sat in the loop, not the leaf work. A token counter gives you one number; attribution tells you which part of the session to fix.
The config
Add a custom model provider pointing at the ACP proxy. Two rules that cost people the most debugging time, both from Codex’s own source: the block must live in ~/.codex/config.toml — provider keys are ignored in project-local .codex/config.toml — and wire_api accepts only "responses" (Codex removed wire_api = "chat" in v0.96; the TOML deserializer hard-errors on it, discussion #7782).
# ~/.codex/config.toml
model = "gpt-5.5-codex"
model_provider = "acp"
[model_providers.acp]
name = "Agentic Control Plane"
base_url = "https://api.agenticcontrolplane.com/openai/v1"
env_key = "OPENAI_API_KEY" # your OpenAI key — forwarded untouched, billed to you
wire_api = "responses" # only legal value since v0.96
env_http_headers = { "x-acp-key" = "ACP_KEY" } # your ACP workspace key (gsk_...), from env
Export both env vars, restart Codex, run anything. Each /responses call now passes through the proxy: the request is forwarded to OpenAI unchanged (SSE stream and all), the usage fields on the way back are priced, and the call lands as a row — model, tokens, cached share, dollars — in the console. Sessions aggregate into runs, so you get per-session cost, not just per-call.
Prefer not to manage an OpenAI key? Leave env_key unset and store a workspace-managed key in the console instead — the proxy supplies the upstream credential and your workspace is billed.
The honest caveat: API-key billing only
Codex custom model providers authenticate with an API key. A Codex signed in with a ChatGPT plan routes through OpenAI’s own auth and cannot be pointed at a custom provider — which means subscription traffic can’t be metered this way, by construction. If your whole team is on ChatGPT-plan Codex, this pattern doesn’t apply until you move to API-key billing. We’d rather say that plainly than have you discover it after editing config files.
(Claude Code users: the equivalent limitation doesn’t bite there — ACP’s claude-acp wrapper forwards subscription OAuth upstream and prices the traffic at API-rate equivalents. Codex offers no analogous passthrough for plan auth today.)
Budget limits
Codex has none. Through the proxy, workspace-billed traffic is subject to your workspace’s daily LLM cost limit, enforced at the gateway before the call goes upstream. BYO-key traffic is billed by OpenAI directly — ACP meters it but can’t cap what it doesn’t bill, so set the hard limit in your OpenAI dashboard as the backstop.
Troubleshooting
Provider config seems ignored. It’s in a project-local .codex/config.toml — provider keys only load from ~/.codex/config.toml. Move the block.
Startup error about a missing env var. env_key = "OPENAI_API_KEY" makes an empty/missing variable a hard startup error, by design. Export it in the shell that launches Codex.
Hard error mentioning wire_api. You have wire_api = "chat" somewhere — removed in v0.96. The only legal value is "responses".
Provider id conflicts. openai, ollama, and lmstudio are reserved ids and can’t be overridden. Use acp (or anything else).
Calls work but nothing appears in the console. Check the x-acp-key header is actually reaching us: env_http_headers reads the ACP_KEY env var at launch. Without it the request is treated as unauthenticated and rejected — the proxy never silently meters to nowhere.
What this pairs with
Cost is one of the two planes. The other — governing what Codex does — is the hook + MCP-connector layer covered in the Codex CLI hooks reference. They’re independent: hooks see tool calls and never token usage; the proxy sees model calls and never what your shell actually ran. Ways to set up ACP wires both and tells you which planes you have.
Frequently asked questions
Does Codex CLI track cost?
Not in dollars. The CLI surfaces token counts (context-window usage in the status line, token info in rollout files) but has no built-in per-session dollar cost, no historical spend view, and no budget limits. The demand is well documented — openai/codex #5085 is an RFC for exactly this module, closed without shipping — so cost visibility currently comes from outside the CLI.
How do I see what a Codex session actually costs?
Route Codex’s model calls through a metering proxy: add a custom model provider in ~/.codex/config.toml whose base_url points at the proxy, and every request/response is token-counted and priced per call as it happens. The config is five lines; responses pass through unchanged.
Can I set a budget or spend limit for Codex CLI?
Not natively — the CLI has no budget controls. Through the ACP proxy, workspace-billed traffic gets a daily LLM cost limit enforced at the gateway. If you bring your own OpenAI key, billing happens upstream at OpenAI and ACP meters but cannot cap it — set the hard cap in your OpenAI dashboard in that case.
Does routing Codex through a proxy change model responses?
No. The proxy is a passthrough for the Responses API over SSE — same request upstream, same stream back. It reads the usage fields to price the call and forwards everything else untouched.
Does this work with a ChatGPT plan (subscription) sign-in?
No — and this is the honest limitation of the pattern. Codex custom model providers authenticate with an API key, so proxy metering applies to API-key-billed usage only. A Codex signed in with a ChatGPT plan sends its traffic through OpenAI’s own auth and cannot be pointed at a custom provider.
Why does my custom provider config get ignored?
Provider keys are ignored in project-local .codex/config.toml — the [model_providers] block must live in ~/.codex/config.toml. Also check the provider id: openai, ollama, and lmstudio are reserved and cannot be overridden.
Where to read more
- Codex CLI hooks reference — the governance plane: hooks.json, PreToolUse, what’s covered and what isn’t
- Ways to set up ACP — every stack’s setup path, ending with your coverage state
- Claude Code cost tracking — the sibling reference for Claude Code
- The loop tax — why ~89% of agent spend sits in the orchestration loop
- The Tool Surface Index — Codex’s 17 declared tools next to Claude Code’s 76
- OpenAI Codex config docs — canonical upstream reference for config.toml