Skip to content

Runtime Routes

Codex Pooler exposes a deliberately narrow runtime surface. It is not a wildcard proxy and it does not claim full OpenAI API parity. Each route below is either a Codex backend compatibility route, a backend bridge route, a translated /v1 compatibility route, an operator metadata route, or an explicit unsupported boundary.

Use this page when you need to answer three questions before wiring a client:

  • Which endpoint should the client call?
  • Which upstream route does Codex Pooler call after admission and routing?
  • Is the request passed through as Codex backend traffic, translated into Codex work, partially supported, or blocked?

All runtime endpoints require Pool API key bearer auth unless noted otherwise. A Pool API key represents a Pool, not one upstream account. Codex Pooler still applies Pool policy, model support, limits, account health, route class admission, session continuity, and accounting before dispatching supported work upstream.

Use /backend-api/codex for Codex backend-compatible clients, /v1 for selected OpenAI SDK-compatible clients, and /mcp only for operator metadata tools. Runtime work on /backend-api and /v1 uses Pool API key bearer auth. MCP uses operator-owned MCP tokens and does not accept Pool API keys.

Route familyUse it forAuth boundary
/backend-api/codexCodex backend compatibility route for Codex-compatible clientsPool API key bearer auth
/backend-apiBackend file bridge, audio transcription, and backend usage routesPool API key bearer auth
/v1Narrow OpenAI-compatible /v1 support for selected SDK routesPool API key bearer auth
/mcpRead-only operator MCP endpoint for metadata lookupOperator-owned MCP bearer token
Usage routesRuntime usage checks exposed on compatibility pathsPool API key bearer auth
StatusMeaning
SupportedThe route is an active public route and enters the normal authenticated gateway path.
TranslatedThe client calls an OpenAI-shaped /v1 route, and Codex Pooler converts the request to Codex-compatible work before dispatch.
PartialThe route exists, but only a narrower behavior is supported than the name may imply.
UnsupportedThe route is blocked with a deterministic unsupported response or intentionally absent from the route surface.

Use /backend-api/codex for Codex-compatible clients:

https://codex-pooler.example.com/backend-api/codex

These endpoints keep Codex backend semantics and do not translate through the public OpenAI SDK adapter.

Exposed endpointUpstream destinationTranslationSupportNotes
GET /backend-api/codex/modelsModel metadata served from Pool/catalog stateNo Codex request translationSupportedLists models visible to the authenticated Pool, including backend Codex metadata such as context windows and optional comp_hash.
POST /backend-api/codex/responses/backend-api/codex/responses, or /backend-api/codex/responses/compact for terminal compaction triggersNo; backend payload is proxied through gateway normalizationSupportedPrimary Codex Responses route for JSON and SSE work. A valid terminal compaction_trigger bridges through compact handling and returns backend Responses SSE with encrypted compaction output. The compact bridge strips compact-unsupported controls such as store, stream, and include before upstream dispatch.
GET /backend-api/codex/responsesPersistent upstream Codex websocket response sessionNo HTTP adapter translationSupportedNarrow backend websocket route. It preserves websocket session continuity, uses x-codex-turn-state, and applies the admin-managed websocket_idle_timeout_ms downstream idle window.
POST /backend-api/codex/responses/compact/backend-api/codex/responses/compactNoSupportedBackend compact compatibility route.
POST /backend-api/codex/images/generations/backend-api/codex/images/generationsNo public /v1 image translationSupportedExplicit authenticated backend image proxy route; image prompt and source fields stay image-specific.
POST /backend-api/codex/images/edits/backend-api/codex/images/editsNo public /v1 image translationSupportedExplicit authenticated backend image edit proxy route.

Some Codex clients use /backend-api/codex/v1 as their base URL. Codex Pooler exposes exact aliases for that shape. These are still backend routes, not the public OpenAI-compatible /v1 surface.

Exposed endpointCanonical gateway targetTranslationSupportNotes
GET /backend-api/codex/v1/models/backend-api/codex/modelsNoSupportedAlias for backend model listing, including backend-only fields such as optional comp_hash.
POST /backend-api/codex/v1/responses/backend-api/codex/responses, or /backend-api/codex/responses/compact for terminal compaction triggersNoSupportedAlias for backend Responses. Prompt-cache routing locality can apply here. Terminal compaction triggers follow the canonical compact bridge.
GET /backend-api/codex/v1/responsesBackend websocket response sessionNoSupportedAlias for the backend websocket route. Prompt-cache routing locality is excluded, and the same websocket_idle_timeout_ms downstream idle window applies.
POST /backend-api/codex/v1/responses/compact/backend-api/codex/responses/compactNoSupportedAlias for backend compact. Prompt-cache routing locality is excluded.
POST /backend-api/codex/v1/chat/completions/backend-api/codex/responsesChat payload is coerced to backend Responses workSupportedBackend alias for chat-completion-shaped Codex clients. Prompt-cache routing locality can apply here.

