| summary | Codex provider data sources: OpenAI web dashboard, Codex CLI RPC, credits, and local cost usage. | ||||
|---|---|---|---|---|---|
| read_when |
|
Codex has three automatic usage data paths (OAuth API, web dashboard, CLI RPC) plus a manual CLI PTY diagnostic parser and a local cost-usage scanner. The OAuth API is the default app source when credentials are available; web access is optional for dashboard extras.
- OAuth API (auth.json credentials).
- CLI RPC through
codex app-server. - If OpenAI web extras are enabled and a matching OpenAI web session is available (Automatic or Manual cookies),
dashboard extras load as a separate follow-up refresh and the source label becomes
primary + openai-web.
Usage source picker:
- Preferences → Providers → Codex → Usage source (Auto/OAuth/CLI).
- OpenAI web dashboard (when available).
- Codex CLI RPC through
codex app-server.
- Reads OAuth tokens from
~/.codex/auth.json(or$CODEX_HOME/auth.json). - Refreshes access tokens when
last_refreshis older than 8 days. - Calls
GET https://chatgpt.com/backend-api/wham/usage(default) withAuthorization: Bearer <token>. - The app reads reset-credit inventory once per refresh with a best-effort
GET https://chatgpt.com/backend-api/wham/rate-limit-reset-creditsusing the same account-scoped OAuth context; the CLI requests it only when optional credits are included. - The menu and provider settings list every still-available expiry, while the optional credits setting controls nearing-expiry notifications. QuotaKit does not redeem or modify reset credits.
rate_limit.primary_window/secondary_windowmap to the session/weekly lanes.additional_rate_limits[](model-specific limits such as GPT-5.3-Codex-Spark) map to namedUsageSnapshot.extraRateWindowsentries. Spark uses stablecodex-spark/codex-spark-weeklyids andCodex Spark 5-hour/Codex Spark Weeklytitles. When the field is absent, the snapshot is unchanged.- Preferences → Providers → Codex → Show Codex Spark usage hides only the Spark rows in menus and the provider preview. It does not change fetching, history, notifications, widgets, credits, or other extra limits.
- Managed Codex accounts remain the default multi-account path.
- Advanced users can add existing Codex homes to
~/.quotakit/config.jsonwithproviders[].codexProfileHomePaths. - Each configured path must be absolute or start with
~/, and point at a Codex home that containsauth.json. - QuotaKit reads identity from the configured home, exposes it in the Codex account switcher, and scopes
remote Codex fetches with
CODEX_HOME. - Profile homes are not copied, reauthenticated, or removed by QuotaKit.
Example:
{
"id": "codex",
"codexProfileHomePaths": [
"~/.codex-work",
"~/.codex-personal"
]
}- Enable it in Preferences -> Providers -> Codex -> OpenAI web extras.
- It exists for dashboard-only extras such as code review remaining, usage breakdown, and credits history.
- It is intentionally opt-in because it loads
chatgpt.comin a hidden WebView and can materially increase battery or network usage. - OpenAI web battery saver is a separate toggle. When enabled, routine background/settings-driven refreshes are reduced, but explicit manual refreshes still run.
- OpenAI web battery saver currently defaults to off.
- Preferences → Providers → Codex → OpenAI cookies (Automatic or Manual).
- URL:
https://chatgpt.com/codex/settings/usage. - Uses an off-screen
WKWebViewwith a per-accountWKWebsiteDataStore.- Store key: deterministic UUID from the normalized email.
- WebKit store can hold multiple accounts concurrently.
- Cookie import (Automatic mode, when WebKit store has no matching session or login required):
- Safari:
~/Library/Cookies/Cookies.binarycookies - Chrome/Chromium forks:
~/Library/Application Support/Google/Chrome/*/Cookies - Firefox:
~/Library/Application Support/Firefox/Profiles/*/cookies.sqlite
- Domains loaded:
chatgpt.com,openai.com. - No cookie-name filter; we import all matching domain cookies.
- Safari:
- Cached cookies: Keychain cache
com.steipete.quotakit.cache(accountcookie.codex, source + timestamp). Reused before re-importing from browsers. - Manual cookie header:
- Paste the
Cookie:header from achatgpt.comrequest in Preferences → Providers → Codex. - Used when OpenAI cookies are set to Manual.
- Paste the
- Account match:
- Signed-in email extracted from
client-bootstrapJSON in HTML (or__NEXT_DATA__). - If Codex email is known and does not match, the web path is rejected.
- Signed-in email extracted from
- Web scrape payload (via
OpenAIDashboardScrapeScript+OpenAIDashboardParser):- Rate limits (5h + weekly) parsed from body text.
- Credits remaining parsed from body text.
- Code review remaining (%).
- Usage breakdown chart (Recharts bar data + legend colors).
- Credits usage history table rows.
- Credits purchase URL (best-effort).
- Errors surfaced:
- Login required or Cloudflare interstitial.
- Launches local RPC server:
codex -s read-only -a untrusted app-server. - JSON-RPC over stdin/stdout:
initialize(client name/version)account/readaccount/rateLimits/read
- RPC reads are bounded: initialization has a longer startup budget, and normal requests have a shorter per-method
timeout. On timeout, QuotaKit terminates the child
codex app-serverprocess so the stdout reader unwinds instead of leaving refresh stuck indefinitely. - Provides:
- Usage windows (primary + secondary) with reset timestamps.
- Credits snapshot (balance, hasCredits, unlimited).
- Account identity (email + plan type) when available.
- App-server errors are terminal for the CLI strategy, except when Codex includes a recoverable
wham/usageJSON body in the error text. - If macOS blocks or quarantines the
codexexecutable, QuotaKit records the launch failure and skips background CLI launches for 30 minutes. Use a manual refresh after reinstalling or unblockingcodexto retry immediately. - QuotaKit also discovers the Codex CLI bundled with current ChatGPT and legacy Codex desktop apps, even when
codexis absent from the shell PATH. - If managed Codex account login still reports a missing executable, turn on Show debug settings in
Settings > Advanced, then check Settings > Debug > CLI Paths. When no Codex binary appears there, confirm
codex --versionworks in Terminal, checkwhich -a codexfor stale duplicate installs, then runnpm install -g --include=optional @openai/codex@latestbefore retrying Add Account.
- Manual/debug parser only; automatic background refresh and
QuotaKitCLI usage --source clido not launch bare Codex TUI. - Kept for explicit diagnostics/parser coverage because bare
codexTUI can start interactive auth and open browser tabs. - Parses rendered
/statusoutput:Credits:line5h limitline → percent + reset textWeekly limitline → percent + reset text
- Detects update prompts and surfaces a "CLI update needed" error.
- Latest Codex usage snapshot (from RPC, if available).
~/.codex/auth.json(JWT claims: email + plan).- OpenAI dashboard signed-in email (cached).
- Last imported browser cookie email (cached).
- Web dashboard fills credits only when OAuth/CLI do not provide them.
- CLI RPC:
account/rateLimits/read→ credits balance. - CLI PTY diagnostics can still parse
Credits:from saved/manual/statusoutput.
- Menu source selection:
- By default, a selected managed account keeps its own
CODEX_HOMEsession history. - Local session cost estimates is a Codex-only opt-in that instead scans this Mac's ambient
$CODEX_HOME(or~/.codex) independently of quota, OAuth, web-dashboard, and administrator access. - The local-only mode never makes a network request or uploads session content. It uses an existing local models.dev
cache when available, then the bundled
CostUsagePricingrates.
- By default, a selected managed account keeps its own
- Source files:
- Native Codex logs:
~/.codex/sessions/YYYY/MM/DD/*.jsonl~/.codex/archived_sessions/*.jsonl(flat; date inferred from filename when present)- Or
$CODEX_HOME/sessions/...+$CODEX_HOME/archived_sessions/...ifCODEX_HOMEis set.
- Supported pi sessions:
~/.pi/agent/sessions/**/*.jsonl
- Native Codex logs:
- Scanner:
- Native Codex logs parse
event_msgtoken_count entries andturn_contextmodel markers; when both are present,turn_contextis authoritative for the model bucket. - pi sessions count assistant-message usage rows and attribute
openai-codexassistant usage to Codex. - pi assistant usage is bucketed by assistant-turn timestamp, so mixed-model pi sessions can contribute to multiple days/models correctly.
- Native conversation rows reuse the corrected cached per-file totals and existing pricing tables. They are hidden when pi usage joins the aggregate because the native-only rows would not reconcile with the merged total.
- Native Codex logs parse
- Cache:
- Native + merged provider cache:
~/Library/Caches/CodexBar/cost-usage/codex-v11.json - pi-compatible session cache:
~/Library/Caches/CodexBar/cost-usage/pi-sessions-v7.json
- Native + merged provider cache:
- Window: configurable 1-365 day rolling history, with a 60s minimum refresh interval.
Settings → Usage & Spend performs a separate fixed 30-day scan for every visible Codex account. Each request freezes
the account source, exact Codex home, authentication fingerprint, and cache identity before scanning. A missing or
invalid home is omitted; it never falls back to ambient ~/.codex or to the global Codex token snapshot.
These account rows intentionally exclude pi sessions because pi history is machine-local rather than owned by one Codex account. The normal Codex cost menu and CLI scan continue to include supported pi history. The dashboard labels its values as local estimates and keeps currencies separate.
- Web:
Sources/QuotaKitCore/OpenAIWeb/* - CLI RPC + diagnostic PTY parser:
Sources/QuotaKitCore/UsageFetcher.swift,Sources/QuotaKitCore/Providers/Codex/CodexStatusProbe.swift - Cost usage:
Sources/QuotaKitCore/CostUsageFetcher.swift,Sources/QuotaKitCore/PiSessionCostScanner.swift,Sources/QuotaKitCore/PiSessionCostCache.swift,Sources/QuotaKitCore/Vendored/CostUsage/*