Upstreams
The Upstreams page is the operator surface for Codex account capacity. An upstream is an account identity that Codex Pooler can assign to one or more Pools and consider for runtime routing when it is active, fresh, compatible, and inside usable quota windows.
Use this page when you need to answer:
- which upstream accounts are available
- which Pool each account is assigned to
- whether an account is active, paused, stale, or blocked by quota evidence
- whether token refresh or reauthorization needs attention
- how recent token usage compares with observed quota windows
- which account actions are available without exposing raw credentials
The page is metadata-only after linking or import. It shows operator labels, workspace and plan badges, safe status labels, quota-window evidence, token counters, assignment counts, and links to related logs. It does not show prompts, responses, files, websocket frames, bearer tokens, refresh tokens, provider cookies, OAuth provider payloads, or stored Codex auth.json contents.

What an Upstream Controls
Section titled “What an Upstream Controls”An upstream account is not a client credential. Clients authenticate with Pool API keys. Codex Pooler then chooses an eligible upstream assigned to that Pool.
An upstream controls:
- encrypted account credentials linked through OpenAI OAuth or imported from Codex
auth.json - account lifecycle state, such as active, paused, refresh due, or reauth required
- Pool assignments that make the account available to routing boundaries
- quota and token freshness evidence used by route eligibility
- model and route compatibility evidence observed from the account
- operator-facing labels used in cards, logs, audit events, and recovery views
Routing still happens at request time. A visible active upstream can be skipped if it is not assigned to the Pool, does not support the requested model or route shape, has stale credentials, is temporarily demoted, or is outside usable quota evidence.
Page Actions
Section titled “Page Actions”The page header exposes the account onboarding actions as separate buttons:
OAuth, for linking a new upstream account through OpenAI authorization without handlingauth.jsonInvite, for onboarding a person who will provide or operate an account through the browser UIImport, for adding an account from Codex CLI or Codex Desktopauth.jsoncredentials
Prefer OAuth for new operator-managed upstream accounts when browser authorization is practical. It stores resulting credential material through encrypted upstream secret storage and keeps the admin surface metadata-only.
Invite onboarding and the OAuth device-code fallback use OpenAI’s Codex device-code authorization. This setup is only for those device-code paths; browser OAuth linking does not depend on it. Before using an invite or fallback flow, a personal ChatGPT account should have Enable device code authorization for Codex enabled in ChatGPT Settings > Security. Workspace-managed accounts may need a workspace admin to enable device-code login for Codex in workspace permissions. If OpenAI blocks device-code approval, the invite or fallback flow may remain pending but the upstream will not become ready.
The search box filters upstream cards by account label or safe metadata. The Pool filter narrows cards to accounts assigned to a specific Pool. The status filter narrows cards by lifecycle or readiness state.
Account Cards
Section titled “Account Cards”Each account appears as a card. The header shows the operator label, workspace badge, plan badge, and dotted action menu. Clicking the account label opens the upstream cockpit.
The card body is split into status, token burn, quota windows, and footer metrics.
| Card area | Meaning |
|---|---|
| Status | Current lifecycle and route-readiness state for the account. Active means the account can be considered, but final routing still checks Pool assignment, model support, freshness, and quota evidence. |
| Token burn | Recent token multiplier shown from observed usage pressure. It is a quick warning signal, not a billing ledger. |
| Quota bars | Observed window fullness for account-level and model-specific quota windows. Green windows have usable room; red or exhausted windows can keep the account out of routing. |
| Routing | Compact lifecycle-aware runtime routing readiness summary. It separates identity lifecycle, Pool assignment, credential freshness, and quota evidence so operators can see why this account is likely eligible or blocked before request-specific checks. |
| Saved resets | Compact reported saved reset count badge from sanitized usage observations. The badge appears only when at least one saved reset is available; policy editing opens from the account-card Saved resets dropdown action. |
| Pools | How many Pools currently assign this upstream account. |
| 5m tokens | Recent token volume observed for this upstream over the short rolling window. |
Saved Resets
Section titled “Saved Resets”Account cards show a compact saved-reset count badge only when sanitized usage observations report at least one available reset. Common cockpit labels are N saved resets, No saved resets, Saved resets unavailable, and Saved resets not reported. When the upstream reset-credit list reports available-credit expirations, the badge title, cockpit summary, and saved-reset dialog also show the next expiration time. The count badge and the card dropdown action Saved resets open the saved-reset dialog.
The saved-reset dialog explains the banked reset count in plain operator terms and edits auto-redemption policy. If expiration metadata is available, it shows the next available saved reset expiration and the number of reported expiration dates. The dialog and cockpit both require an explicit confirmation before queueing a manual Redeem one saved reset action. Saving the policy never enqueues redemption work.
Manual redemption is enabled only when the upstream is not deleted or disabled, credentials are usable, at least one Pool assignment exists, a saved-reset count has been reported, the reported count is greater than zero, and no fresh redemption is already in progress. A stale in-progress attempt is not a blocker; confirming manual redemption lets the worker recover the stale attempt state before claiming a new redemption. Otherwise the action is disabled with the matching blocker, such as missing credentials, no Pool assignment, unreported count, no available resets, or a fresh in-progress redemption.
Auto redemption is a per-upstream opt-in policy available from the account-card Saved resets dialog and the upstream cockpit. New accounts default to auto redemption off. Operators choose whether automatic redemption waits until weekly quota is blocked or may start earlier when fresh weekly quota evidence shows every eligible candidate account is near the configured Near-limit threshold. The blocked mode is still allowed to rescue a saved reset with a known expiration inside the next 24 hours when that same account already has weekly usage to recover and the natural weekly reset is not close. The Natural reset buffer prevents spending when the weekly quota will reset naturally soon, and Keep credits reserves banked resets from automatic use.
Saved reset observations and redemption attempts stay metadata-only on upstream_identities.metadata under saved_resets and saved_reset_redemption. The saved-reset observation may include sanitized aggregate expiration fields such as available_expires_at, next_expires_at, expires_observed_at, and expires_refresh_attempted_at; it must not include raw provider credit objects, identifiers, titles, descriptions, or redemption request ids. Policy fields live on the upstream identity as saved_reset_auto_redeem_enabled, saved_reset_auto_redeem_trigger_mode, saved_reset_auto_redeem_quota_threshold_percent, saved_reset_auto_redeem_min_blocked_minutes, and saved_reset_auto_redeem_keep_credits. Do not copy provider payloads, raw credit objects or identifiers, redemption request identifiers, token material, or account secrets into metadata, logs, docs, or tests.
Readiness States
Section titled “Readiness States”Common upstream states are:
| State | Meaning |
|---|---|
| Active | The account is configured and can be considered for eligible Pool traffic. |
| Paused | The account stays configured, but Codex Pooler should not select it for new traffic. |
| Refresh due | The account needs credential or quota refresh work before freshness is trusted. |
| Refreshing | A background refresh is currently updating account evidence or credentials. |
| Refresh failed | refresh_failed means credential or auth lifecycle refresh failed. Treat it as identity recovery work first; quota readiness may still be unknown or stale until credentials are relinked or refreshed successfully. |
| Reauth required | The account needs operator recovery before it can route work again. Relink with OpenAI OAuth, import replacement credentials, or reinvite the account when those actions are available. |
| Quota exhausted | Observed quota evidence says the account should not receive matching work until one or more windows reset. |
Readiness is intentionally conservative. If quota evidence is missing, stale, or exhausted, Codex Pooler may keep an account out of routing even when the card still exists and the account is assigned to a Pool.
Import auth.json
Section titled “Import auth.json”Click Import to open the upstream credentials dialog when an existing Codex auth.json is the right source of account credentials.