Codex Pooler is a model-provider runtime boundary. It does not proxy Codex account helpers, analytics posting, thread-goal helpers, memory summaries, search helpers, realtime helper calls, safety helper calls, identity JWKS, or reset-credit consume operations. Configure Codex clients by pointing model_providers.*.base_url at /backend-api/codex. Supported Responses stream event metadata is relayed on model-provider streams as upstream sends it. Codex Pooler does not synthesize app-server notifications such as turn/safetyBuffering/updated.

These routes live under /backend-api or legacy usage paths. They are still Pool API key routes. The backend file bridge stores metadata only; file bytes stay upstream-backed.

Exposed endpointUpstream destinationTranslationSupportNotes
POST /backend-api/filesUpstream file create/upload-url flowNo OpenAI multipart translationSupportedAccepts JSON metadata only and returns upstream file metadata plus upload URL. Codex Pooler stores metadata only.
POST /backend-api/files/:file_id/uploadedUpstream file finalization flowNoSupportedMarks an upstream-backed file upload as complete.
POST /backend-api/transcribe/backend-api/transcribeNo public /v1 audio translationSupportedBackend multipart transcription route. It forces the backend transcription model and preserves safe multipart fields.
GET /api/codex/usageCodex usage resolverNoSupportedCompatibility usage route.
GET /wham/usageCodex usage resolverNoSupportedCompatibility usage route.
GET /backend-api/wham/usageCodex usage resolverNoSupportedBackend usage alias.

The app-server JSON-RPC reset-credit method account/rateLimitResetCredit/consume remains unsupported. Codex Pooler does not add a wildcard backend app-server proxy for reset-credit methods.

Use /v1 only for clients that require an OpenAI-shaped base URL:

https://codex-pooler.example.com/v1

Supported work is translated into Codex-compatible requests and then routed through the same Pool policy, limit, account-selection, accounting, and session-continuity machinery as backend traffic. Codex Pooler does not provide full OpenAI API parity.

Exposed endpointGateway/upstream destinationTranslated to Codex?SupportNotes
GET /v1/modelsOpenAI-shaped model metadata from Pool/catalog stateNo upstream Codex requestSupportedReturns an OpenAI-shaped model list for the authenticated Pool. Includes effective context_length when Codex context metadata is available; backend-only fields such as context_window, max_context_window, auto_compact_token_limit, and comp_hash are omitted.
POST /v1/responses/backend-api/codex/responsesYesTranslatedOpenAI Responses payloads are coerced to Codex-compatible work. System/developer input-message text is lifted into top-level instructions. Encrypted type: “compaction” replay items from prior remote compaction turns are forwarded. Remote MCP tool definitions are rejected before dispatch. Streaming responses use the public Responses stream adapter, and early terminal errors emit first without synthetic success prefixes. For public HTTP SSE only, if upstream has already emitted public Responses-visible data and ends before a terminal Responses event, Codex Pooler emits a sanitized response.failed terminal with upstream_stream_error; backend raw streams and websocket surfaces are not rewritten.
GET /v1/responsesBackend Codex websocket response sessionPartialPartialNarrow Responses websocket compatibility only. It is not OpenAI Realtime SDK support. It uses the same downstream idle and frame guardrails as backend Codex websockets.
POST /v1/chat/completions/backend-api/codex/responsesYesTranslatedChat Completions payloads are coerced to Codex Responses work and normalized back to Chat Completions shape. Early streaming terminal errors emit one public error chunk before any assistant role chunk.
GET /v1/usageCodex usage resolverNo upstream Codex work requestSupportedOpenAI-compatible usage read surface for the authenticated Pool.
GET /v1/filesCodex Pooler file metadataNoSupportedLists metadata for upstream-backed files visible to the Pool.
POST /v1/filesUpstream-backed file metadata create flowPartialPartialCreates metadata for Codex-compatible upstream file storage. Backend /backend-api/files remains JSON-only; this is the OpenAI-compatible file-create surface.
GET /v1/files/:file_idCodex Pooler file metadataNoSupportedRetrieves metadata only.
GET /v1/files/:file_id/contentNo upstream content readNoPartialChecks ownership, records an unsupported operation, then returns an OpenAI-shaped unsupported endpoint response. File bytes are not served by Codex Pooler.
DELETE /v1/files/:file_idNo upstream deleteNoPartialChecks ownership, records an unsupported operation, then returns an OpenAI-shaped unsupported endpoint response.
POST /v1/audio/transcriptions/backend-api/transcribeYesTranslatedOpenAI-style multipart transcription request dispatched through the backend transcription path.
POST /v1/images/generations/backend-api/codex/responsesYesTranslatedOpenAI image generation request is converted to Codex Responses-compatible image work.
POST /v1/images/edits/backend-api/codex/responsesYesTranslatedOpenAI image edit request is converted to Codex Responses-compatible image work.

