Files
ai-artifacts/projects/dotfiles/064-pi-ui-third-party-codex-quota-research.md
2026-08-01 14:05:09 -04:00

89 lines
7.6 KiB
Markdown

---
status: resolved
parent: "[[060-pi-ui-codex-quota-research]]"
blocked-by: []
resolved-at: "2026-08-01T00:24:40-04:00"
tags:
- ticket/research
---
# Third-party ChatGPT Codex quota research
## Question
What mechanism do third-party tools such as baby-menu use to show remaining ChatGPT Codex quota, and can that mechanism be adapted safely for a Pi status integration?
## Findings
`baby-menu` does not ship a completed Codex quota extension in the checked repository snapshot.
It ships an extension recipe at `extensions/recipes/codex-quota.html` that instructs implementers to obtain real local Codex quota data from two sources: a direct ChatGPT backend usage call using local Codex credentials, then a Codex CLI app-server JSON-RPC fallback.
Source: `/tmp/pi-ui-quota-research/baby-menu/extensions/recipes/codex-quota.html`.
The direct `baby-menu` recipe endpoint is `GET https://chatgpt.com/backend-api/wham/usage` with `Authorization: Bearer <access_token>` and `ChatGPT-Account-Id` when available.
The recipe says usage lives under `rate_limit`, `used_percent` is percent used, `primary_window` is the short session window, `secondary_window` is the weekly window, and remaining is `100 - used_percent`.
Source: `/tmp/pi-ui-quota-research/baby-menu/extensions/recipes/codex-quota.html`.
The same first-party endpoint family is present in OpenAI's own Codex source.
The official Codex backend client selects `/wham/usage` for the ChatGPT API path and `/api/codex/usage` for the Codex API path, adds `ChatGPT-Account-Id` when it has a ChatGPT account id, and parses the returned rate-limit payload into Codex rate-limit snapshots.
Sources: `/tmp/pi-ui-quota-research/openai-codex/codex-rs/backend-client/src/client/rate_limit_resets.rs`; `/tmp/pi-ui-quota-research/openai-codex/codex-rs/backend-client/src/client.rs`.
OpenAI's `codex app-server` exposes the same information through a documented local JSON-RPC method.
Its app-server README documents `account/rateLimits/read` as fetching ChatGPT rate limits, monthly credit-limit data when available, spend-control state, and earned reset credits, with updates via `account/rateLimits/updated`.
The protocol schema defines `GetAccountRateLimitsResponse` with `rateLimits`, optional `rateLimitsByLimitId`, and optional `rateLimitResetCredits`, and defines `RateLimitWindow.usedPercent`, `windowDurationMins`, and `resetsAt`.
Sources: `/tmp/pi-ui-quota-research/openai-codex/codex-rs/app-server/README.md`; `/tmp/pi-ui-quota-research/openai-codex/codex-rs/app-server-protocol/src/protocol/v2/account.rs`.
`quota-axi` implements the same mechanism as a local data-only CLI.
For Codex it first reads OAuth tokens from `$CODEX_HOME/auth.json` or `~/.codex/auth.json`, calls `https://chatgpt.com/backend-api/wham/usage` and `https://chatgpt.com/backend-api/codex/usage`, and falls back to spawning `codex -s read-only -a untrusted app-server` and issuing `initialize`, `account/read`, and `account/rateLimits/read` JSON-RPC requests.
Sources: `/tmp/pi-ui-quota-research/quota-axi/src/providers/codex.ts`; `/tmp/pi-ui-quota-research/quota-axi/README.md`.
`quota-axi` normalizes Codex windows by duration rather than by position alone.
It maps 18,000-second windows to a session or five-hour window, 604,800-second windows to weekly windows, computes `percentRemaining` from `percentUsed`, handles additional named or per-model limits, and reports reset times and credit snapshots when available.
Source: `/tmp/pi-ui-quota-research/quota-axi/src/providers/codex.ts`.
There is an important discrepancy between sources about API-key auth.
The `baby-menu` recipe says a top-level `OPENAI_API_KEY` in Codex `auth.json` can be used directly as the bearer token.
`quota-axi` explicitly does not send `OPENAI_API_KEY` to ChatGPT OAuth usage endpoints, and OpenAI's app-server account/rate-limit path is documented as ChatGPT account rate limits rather than ordinary API-key billing quota.
For a Pi status integration, the safer interpretation is that ChatGPT Codex subscription quota should use ChatGPT OAuth credentials or the Codex app-server, not an OpenAI API key.
Sources: `/tmp/pi-ui-quota-research/baby-menu/extensions/recipes/codex-quota.html`; `/tmp/pi-ui-quota-research/quota-axi/src/providers/codex.ts`; `/tmp/pi-ui-quota-research/quota-axi/test/providers/codex-auth.test.ts`; `/tmp/pi-ui-quota-research/openai-codex/codex-rs/app-server/README.md`.
A Pi integration can adapt the mechanism, but not as a blind frontend-only widget.
The status integration would need a backend extension path that reads local credentials without logging them, calls first-party ChatGPT/Codex endpoints directly or shells out to a local Codex app-server fallback, parses defensively, caches only normalized non-secret quota snapshots, and treats missing or unparsable data as unknown rather than inventing quota.
Sources: `/tmp/pi-ui-quota-research/quota-axi/README.md`; `/tmp/pi-ui-quota-research/quota-axi/AGENTS.md`; `/tmp/pi-ui-quota-research/quota-axi/src/providers/codex.ts`; `/tmp/pi-ui-quota-research/baby-menu/extensions/recipes/codex-quota.html`.
Pi's own installed OpenAI Codex provider already has OAuth credentials and a ChatGPT account id in its auth flow, but the previously inspected Pi provider code does not itself expose a quota endpoint.
Therefore a Pi-native implementation can either add a small first-party endpoint client using Pi's existing OpenAI Codex OAuth credential shape, or run `quota-axi`/Codex CLI as an external local data source when available.
Using Pi's auth file directly is more integrated, while using `quota-axi` is lower risk for quota parsing because it already handles multiple endpoint shapes and app-server fallback.
Sources: `[[060-pi-ui-codex-quota-research]]`; `/tmp/pi-ui-quota-research/quota-axi/src/providers/codex.ts`.
## Answer
Third-party tools obtain ChatGPT Codex quota from first-party ChatGPT/Codex rate-limit surfaces, not from screen scraping.
The established mechanisms are:
1. call ChatGPT backend usage endpoints such as `/backend-api/wham/usage` or `/backend-api/codex/usage` with local ChatGPT OAuth credentials and account id
2. fall back to Codex CLI app-server JSON-RPC, especially `account/rateLimits/read`
This is adaptable for a Pi status integration if it is implemented as local, read-only, credential-safe backend code with defensive parsing and an unknown/stale state.
It should not send OpenAI API keys to ChatGPT quota endpoints.
It should not expose tokens, account ids, or raw response bodies through the TUI, logs, or transcript.
## Limitations
This research read source code and documentation but did not call the live ChatGPT endpoints with the user's credentials.
That avoids probing authenticated undocumented surfaces during research.
The direct ChatGPT backend endpoints are first-party and used by OpenAI's Codex code, but they are still not public stable API documentation for third-party clients.
The app-server JSON-RPC surface is the best documented local interface when the Codex CLI is available and signed in.
## Citations
- `/tmp/pi-ui-quota-research/baby-menu/extensions/recipes/codex-quota.html`.
- `/tmp/pi-ui-quota-research/quota-axi/README.md`.
- `/tmp/pi-ui-quota-research/quota-axi/AGENTS.md`.
- `/tmp/pi-ui-quota-research/quota-axi/src/providers/codex.ts`.
- `/tmp/pi-ui-quota-research/quota-axi/test/providers/codex-auth.test.ts`.
- `/tmp/pi-ui-quota-research/openai-codex/codex-rs/app-server/README.md`.
- `/tmp/pi-ui-quota-research/openai-codex/codex-rs/app-server-protocol/src/protocol/v2/account.rs`.
- `/tmp/pi-ui-quota-research/openai-codex/codex-rs/backend-client/src/client.rs`.
- `/tmp/pi-ui-quota-research/openai-codex/codex-rs/backend-client/src/client/rate_limit_resets.rs`.