The import dialog asks for:
- target Pool, which assigns the imported account to a routing boundary
- pasted
auth.jsoncontents, when the file is already open - uploaded
auth.json, when the file is available on disk
The upload accepts small auth files only. The current UI states a 64 KB limit.
After import, Codex Pooler becomes the refresh-token authority for that account lineage. Do not keep using the same auth.json from another Codex install, machine, or automation. Provider refresh-token rotation can invalidate one copy and move the account into reauth_required.
The dialog footer keeps docs on the left and the submit actions on the right. Cancel closes without importing. Import auth.json stores the credential material through encrypted upstream secret storage.
OpenAI OAuth Upstream Linking
Section titled “OpenAI OAuth Upstream Linking”OpenAI OAuth upstream linking is an authenticated admin workflow. Use
OAuth on /admin/upstreams to link a new OpenAI upstream account to a selected Pool. Use
/admin/upstreams/:id to relink or reconnect the exact upstream identity shown
in the cockpit. Relink checks the returned account and workspace claims against
the target identity before replacing encrypted credential material.
The browser manual callback workflow is:
- open the OAuth link or relink dialog
- choose
Browser - open the generated OpenAI authorization URL
- complete OpenAI authorization in the browser
- paste the resulting local callback URL back into the admin dialog
- submit the callback form and wait for the success or safe error state
- use
Closeafter the dialog reports that the account was linked or relinked
The local callback URL is consumed only by the already-authenticated admin page,
and there is no hosted OAuth callback route, no public /auth/callback, and no
/api/admin/* or dashboard JSON API for this workflow.
Use the device-code fallback when browser authorization is not practical. The dialog shows the user code and verification URL while the flow is pending, and the page polls only while the operator keeps the dialog open. Device-code authorization must be enabled for Codex on the OpenAI account or workspace. If device authorization is unavailable or denied, use the browser workflow or ask the workspace admin to enable Codex device-code login.
Immediately after a successful link, the new account is not guaranteed to route
traffic. Codex Pooler creates the initial Pool assignment and enqueues account
reconciliation to prime quota evidence. That quota refresh can require a token
refresh first. If token refresh fails, the account can move to refresh_failed
before any user request is routed, and runtime routing excludes it until token
refresh succeeds or the credentials are relinked.
Operators should never paste callback URLs, authorization codes, tokens, cookies, raw auth.json, OpenAI provider payloads, or local credential files into docs, tickets, logs, or evidence. The admin UI may show the one-time authorization URL or device user code during a pending flow, but persisted flow summaries, audit metadata, request logs, tests, and docs stay metadata-only.
Safe OAuth troubleshooting codes:
| Code | Operator action |
|---|---|
invalid_callback_url | Paste the full localhost callback URL from the browser address bar. |
invalid_callback_origin | Use only the http://localhost:1455/auth/callback URL produced by the OpenAI flow. |
missing_state | Restart the OAuth flow from the admin dialog. |
duplicate_callback_param | Restart the OAuth flow and paste the unedited callback URL. |
missing_callback_result | Restart the OAuth flow because the callback did not include a usable result. |
provider_denied | The OpenAI authorization was denied; restart only if the account should be connected. |
invalid_state | Restart from the current admin dialog; an old or unrelated callback was pasted. |
expired_flow | Start a new OAuth flow. |
flow_not_pending | Close the stale dialog state, start a fresh OAuth link or relink flow, and use the latest callback URL. |
stale_flow | A newer flow superseded this one; use the latest dialog state. |
token_exchange_failed | Retry once, then inspect OpenAI availability and sanitized provider status. |
identity_mismatch | Relink with the same OpenAI account and workspace shown in the cockpit. |
identity_conflict | Resolve the duplicate or ambiguous upstream identity before retrying. |
unauthorized_pool | Confirm the operator can manage the selected Pool. |
Card Action Menu
Section titled “Card Action Menu”Open the dotted menu on an upstream card for account actions.

The current actions are:
| Action | What it does |
|---|---|
| Rename | Opens a label dialog. This changes the operator-facing account label only. |
| Pause | Stops the account from being selected for new runtime work while keeping it configured. |
| Reactivate | Returns a paused or recoverable account to active consideration when the action is enabled. |
| Refresh token | Requests a token-refresh job for the account. Use this when freshness evidence is stale or recovery instructions ask for it. |
| Replace auth.json | Appears for recovery states that can accept replacement account credentials. |
| Reinvite account | Appears for recovery states where operator-driven reauthorization is the right next step. |
| Delete | Soft-deletes the upstream from active use. This is an immediate destructive account-lifecycle action in the current UI, so use it only when the account should leave routing. |
Some actions are disabled or hidden depending on the account state. For example, Reactivate is not useful while an account is already active, and recovery actions only appear when the account is in a recovery-eligible state.
Rename Dialog
Section titled “Rename Dialog”Rename opens a small account dialog.

The label is the operator-facing name used in cards and related metadata. It is not the provider account ID, not a Pool API key, and not secret material. Use labels that make operations clear without embedding private customer or credential details.
Upstream Cockpit
Section titled “Upstream Cockpit”Clicking an account label opens the upstream cockpit.

The cockpit is the focused detail view for one account. The top summary shows identity state, quota posture, request posture, saved reset status, stored account identifier hash, lifecycle badges, token freshness, and quota freshness. It also exposes OAuth relink for reconnecting the selected upstream identity through OpenAI OAuth, Redeem saved reset when manual redemption is available, and the saved-reset auto-redemption policy controls.
Saved-reset manual redemption is available from the cockpit and from the account-card saved-reset dialog. The summary metric shows the reported count, the actions area shows Redeem saved reset when manual redemption is available, and the saved-reset policy form controls auto redemption, trigger mode, near-limit threshold, natural reset buffer, and reserved credits.
Use it when the card says an account is degraded, stale, exhausted, or needs recovery. The detail page provides more space for assignment posture, quota health, recent events, and related links without exposing raw account secrets.
Operational Checklist
Section titled “Operational Checklist”When an upstream is not routing as expected, check it in this order:
- confirm the upstream state is
active - confirm it is assigned to the Pool used by the client API key
- confirm the Pool itself is active
- inspect the routing footer for lifecycle-aware runtime routing readiness across identity state, Pool assignment, credential freshness, quota signals, and request posture
- inspect quota bars for exhausted account-level or model-specific windows; quota readiness is only one input to routing readiness
- confirm token freshness and quota freshness are recent enough to trust
- open the upstream cockpit when the card shows degraded, stale, or recovery states
- use Request logs filtered by Pool or upstream metadata to confirm whether traffic selected this account
- use Audit logs when lifecycle, assignment, import, pause, or rename actions changed recently
If an account remains inactive after linking, import, or refresh, treat reauth_required as a credential-lineage problem first. Prefer OAuth relink when browser authorization is practical. Importing the same stale auth.json again may not recover it if another machine already rotated the refresh token.