POST /v1/responses accepts reasoning.context only for auto, current_turn, and all_turns after trimming and lowercasing. Unknown, empty, or non-string context values fail before dispatch with param: "reasoning.context".

Reasoning effort values can come from the client request or API-key policy. The policy is derived from its configured fields:

  1. Unrestricted preserves the current route behavior. Omission stays absent, and any currently accepted explicit effort, including a custom value, passes through this policy.
  2. Allow up to permits only known efforts at or below the selected ceiling: none, minimal, low, medium, high, xhigh, max, and ultra. The selected model’s effective known levels narrow the permitted set. An omitted effort resolves to the permitted model default, or the highest permitted known effort.
  3. Always use applies the legacy exact configured effort. It remains compatible even when the configured effort is absent from model metadata.

Allow up to never clamps or downgrades a request. An above-ceiling, unknown, or custom effort, or an omission with no permitted effort, returns 400 with code reasoning_effort_not_allowed and message reasoning effort is not available for this API key before reservation or upstream dispatch. Responses, backend Responses, and compact routes return param: "reasoning.effort"; Chat Completions returns param: "reasoning_effort". API-key model denial remains first and returns the existing 403 model_not_allowed response.

The same policy runs after websocket upgrade for every response.create frame. A forbidden frame uses the existing websocket error frame with the same status, code, message, and route-native parameter. The connection is not rejected at upgrade time.

Authenticated backend Codex model metadata reflects the policy. Unrestricted keeps the current levels and default. Allow up to filters to permitted known levels and a permitted default. Always use advertises its singleton only when it is model-effective, otherwise it returns no levels and no default. Models stay visible, and public /v1/models remains unchanged.

minimal and ultra remain distinct for policy evaluation. Backend Codex compatibility rewrites them to low and max respectively before upstream dispatch. Safe reasoning summaries retain requested, applied, and effective values.

Non-strict function tool schemas are lowered before local validation and upstream dispatch for backend Responses HTTP, backend Responses websocket response.create, and public /v1/responses compatibility paths. Lowering is limited to function tools, including nested function tools inside accepted namespace tools. Strict function tools and strict structured-output schemas stay on the strict validation path and are not made looser.

Catalog revision and final Responses envelope

Section titled “Catalog revision and final Responses envelope”

The authenticated backend model routes return the same effective catalog body for the same Pool and catalog snapshot. Both GET /backend-api/codex/models and GET /backend-api/codex/v1/models attach a deterministic weak ETag derived from that policy-visible body.

Successful backend Responses streams expose the same token as X-Models-Etag. It appears on HTTP SSE response headers for the canonical and backend-alias POST routes, and on websocket upgrade headers for the matching GET routes. The token is produced by Codex Pooler, not relayed from upstream. It is not exposed by compact, public /v1, usage, or unauthenticated routes. Catalog convergence across replicas is eventual, so clients should compare a successful Responses token with a later authenticated backend models token.

Every non-compact request that reaches the backend Responses destination has a reasoning object and exactly one reasoning.encrypted_content entry in include after final normalization. This applies to canonical backend HTTP and websocket traffic, backend /v1 Responses and Chat Completions aliases, and translated POST /v1/responses, GET /v1/responses, and POST /v1/chat/completions traffic. Compact dispatch is excluded and keeps its narrow compact request shape.

When upstream returns a valid parameter path with an error, failed attempt detail may expose it as upstream_error_param. The value is limited to a bounded field or numeric-index path. Invalid values and successful attempts omit the field, and raw upstream error messages or rejected values are never projected through it.

