Non-interactive codex status (JSON/headless replacement for /status)

Open 💬 15 comments Opened Jan 30, 2026 by aleksandarristic
💡 Likely answer: A maintainer (etraut-openai, contributor) responded on this thread — see the highlighted reply below.

What feature would you like to see?

Problem

The Codex CLI exposes account and runtime information (such as model, permissions, writable roots, and current 5-hour / weekly limits) through the interactive TUI slash command /status.

At present, there is no supported non-interactive or headless way to retrieve the same information.

This makes it difficult to integrate Codex CLI into automated workflows, since relying on terminal emulation or screen scraping is fragile and environment-dependent.

---

Current behavior

  • /status is only available inside the interactive TUI
  • There is no codex status subcommand
  • codex exec --json does not include quota or overall status information
  • codex login status reports authentication state only

As a result, tools cannot reliably determine quota status, runtime configuration, or workspace context without using the TUI.

---

Feature request

Provide a non-interactive, machine-readable way to retrieve the same information currently shown by /status.

The specific command name or flags are flexible; the key requirement is that the information be available outside the TUI.

---

Expectations

  • Works without a TTY
  • Does not require initializing the TUI
  • Produces stable output suitable for automation
  • Uses exit codes to indicate authentication or quota-related errors

---

Motivation

The information exposed by /status is already available interactively. Making it accessible in a headless form would simplify automation use cases and reduce the need for brittle workarounds.

---

Environment

  • OS: Linux / WSL2
  • Usage: non-interactive (Python subprocesses, I am talking with my codex via a Discord bot to use my dev machine on the go)

thanks!

Additional information

_No response_

View original on GitHub ↗

15 Comments

dmahurin · 5 months ago

