Limits adapter
ChatGPT (Codex) Subscription Quota
Opt-in ChatGPT quota gauges stored in the OS keychain and shown with local Codex usage.
ChatGPT (Codex) Subscription Quota
tokenuse can optionally show ChatGPT (Codex) subscription-quota gauges (5-hour / 7-day / credits balance) next to your local Codex CLI spend. It is opt-in, user-triggered, and gated behind the quota-sync Cargo feature (on by default).
Status: implemented (limits-only adapter, no session ingestion).
The flow mirrors the Claude.ai subscription adapter — see claude-subscription.md for the full design rationale. Codex differs in three ways:
- Auth is two-step. ChatGPT expects a session cookie (
__Secure-next-auth.session-token), which you exchange for a short-lived bearer token before calling the usage endpoint. - Endpoint shape. Quotas come from
/backend-api/wham/usagewithAuthorization: Bearer <accessToken>, not from a per-organization usage path. LimitSnapshot.toolis tagged"codex"so the gauges appear inside the existing Codex section.
How it works
Adding the cookie
Service dev.tokenuse, account codex_subscription.session.
- Open
https://chatgpt.comin your browser and log in. - Open dev tools → Application/Storage → Cookies →
https://chatgpt.com. - Locate the session cookies. NextAuth splits session JWTs larger than ~4 KB across
.0/.1shards; both must be sent under their original names — concatenation does not work.
TUI (recommended). Press c from the dashboard, scroll to ChatGPT (Codex) subscription quota and press Enter. The cookie modal exposes three fields — Tab/Shift+Tab move between them, Cmd/Ctrl+V pastes via bracketed paste:
__Secure-next-auth.session-token.0— paste the value of the first shard (~3–4 KB).__Secure-next-auth.session-token.1— paste the value of the second shard (~200 B).- Additional cookies (optional, multi-line) — paste extra cookies (e.g.
cf_clearance=…; __Host-next-auth.csrf-token=…) if Cloudflare or the two shards alone aren’t enough.
When you confirm Save & sync, the TUI composes the Cookie: header (__Secure-next-auth.session-token.0=<a>; __Secure-next-auth.session-token.1=<b>[; <extras>]), writes it to the OS keychain, and runs the sync on a worker thread. The two other modal actions are Sync with stored cookie (reuses the stored value) and Clear stored cookie.
Desktop app. Same Subscription cookie modal — see docs/guides/desktop-usage.md. Underneath: set_codex_session_cookie / clear_codex_session_cookie Tauri commands.
CLI (scripted setup). The flag accepts either form: a bare unsharded token value, or a raw Cookie: request header (any string containing =, optionally prefixed with Cookie:).
# Unsharded (rare — when chatgpt.com sets a single __Secure-next-auth.session-token cookie):
tokenuse --set-codex-cookie '<bare-token-value>'
# Sharded — copy from dev tools → Network → any /api/auth/session request → Headers → Cookie:
tokenuse --set-codex-cookie '__Secure-next-auth.session-token.0=<a>; __Secure-next-auth.session-token.1=<b>'
# Clear:
tokenuse --clear-codex-cookie
Sidecar format
{
"observed_at": "2026-05-11T12:00:00Z",
"source": "https://chatgpt.com/backend-api/wham/usage",
"usage": {
"plan_type": "plus",
"rate_limit": {
"limit_reached": false,
"primary_window": { "used_percent": 33.0, "limit_window_seconds": 18000, "reset_after_seconds": 7200 },
"secondary_window": { "used_percent": 12.0, "limit_window_seconds": 604800, "reset_after_seconds": 432000 }
},
"credits": {
"has_credits": true,
"unlimited": false,
"balance": "45.25"
},
"spend_control": { "reached": false }
}
}
reset_at (epoch seconds) is used when present; otherwise reset_after_seconds is added to “now” at parse time. balance is accepted as either a string or a number.
LimitSnapshot row | Source field |
|---|---|
primary (5-Hour Limit) | rate_limit.primary_window — window_minutes defaults to 300 when limit_window_seconds is missing |
secondary (7-Day Limit) | rate_limit.secondary_window — window_minutes defaults to 10 080 |
extra_usage | credits + spend_control |
Errors
The error mapping matches Claude (401 → re-auth prompt, 403/HTML → Cloudflare, 429 → rate limited). A missing accessToken in the auth response also triggers the re-auth status.
Privacy posture
Same as the Claude adapter — cookie in keychain only, no telemetry, no background polling, disabled when quota-sync is off. OpenAI’s Terms of Service govern your use of the underlying endpoints; this feature accesses your own ChatGPT account using your own credentials.