These POST /v1/responses request shapes return OpenAI-shaped invalid_request before gateway dispatch, not unsupported_endpoint:

  • top-level tools[].type = "mcp"
  • nested input[].type = "additional_tools" with tools[].type = "mcp"

These routes are deliberately present so clients receive deterministic OpenAI-shaped unsupported endpoint errors before gateway admission or upstream dispatch.

Exposed endpointUpstream destinationTranslated to Codex?SupportNotes
POST /v1/responses/compactNoneNoUnsupportedThe backend compact route exists under /backend-api/codex; the public /v1 compact route returns unsupported_endpoint.
POST /v1/images/variationsNoneNoUnsupportedImage variations are not implemented.
POST /v1/embeddingsNoneNoUnsupportedEmbeddings are outside the Codex Pooler route surface.
POST /v1/batchesNoneNoUnsupportedBatch jobs are not dispatched by Codex Pooler.
POST /v1/moderationsNoneNoUnsupportedModerations are not implemented.
POST /v1/fine_tuning/jobsNoneNoUnsupportedFine-tuning jobs are not implemented.
GET /v1/responses/:response_idNoneNoUnsupportedResponse retrieval by id is not part of the public compatibility surface.
POST /v1/responses/:response_id/cancelNoneNoUnsupportedResponse cancellation by id is not part of the public compatibility surface.
DELETE /v1/responses/:response_idNoneNoUnsupportedResponse deletion by id is not part of the public compatibility surface.

/v1/realtime and OpenAI Realtime SDK websocket/session routes are intentionally outside the public route surface. A client calling those paths should treat Codex Pooler as not supporting OpenAI Realtime. Use GET /v1/responses only for the narrow Responses websocket compatibility route documented above.

The operator MCP endpoint is rooted at /mcp, not under /backend-api or /v1.

RouteMeaning
POST /mcpJSON-RPC Streamable HTTP endpoint
GET /mcpRouted endpoint, but stateless SSE is unavailable today
OPTIONS /mcpAllowed MCP methods response

MCP uses operator-owned bearer MCP tokens. It doesn’t accept Pool API keys, browser sessions, cookies, query tokens, invite tokens, upstream tokens, or custom headers as authentication.

MCP output is metadata-only and scoped by the operator’s owner or assigned-Pool visibility. It is an operator inspection endpoint, not a runtime client endpoint.

The root /mcp operator endpoint is not a bridge for /v1/responses remote MCP tools.

Prompt-cache routing locality is a local routing hint. It can apply on POST /backend-api/codex/responses, POST /backend-api/codex/v1/responses, POST /backend-api/codex/v1/chat/completions, POST /v1/responses, and POST /v1/chat/completions. It is excluded from websocket, compact, file, audio, image, usage, and app-server helper routes. Locality is always a heuristic: it can improve the chance that compatible work reaches a reusable upstream connection, but it never guarantees a provider cache hit or cached-token accounting.

When a Pool enables the upstream websocket bridge, an eligible streaming POST /v1/responses request keeps HTTP SSE as its downstream contract while first attempting upstream dispatch through the continuity owner’s websocket. Internal upstream events remain buffered and do not commit the bridge. The bridge commits only when the first event that public Responses normalization would expose is forwarded downstream.

Any bridge failure before that commit boundary falls back to plain HTTP on the same candidate and attempt, with one settlement. After a public event has committed the websocket transport, Codex Pooler does not replay the turn over HTTP; a later upstream websocket failure ends the request as failed. Reusing an owner websocket is a cache-locality heuristic, never a cache guarantee.

During a mixed-release transition, native websocket attachment keeps its two-argument compatibility path against a previous-release owner. The bridge’s option-carrying three-argument attachment is unavailable there and fails closed to HTTP before commit. Previous-release owners also retain the legacy five-minute post-detach window and omit connection lifecycle metadata; new or recovered owners use the current 30-minute default.

Backend Codex websocket routes and the narrow public GET /v1/responses websocket route use bounded downstream guardrails. websocket_idle_timeout_ms controls the downstream websocket idle close window for new upgrades. It also bounds owner-forwarded full-turn submit waits for new websocket requests, so healthy long turns are not limited by upstream receive timeout. Its default is 1_800_000 ms, and accepted values are 60_000..3_600_000 ms.

websocket_owner_idle_timeout_ms is separate. It controls post-detach owner retention after no downstream or active turn remains, not downstream idle closure. It has the same 1_800_000 ms default and 60_000..3_600_000 ms bounds. Each new or recovered owner captures its node-local value at startup, and existing owners retain the value they captured.