Workaround. ( See: #10106 )

https://github.com/dmahurin/pty-runner

Examples:
pty-runner codex ... /status /exit

andrewmurphyusa · 3 months ago

Seconding this - I have just run in to a scenario where not being able to check the current status with a headless call makes Codex significantly less functional for me than Claude Code.

Specifically, it makes it harder to use it automatically in a Ralph Wiggum loop that sleeps when it runs out of capacity at the 5-hour window. With Claude Code this is _easy_ to implement; with Codex it requires a gnarly pty-emulation hack.

luboszima · 3 months ago

Any updates with this feature? It will be quite useful.

azinzuvadia-git · 2 months ago

I’d like to add another use case in support of a non-interactive codex status / codex status --json command.

We are using Codex on a ChatGPT Business workspace. The interactive /status command is very helpful because it shows the live 5-hour and weekly limits, for example:

5h limit: 85% left (resets 22:15)
Weekly limit: 69% left (resets 23:19 on 23 May)
````

The problem is that this information only seems available inside the interactive TUI. We tried several automation paths:

* Running `codex /status` from PowerShell fails because stdout is not a terminal.
* Running `codex exec --skip-git-repo-check "/status"` works, but it treats `/status` as a normal model prompt and does not return the quota/rate-limit information.
* Piping input with `echo /status | codex` fails because stdin is not a terminal.
* PTY / terminal automation workarounds are possible, but they are brittle, platform-specific, and not something we would want to rely on for workspace monitoring.
* The Codex Analytics API is useful for reporting, but it appears delayed and does not expose the live rolling 5-hour quota, reset time, or whether usage has moved from included quota to paid workspace credits.

Why this matters for us:

On Business, Codex has included usage windows, but workspaces can also have paid credits. We want to warn users before or at the moment their included 5-hour Codex window is exhausted, so they understand that continuing may consume paid workspace credits until the reset time.

The ideal solution would be a supported, non-interactive command such as:

```bash
codex status --json

with fields like:

{
  "account": {
    "email": "...",
    "plan": "Business"
  },
  "model": "gpt-5.5",
  "limits": {
    "five_hour": {
      "remaining_percent": 85,
      "reset_at": "2026-05-17T22:15:00+02:00"
    },
    "weekly": {
      "remaining_percent": 69,
      "reset_at": "2026-05-23T23:19:00+02:00"
    }
  },
  "credits": {
    "workspace_balance": null,
    "using_paid_credits": false
  }
}

Even if using_paid_credits is not available initially, exposing the same 5-hour and weekly limit information from /status in a machine-readable form would be very helpful.

This would enable clean integrations such as:

  • Windows/macOS/Linux tray notifications
  • IDE status bar warnings
  • Slack/Teams alerts
  • CI or developer-environment checks
  • workspace spend-governance tooling

Right now the information exists and is visible to humans in /status, but there does not seem to be a reliable supported way to read it from scripts.

etraut-openai contributor · 2 months ago

Can someone put together a more detailed spec for what you'd like to see here?

  • Which fields do you want?
  • Do you want this to be a separate command, or would you like to see these fields emitted for every codex exec --json call?
  • If included for every codex exec --json call, should the stats be sampled at the start or end of the turn?
azinzuvadia-git · 2 months ago
Can someone put together a more detailed spec for what you'd like to see here? Which fields do you want? Do you want this to be a separate command, or would you like to see these fields emitted for every codex exec --json call? * If included for every codex exec --json call, should the stats be sampled at the start or end of the turn?

Thanks for asking. Here’s a more concrete spec proposal based on the original issue, the other comments, and our Business workspace use case. I tried to summarize the discussion above. @aleksandarristic and Others can add / change if necessary.

Summary of what we want

The core ask is a supported, non-interactive, machine-readable equivalent of the interactive /status command.

The main use cases are:

  • checking live 5-hour / weekly Codex usage without launching the TUI
  • warning users before or when included quota is exhausted
  • deciding whether automation should continue, sleep, or stop
  • avoiding PTY/screen-scraping workarounds
  • exposing enough account/workspace/runtime context for monitoring and developer-environment tooling

Preferred interface

I would strongly prefer a separate command as the canonical interface:

codex status --json

or equivalently:

codex status --format json

Reason: this is useful as a cheap preflight/status check that does not start a model turn, does not require a git repo, and can be called by tray apps, IDE extensions, shell prompts, Slack/Teams bots, CI, etc.

codex exec --json could optionally include status metadata too, but I would not make full status emission mandatory for every exec call by default.

Suggested v1 fields

A v1 schema could focus on the fields already visible in /status, plus enough metadata to make automation reliable:

{
  "schema_version": 1,
  "sampled_at": "2026-05-18T10:30:00+02:00",
  "account": {
    "email": "user@example.com",
    "plan": "Business",
    "workspace": {
      "id": "...",
      "name": "Example Workspace"
    }
  },
  "auth": {
    "logged_in": true,
    "method": "chatgpt"
  },
  "model": {
    "current": "gpt-5.5"
  },
  "limits": {
    "five_hour": {
      "remaining_percent": 85,
      "reset_at": "2026-05-18T22:15:00+02:00"
    },
    "weekly": {
      "remaining_percent": 69,
      "reset_at": "2026-05-23T23:19:00+02:00"
    }
  },
  "credits": {
    "using_paid_credits": false,
    "workspace_balance": null
  },
  "runtime": {
    "approval_policy": "...",
    "sandbox_mode": "...",
    "network_access": "...",
    "writable_roots": []
  }
}

Minimum viable version

If some account, workspace, runtime, or credit fields are harder to expose initially, the minimum useful version would be:

{
  "schema_version": 1,
  "sampled_at": "2026-05-18T10:30:00+02:00",
  "account": {
    "email": "user@example.com",
    "plan": "Business"
  },
  "model": {
    "current": "gpt-5.5"
  },
  "limits": {
    "five_hour": {
      "remaining_percent": 85,
      "reset_at": "2026-05-18T22:15:00+02:00"
    },
    "weekly": {
      "remaining_percent": 69,
      "reset_at": "2026-05-23T23:19:00+02:00"
    }
  }
}

For our use case, the two most important fields are:

  • limits.five_hour.remaining_percent
  • limits.five_hour.reset_at

The weekly equivalents are also very helpful.

Handling paid credits

For Business workspaces, an ideal version would also expose whether usage has moved from included quota to paid workspace credits:

"credits": {
  "using_paid_credits": false,
  "workspace_balance": null
}

If this is not available in v1, I’d suggest returning null or omitting it rather than blocking the rest of the status API. The live 5-hour and weekly reset information alone would already solve most automation use cases.

codex exec --json behavior

My preference:

  1. Add codex status --json as the primary interface.
  2. Optionally add status events to codex exec --json behind an explicit flag, for example:
codex exec --json --include-status "..."

or:

codex exec --json --status-sample=start,end "..."

If status is included in codex exec --json, I think both start and end samples are useful:

  • start sample: lets automation decide whether the turn should begin
  • end sample: shows the quota state after the turn consumes usage

If only one can be included, I would prefer end, because it reflects the updated remaining quota after the operation. For preflight checks, callers can use codex status --json before invoking codex exec.

Suggested JSON event shape for codex exec --json

If added to codex exec --json, I’d suggest emitting explicit status events rather than adding fields to every event:

{
  "type": "status",
  "sample": "start",
  "status": {
    "schema_version": 1,
    "sampled_at": "2026-05-18T10:30:00+02:00",
    "limits": {
      "five_hour": {
        "remaining_percent": 85,
        "reset_at": "2026-05-18T22:15:00+02:00"
      },
      "weekly": {
        "remaining_percent": 69,
        "reset_at": "2026-05-23T23:19:00+02:00"
      }
    }
  }
}

and optionally:

{
  "type": "status",
  "sample": "end",
  "status": {
    "...": "..."
  }
}

Exit codes

For automation, stable exit codes would also help:

  • 0: status retrieved successfully
  • non-zero: not logged in / auth expired
  • non-zero: status unavailable / network error
  • non-zero: unsupported account or unavailable quota information

The exact numeric values matter less than documenting them.

Why a separate command matters

The key point is that the information already exists and is visible to humans in /status, but it is not currently available to scripts without brittle terminal emulation. A supported JSON command would make Codex much easier to integrate into IDE status bars, tray notifications, Slack/Teams alerts, CI/developer-environment checks, and workspace spend-governance tooling.

etraut-openai contributor · 2 months ago

Thanks, that's helpful. However, I don't think we can implement that spec. The problem is that much of the information that /status displays is valid only within the context of a thread.

Usage limits are returned to the client by the responses endpoint. They're returned as HTTP headers. A responses call requires a thread.

The "model" and "runtime" parameters are properties of a thread. They are specified at the time a thread is started, and they can be updated between turns. When you run /status, it is in the context of a thread, and it displays the latest values of these parameters. It's not clear what values should be returned outside the context of a thread. Perhaps you're looking for the default values of these values — those that are used if a client does not specify them at thread creation time?

With that in mind, I think it makes more sense for the status information to be returned as part of the codex exec --json output — and sampled only at the end of the turn.

Also, to my knowledge, there's currently no way for the client to retrieve available credits. We don't expose a public endpoint that provides this information.

azinzuvadia-git · 2 months ago
Thanks, that's helpful. However, I don't think we can implement that spec. The problem is that much of the information that /status displays is valid only within the context of a thread. Usage limits are returned to the client by the responses endpoint. They're returned as HTTP headers. A responses call requires a thread. The "model" and "runtime" parameters are properties of a thread. They are specified at the time a thread is started, and they can be updated between turns. When you run /status, it is in the context of a thread, and it displays the latest values of these parameters. It's not clear what values should be returned outside the context of a thread. Perhaps you're looking for the default values of these values — those that are used if a client does not specify them at thread creation time? With that in mind, I think it makes more sense for the status information to be returned as part of the codex exec --json output — and sampled only at the end of the turn. Also, to my knowledge, there's currently no way for the client to retrieve available credits. We don't expose a public endpoint that provides this information.

Thanks, that explanation makes sense. Given those constraints, I agree that a thread/turn-scoped status event in codex exec --json is probably the right v1 shape.

The most important thing for our use case is not that this is a standalone codex status --json command specifically; it is that the live quota/reset information currently visible in /status becomes available in a supported, machine-readable, non-TTY path.

Based on your explanation, I’d revise the ask to this:

Preferred v1 behavior

For codex exec --json, emit a final status/rate-limit event at the end of the turn, sampled after the responses call completes and after any returned rate-limit headers have been observed.

For example:

{
  "type": "status",
  "sample": "end",
  "sampled_at": "2026-05-18T10:30:00+02:00",
  "limits": {
    "five_hour": {
      "remaining_percent": 85,
      "reset_at": "2026-05-18T22:15:00+02:00"
    },
    "weekly": {
      "remaining_percent": 69,
      "reset_at": "2026-05-23T23:19:00+02:00"
    }
  }
}

Naming is flexible; status, rate_limits, usage_limits, etc. would all work. The important part is that it is a stable JSON event that automation can parse.

Fields we care about most

Minimum useful fields:

{
  "type": "status",
  "sample": "end",
  "sampled_at": "...",
  "limits": {
    "five_hour": {
      "remaining_percent": 85,
      "reset_at": "..."
    },
    "weekly": {
      "remaining_percent": 69,
      "reset_at": "..."
    }
  }
}

Optional but useful if readily available:

{
  "account": {
    "email": "...",
    "plan": "Business"
  },
  "thread": {
    "id": "..."
  },
  "model": {
    "current": "..."
  },
  "runtime": {
    "approval_policy": "...",
    "sandbox_mode": "...",
    "network_access": "..."
  }
}

Given your point that model/runtime are thread properties, it would be fine for those to mean “the values in effect for this exec turn/thread,” not global defaults.

Sampling

End-of-turn sampling is fine for v1.

That works because it gives automation the updated quota state after the turn consumes usage. A wrapper can then decide whether to continue, warn the user, sleep until reset, or stop.

Start-of-turn sampling would still be nice eventually for preflight decisions, but I understand from your explanation that the status data is returned by the responses endpoint and therefore naturally becomes available after a turn. End-only is still a big improvement over requiring PTY automation.

Whether this should appear on every codex exec --json call

I would be happy with either:

  1. always emitting a final status/rate-limit event for codex exec --json, or
  2. emitting it behind an explicit flag such as:
codex exec --json --include-status "..."

From an automation perspective, always emitting it is simpler, as long as it is a distinct JSON event type and does not break existing consumers that ignore unknown events.

Credits

Understood on available credits. I would drop credits.workspace_balance and credits.using_paid_credits from the v1 ask if the client cannot retrieve them today.

The live 5-hour and weekly remaining/reset information is the critical part.

Remaining use case gap

The only thing this does not fully solve is a true “preflight without spending a turn” check. But if the current architecture requires a responses call/thread to obtain the headers, then an end-of-turn codex exec --json status event is still very useful and would remove the need for brittle PTY/screen-scraping workarounds.

So, revised v1 ask:

  • add a machine-readable final status/rate-limit event to codex exec --json
  • sample at end of turn
  • include live 5-hour and weekly remaining/reset values
  • optionally include thread-scoped model/runtime/account fields if readily available
  • omit credits for now
azinzuvadia-git · 2 months ago

Hi @etraut-openai

We built a working Windows desktop quota widget as a real-world validation of this issue and wanted to share results.

What we achieved

  • Tiny always-on-top desktop widget for live Codex quota visibility.
  • Shows:
  • 5-hour remaining quota (battery style)
  • Weekly remaining quota (battery style)
  • Reset countdown timers for both windows
  • Runs without interactive TTY screen-scraping of /status.
  • Uses Codex app-server JSON-RPC polling (account/rateLimits/read) from a local client process.

Implementation approach (brief)

  • Python + Tkinter desktop UI
  • Local hidden Codex process (codex app-server --listen stdio://)
  • JSON-RPC request/response loop every 5s
  • Map returned limit/reset fields to compact UI state

_Code is here - https://github.com/azinzuvadia-git/codex-status-credits-watcher_
_More about the app: https://azinzuvadia-git.github.io/codex-status-credits-watcher/help.html_

Why this matters

This removed brittle PTY automation for our use case and gave us stable, glanceable quota telemetry for everyday usage.

What we still ask (v1)

As discussed, a supported machine-readable output in official CLI flow would be ideal:

  • add a machine-readable final status/rate-limit event to codex exec --json
  • sample at end of turn
  • include live 5-hour and weekly remaining/reset values
  • optionally include thread-scoped model/runtime/account fields if readily available

This would make integrations cleaner (desktop widgets, IDE status indicators, automation loops) without relying on implementation details.

Screenshot of our widget:

<img width="142" height="110" alt="Image" src="https://github.com/user-attachments/assets/b275369a-ee59-4be4-9f3c-15afa8ba56f6" />

_(As you see I ran out of the 5h window quota. have to wait 1 hr till it's refilled, and my weekly quota is only 50% left and still 5 days to go. This is happening often so it matters to me as small consulting business owner, I am really trying to watch each $ spent and want to stretch the existing business subscription $ to the max, I don't have deep pockets to spend unlimited credits like a big organization. Currently the quota is not enough for me to build a prototype analytics dashboard showcase, even when I use all advised efficiency measures and use only 5.3 codex medium standard model.)_

Contact - https://www.zinzuvadia-online.com

ronaldpetty · 2 months ago

Adding one more method to get basic time/levels like /status locally.

https://gist.github.com/ronaldpetty/46397107ca49d0f4bca4c85b1531d268

ronaldpetty · 2 months ago

Not to inflate the original ask. But other information is useful outside of a session for example, interactive approval. When I am switching terminals, I like to be notified Codex is waiting.

There might be hooks/notifications or alternative ways to do these inspection checks, but I think having to build unique solutions (e.g. my script in prior comment to check part of /status can't be used to check is Codex blocked in Ghostty). Building up a oascript or running Codex in tmux/screen are all neat, but not sustainable. In general, I think we have a world where we have three surfaces:

  • remote (API)
  • session (in-app /status)
  • local (local but not in-app; hooks, config files, logs)

Other complexities are CLI vs UI vs browser vs custom.

While all exist, having to figure which can provide one thin but not another is challenging. This gets more challenging because we expect agents to run long term, but short of all tooling being integrated we have to integrate outside tools with Codex. Another complexity is showing useful information. For example, gpt-5-5 xhigh isn't reflected in /status, but you can see it reflect on web https://chatgpt.com/codex/cloud/settings/analytics#usage.

Clearly Rome wasn't built in a day, but might be good time to review what it means to expose data in a uniform way across the various ways of using this tool(set).

kamekazu · 1 month ago

Adding another concrete use case for this request.

I often run Codex CLI on a VPS over SSH/tmux, and the lack of a non-interactive usage/status command makes it hard to keep track of the current 5-hour usage window while working remotely.

The interactive /status command helps, but it is not enough for remote/headless workflows because it cannot be consumed by tmux status bars, shell scripts, cron/monitoring checks, or lightweight wrappers.

What would be especially useful:

  • codex usage for a human-readable summary
  • codex usage --json for automation
  • remaining Local Messages / Cloud Tasks for the current 5-hour window
  • reset timestamp for the current window
  • current plan/model context if available
  • stable exit codes for auth/quota errors

This would make Codex much easier to monitor in VPS-based CLI workflows, without relying on terminal scraping or manually opening the TUI just to run /status.

azinzuvadia-git · 1 month ago

Hey I like this in the Codex windows app - is this new (the stats about the usage remaining?
I wasn't aware of this.

<img width="352" height="360" alt="Image" src="https://github.com/user-attachments/assets/4da75e1c-1132-471b-a35b-b02a3428c439" />

Seems like I can check my usage directly here in the settings now. I mean its a pain to keep opening and checking everytime, but at least once in a while this can be a way to do a quick check. I would prefer a way to pin this info on a panel so that its always visible and gets updated as I continue to consume the quota.

EthicalAIExplorer · 1 month ago

Adding a reporting/orchestration use case that I think fits the revised direction discussed above.

For my use case, the critical need is not a prettier /status display. It is a stable, non-TTY, machine-readable status sample that can be bound to an automation/reporting window without scraping the TUI or reading raw session transcripts.

A practical v1 would be an explicit end-of-turn event in codex exec --json, sampled after the responses call has returned whatever rate-limit/status metadata is available.

Suggested event shape:

{
  "type": "status",
  "schema_version": 1,
  "sample": "end",
  "sampled_at": "2026-06-21T12:00:00Z",
  "thread": {
    "id": "..."
  },
  "session": {
    "id": "..."
  },
  "model": {
    "current": "gpt-5.5",
    "reasoning_effort": "xhigh"
  },
  "usage": {
    "input_tokens": 0,
    "cached_input_tokens": 0,
    "output_tokens": 0,
    "reasoning_output_tokens": 0,
    "total_tokens": 0
  },
  "limits": {
    "five_hour": {
      "used_percent": 40,
      "remaining_percent": 60,
      "resets_at": "2026-06-21T13:10:00Z"
    },
    "weekly": {
      "used_percent": 47,
      "remaining_percent": 53,
      "resets_at": "2026-06-25T05:18:00Z"
    }
  }
}

Fields could be nullable/omitted when unavailable. The important part is the stable event contract, not the exact field names.

The reporting use case has a few constraints that are slightly different from statusline or desktop-widget use cases:

  • It needs provenance: the sample time, thread/session identity where available, and the model/reasoning configuration in effect for the turn.
  • It should be safe to store in downstream reports, so it should not contain transcript content, prompts, command output, file contents, secrets, or raw rollout/session JSONL.
  • It should expose both used_percent and remaining_percent, or otherwise make the semantics explicit, because integrations can easily invert that meaning.
  • It should be distinct from token activity graphs or delayed analytics pages. A delayed historical analytics surface is useful, but it cannot replace a turn-bound status sample for automation decisions.
  • It should let wrappers decide whether to continue, pause until reset, downgrade task scope, or produce a handoff before starting another expensive or mutation-heavy turn.

This would also reduce pressure on users to build brittle workarounds around TUI scraping, local app-server polling, or metadata parsing from ~/.codex/sessions. For reporting tools, local session parsing can work as a temporary workaround, but it is not ideal: raw transcript files are privacy-sensitive and easy to over-ingest accidentally.

So I think the minimal valuable contract is:

  1. Emit a final machine-readable status/rate-limit event from codex exec --json.
  2. Sample at end of turn.
  3. Include token usage breakdown already available to exec --json.
  4. Include live 5h/weekly limit percentages and reset times when available.
  5. Include thread/session/model metadata where available.
  6. Guarantee no transcript/tool-output content in the status event.
  7. Use nullable fields rather than failing the whole event when one piece of status is unavailable.

That would be enough for reporting, spend/usage observability, and safe continuation logic without requiring a standalone preflight codex status --json in v1.

Necmttn · 29 days ago

A useful v1 would be a stable status sample, not a TUI mirror. Fields: auth state, model, cwd/project, approval mode, sandbox mode, context window used/remaining, quota windows with reset timestamps, sample age, and last fetch error. Exit codes can separate unauthenticated, stale quota, and unsupported surface. That gives tmux/statusline/daemon callers one contract without scraping screens.

---

_Generated with ax._