Skip to content

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:

  1. which upstream accounts are available
  2. which Pool each account is assigned to
  3. whether an account is active, paused, stale, or blocked by quota evidence
  4. whether token refresh or reauthorization needs attention
  5. how recent token usage compares with observed quota windows
  6. 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.

Upstreams page overview

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:

  1. encrypted account credentials linked through OpenAI OAuth or imported from Codex auth.json
  2. account lifecycle state, such as active, paused, refresh due, or reauth required
  3. Pool assignments that make the account available to routing boundaries
  4. quota and token freshness evidence used by route eligibility
  5. model and route compatibility evidence observed from the account
  6. 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.

The page header exposes the account onboarding actions as separate buttons:

  1. OAuth, for linking a new upstream account through OpenAI authorization without handling auth.json
  2. Invite, for onboarding a person who will provide or operate an account through the browser UI
  3. Import, for adding an account from Codex CLI or Codex Desktop auth.json credentials

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.

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 areaMeaning
StatusCurrent 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 burnRecent token multiplier shown from observed usage pressure. It is a quick warning signal, not a billing ledger.
Quota barsObserved 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.
RoutingCompact 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 resetsCompact 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.
PoolsHow many Pools currently assign this upstream account.
5m tokensRecent token volume observed for this upstream over the short rolling window.

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.

Common upstream states are:

StateMeaning
ActiveThe account is configured and can be considered for eligible Pool traffic.
PausedThe account stays configured, but Codex Pooler should not select it for new traffic.
Refresh dueThe account needs credential or quota refresh work before freshness is trusted.
RefreshingA background refresh is currently updating account evidence or credentials.
Refresh failedrefresh_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 requiredThe 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 exhaustedObserved 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.

Click Import to open the upstream credentials dialog when an existing Codex auth.json is the right source of account credentials.

Import auth.json dialog

The import dialog asks for:

  1. target Pool, which assigns the imported account to a routing boundary
  2. pasted auth.json contents, when the file is already open
  3. 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 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:

  1. open the OAuth link or relink dialog
  2. choose Browser
  3. open the generated OpenAI authorization URL
  4. complete OpenAI authorization in the browser
  5. paste the resulting local callback URL back into the admin dialog
  6. submit the callback form and wait for the success or safe error state
  7. use Close after 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:

CodeOperator action
invalid_callback_urlPaste the full localhost callback URL from the browser address bar.
invalid_callback_originUse only the http://localhost:1455/auth/callback URL produced by the OpenAI flow.
missing_stateRestart the OAuth flow from the admin dialog.
duplicate_callback_paramRestart the OAuth flow and paste the unedited callback URL.
missing_callback_resultRestart the OAuth flow because the callback did not include a usable result.
provider_deniedThe OpenAI authorization was denied; restart only if the account should be connected.
invalid_stateRestart from the current admin dialog; an old or unrelated callback was pasted.
expired_flowStart a new OAuth flow.
flow_not_pendingClose the stale dialog state, start a fresh OAuth link or relink flow, and use the latest callback URL.
stale_flowA newer flow superseded this one; use the latest dialog state.
token_exchange_failedRetry once, then inspect OpenAI availability and sanitized provider status.
identity_mismatchRelink with the same OpenAI account and workspace shown in the cockpit.
identity_conflictResolve the duplicate or ambiguous upstream identity before retrying.
unauthorized_poolConfirm the operator can manage the selected Pool.

Open the dotted menu on an upstream card for account actions.

Upstream card action menu

The current actions are:

ActionWhat it does
RenameOpens a label dialog. This changes the operator-facing account label only.
PauseStops the account from being selected for new runtime work while keeping it configured.
ReactivateReturns a paused or recoverable account to active consideration when the action is enabled.
Refresh tokenRequests a token-refresh job for the account. Use this when freshness evidence is stale or recovery instructions ask for it.
Replace auth.jsonAppears for recovery states that can accept replacement account credentials.
Reinvite accountAppears for recovery states where operator-driven reauthorization is the right next step.
DeleteSoft-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 opens a small account dialog.

Rename upstream 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.

Clicking an account label opens the upstream cockpit.

Upstream cockpit overview

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.

When an upstream is not routing as expected, check it in this order:

  1. confirm the upstream state is active
  2. confirm it is assigned to the Pool used by the client API key
  3. confirm the Pool itself is active
  4. inspect the routing footer for lifecycle-aware runtime routing readiness across identity state, Pool assignment, credential freshness, quota signals, and request posture
  5. inspect quota bars for exhausted account-level or model-specific windows; quota readiness is only one input to routing readiness
  6. confirm token freshness and quota freshness are recent enough to trust
  7. open the upstream cockpit when the card shows degraded, stale, or recovery states
  8. use Request logs filtered by Pool or upstream metadata to confirm whether traffic selected this account
  9. 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.