Inbound websocket frames are also bounded by the configured gateway request body limit. Operators should treat reason_class=max_frame_size_exceeded as an oversized client frame, reason_class=timeout as downstream websocket idle close, and upstream receive timeout errors as separate upstream-side failures. These classifications are metadata-only and must not include raw websocket frames or request bodies.

Request compression is a per-Pool routing option named request_compression_enabled. It is disabled by default. When enabled, Codex Pooler may compress upstream-bound Responses tool-output content before dispatch. This is request-side only: raw outputs and upstream response bodies are not stored, and CCR/retrieval is not implemented.

Supported input shapes are explicit. Search-result compression accepts classic path:line[:column]: text, grouped heading output when a path-like heading has enough line matches below it, and portable NUL-delimited output shaped as path\0line[:column]: text. Diff compression requires a hunk header and accepts additions-only, deletions-only, replacement, minimal unified, combined unified, and long-preamble diffs without a leading diff --git header. Log-output compression keeps every discovered failure block when a summary reports failure/error counts, or skips the rewrite. Malformed NUL fragments, prose headings, ordinary prose with plus/minus lines, and incomplete failure-summary logs stay text/skip.

Protected exact-output tool results stay byte-for-byte upstream-bound before rewriting. This includes default function tools Read, Glob, Grep, Write, Edit, WebSearch, WebFetch, web_search, and web_fetch, plus external retrieval outputs. Output-only function tool results fail closed as protected when the tool name is unavailable. Metadata records aggregate skip counts only.

Eligible route families are exact:

FamilyEligible routes
Backend ResponsesPOST /backend-api/codex/responses
Backend /v1/responsesPOST /backend-api/codex/v1/responses
Translated chat completionsPOST /backend-api/codex/v1/chat/completions and POST /v1/chat/completions
Public /v1/responsesPOST /v1/responses
Compact backend routesPOST /backend-api/codex/responses/compact and POST /backend-api/codex/v1/responses/compact
Responses websocketbackend and narrow public websocket response.create payloads that dispatch to backend Responses

Unsupported surfaces are multipart, file, audio, image, admin, MCP, usage, and other non-Responses routes. POST /v1/responses/compact remains unsupported because the public compact route has no upstream dispatch.

Compression is fail-open. Scanner, tokenizer, compression, and limit errors preserve the original upstream request body and record safe payload_compression metadata. JSON request bodies over 1 MiB skip before scanning, and a dispatch processes at most 50 output candidates. Token counting is local and in-process with tokenizer data shipped by the application; it does not call OpenAI or load a local model.

Request logs show safe aggregate savings only. They prefer saved tokens and token savings percent when token counts are available, and fall back to saved bytes and byte savings percent when token counts are unavailable.

Continuity headers are also local routing inputs. Codex Pooler chooses them in this order:

  1. x-codex-window-id
  2. x-codex-session-id
  3. session-id
  4. x-session-id
  5. x-session-affinity
  6. session_id
  7. x-codex-conversation-id

session-id, x-session-id, and x-session-affinity are not forwarded upstream. If a pinned continuation points at an upstream account that now requires reauthentication, /v1/responses HTTP and websocket requests fail closed with a recovery hint to restart with full context and remove stale continuation anchors.

  • Routing Strategies explains Pool routing policy, account selection, and prompt-cache locality.

No. /v1 is narrow OpenAI-compatible support for selected SDK routes. Supported requests are translated into Codex-compatible work and routed through Pool policy. Unsupported routes are either intentionally absent or return deterministic OpenAI-shaped unsupported endpoint errors when explicitly routed.

Is GET /v1/responses OpenAI Realtime support?

Section titled “Is GET /v1/responses OpenAI Realtime support?”

No. GET /v1/responses is narrow Responses websocket compatibility. It is not /v1/realtime support, and OpenAI Realtime SDK websocket or session routes are outside the Codex Pooler route surface.

No. Pool API keys authenticate runtime clients for /backend-api and /v1. The root /mcp endpoint is for operator metadata only and requires an operator-owned MCP bearer token.

Does Codex Pooler store uploaded file bytes?

Section titled “Does Codex Pooler store uploaded file bytes?”

No. The backend file bridge stores file metadata and uses upstream-backed upload or download URLs. Raw file bytes, upload URLs, prompts, response bodies, media bodies, credentials, and websocket frames are not stored or exposed as public docs evidence.