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.
Which Runtime Route Should I Use?
Section titled “Which Runtime Route Should I Use?”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.
Quick map
Section titled “Quick map”| Route family | Use it for | Auth boundary |
|---|---|---|
/backend-api/codex | Codex backend compatibility route for Codex-compatible clients | Pool API key bearer auth |
/backend-api | Backend file bridge, audio transcription, and backend usage routes | Pool API key bearer auth |
/v1 | Narrow OpenAI-compatible /v1 support for selected SDK routes | Pool API key bearer auth |
/mcp | Read-only operator MCP endpoint for metadata lookup | Operator-owned MCP bearer token |
| Usage routes | Runtime usage checks exposed on compatibility paths | Pool API key bearer auth |
Status labels
Section titled “Status labels”| Status | Meaning |
|---|---|
| Supported | The route is an active public route and enters the normal authenticated gateway path. |
| Translated | The client calls an OpenAI-shaped /v1 route, and Codex Pooler converts the request to Codex-compatible work before dispatch. |
| Partial | The route exists, but only a narrower behavior is supported than the name may imply. |
| Unsupported | The route is blocked with a deterministic unsupported response or intentionally absent from the route surface. |
Codex backend compatibility
Section titled “Codex backend compatibility”Use /backend-api/codex for Codex-compatible clients:
https://codex-pooler.example.com/backend-api/codexThese endpoints keep Codex backend semantics and do not translate through the public OpenAI SDK adapter.
| Exposed endpoint | Upstream destination | Translation | Support | Notes |
|---|---|---|---|---|
GET /backend-api/codex/models | Model metadata served from Pool/catalog state | No Codex request translation | Supported | Lists models visible to the authenticated Pool, including backend Codex metadata such as the selected raw context_window, effective_context_window_percent, automatic compaction limit, and optional comp_hash. Provider accounts can temporarily report different catalog ceilings for the same model; Pooler selects one canonical source cohort for the Pool. Codex applies the percentage once, while the separate /v1/models surface publishes the same selected window as a flattened context_length. |
POST /backend-api/codex/responses | /backend-api/codex/responses | No; backend payload is proxied through gateway normalization | Supported | Primary Codex Responses route for JSON and SSE work, including supported backend compaction. |
GET /backend-api/codex/responses | Persistent upstream Codex websocket response session | No HTTP adapter translation | Supported | Narrow backend websocket response-stream compatibility for Codex-compatible clients, including native backend compaction support. |
POST /backend-api/codex/responses/compact | /backend-api/codex/responses/compact | No | Supported | Backend compact compatibility route. |
POST /backend-api/codex/images/generations | /backend-api/codex/images/generations | No public /v1 image translation | Supported | Explicit authenticated native image proxy route. Pool image permission applies before body parsing. On either native image route, a policy-authorized effective image model that is genuinely absent from the Pool catalog may use eligible visible host capacity while its effective identifier is preserved exactly. A catalog-present but invisible target remains invalid. Image prompt and source fields stay image-specific. |
POST /backend-api/codex/images/edits | /backend-api/codex/images/edits | No public /v1 image translation | Supported | Explicit authenticated native image edit proxy route. Pool image permission applies before body parsing. The same policy-authorized, catalog-absent native image routing applies: eligible visible host capacity anchors the request while the effective image identifier is preserved exactly. A catalog-present but invisible target remains invalid. |
Backend /v1 aliases
Section titled “Backend /v1 aliases”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 endpoint | Canonical gateway target | Translation | Support | Notes |
|---|---|---|---|---|
GET /backend-api/codex/v1/models | /backend-api/codex/models | No | Supported | Alias for backend model listing, including backend-only fields such as optional comp_hash. |
POST /backend-api/codex/v1/responses | /backend-api/codex/responses | No | Supported | Alias for backend Responses, including supported backend compaction. Prompt-cache routing locality can apply here. |
GET /backend-api/codex/v1/responses | Backend websocket response session | No | Supported | Alias for the backend websocket response-stream compatibility route, including native backend compaction support. |
POST /backend-api/codex/v1/responses/compact | /backend-api/codex/responses/compact | No | Supported | Alias for backend compact. Prompt-cache routing locality is excluded. |
POST /backend-api/codex/v1/chat/completions | /backend-api/codex/responses | Chat payload is coerced to backend Responses work | Supported | Backend alias for chat-completion-shaped Codex clients. Prompt-cache routing locality can apply here. |
Backend app-server helper routes
Section titled “Backend app-server helper routes”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.
Backend bridge and usage routes
Section titled “Backend bridge and usage routes”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 endpoint | Upstream destination | Translation | Support | Notes |
|---|---|---|---|---|
POST /backend-api/files | Upstream file create/upload-url flow | No OpenAI multipart translation | Supported | Accepts JSON metadata only and returns upstream file metadata plus upload URL. Codex Pooler stores metadata only. |
POST /backend-api/files/:file_id/uploaded | Upstream file finalization flow | No | Supported | Marks an upstream-backed file upload as complete. |
POST /backend-api/transcribe | /backend-api/transcribe | Separate public /v1 audio transcription translation | Supported | Backend multipart transcription route. It forces the backend transcription model and preserves safe multipart fields. |
GET /api/codex/usage | Codex usage resolver | No | Supported | Compatibility usage route. |
GET /wham/usage | Codex usage resolver | No | Supported | Compatibility usage route. |
GET /backend-api/wham/usage | Codex usage resolver | No | Supported | Backend 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.
OpenAI-compatible /v1 routes
Section titled “OpenAI-compatible /v1 routes”Use /v1 only for clients that require an OpenAI-shaped base URL:
https://codex-pooler.example.com/v1Supported 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 endpoint | Gateway/upstream destination | Translated to Codex? | Support | Notes |
|---|---|---|---|---|
GET /v1/models | OpenAI-shaped model metadata from Pool/catalog state | No upstream Codex request | Supported | Returns 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/responses | Yes | Translated | OpenAI Responses payloads are coerced to Codex-compatible work. Input audio uses the public {data, format} shape and accepts WAV, MP3, M4A, WebM, and OGG. The decoded audio ceiling is 50 MiB (52,428,800 bytes), while the configured request envelope may reject a request earlier. Malformed, unsupported, or oversized audio returns a sanitized invalid_request before upstream dispatch. System/developer input-message text is lifted into top-level instructions. Exactly one final compaction_trigger after visible input requests an explicit compaction turn; non-streaming JSON and public SSE return the normalized compact item. 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. If visible public output ends without a terminal Responses event, public HTTP SSE returns a sequence-valid sanitized type: “error” / nested server_error terminal. Native backend streams and websocket surfaces retain their route-native behavior. |
GET /v1/responses | Backend Codex websocket response session | Partial | Partial | Narrow Responses websocket compatibility only. It is not OpenAI Realtime SDK support. Exactly one final compaction_trigger after visible input returns the same normalized compaction item as HTTP through response.output_item.done and response.completed. Encrypted compaction replay follows the same field and ordering contract as POST /v1/responses. It uses the same downstream idle and frame guardrails as backend Codex websockets. Malformed JSON and JSON non-object provider frames are dropped without consuming a public sequence number or creating a local terminal. |
POST /v1/chat/completions | /backend-api/codex/responses | Yes | Translated | Chat Completions payloads are coerced to Codex Responses work and normalized back to Chat Completions shape. Official nested custom-tool definitions and named custom choices are translated to the supported flat Responses subset; completed and streamed custom calls return the Chat custom shape, and streamed free-form input is never parsed as function JSON. Input audio uses the public {data, format} shape and accepts WAV, MP3, M4A, WebM, and OGG. The decoded audio ceiling is 50 MiB (52,428,800 bytes), while the configured request envelope may reject a request earlier. Malformed, unsupported, or oversized audio returns a sanitized invalid_request before upstream dispatch. Early streaming terminal errors emit one public error chunk before any assistant role chunk. After visible output, a stream that ends without an upstream terminal emits one nested data: {“error”:{…}} chunk with no following [DONE]; the translated POST /backend-api/codex/v1/chat/completions alias has the same OpenAI-compatible HTTP SSE behavior. |
GET /v1/usage | Codex usage resolver | No upstream Codex work request | Supported | OpenAI-compatible usage read surface for the authenticated Pool. |
GET /v1/files | Codex Pooler file metadata | No | Supported | Lists metadata for upstream-backed files visible to the Pool. |
POST /v1/files | Upstream-backed file metadata create flow | Partial | Partial | Creates 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_id | Codex Pooler file metadata | No | Supported | Retrieves metadata only. |
GET /v1/files/:file_id/content | No upstream content read | No | Partial | Checks 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_id | No upstream delete | No | Partial | Checks ownership, records an unsupported operation, then returns an OpenAI-shaped unsupported endpoint response. |
POST /v1/audio/transcriptions | /backend-api/transcribe | Yes | Translated | OpenAI-style multipart transcription request dispatched through the backend transcription path. gpt-transcribe is a caller alias for canonical gpt-4o-transcribe. Nonempty keywords and languages lists retain order and duplicates, while empty lists are omitted. Responses omit language-detection fields. This is request-shape compatibility, not a transcription-quality, model-discovery, or general Audio API coverage claim. |
POST /v1/images/generations | /backend-api/codex/responses | Yes | Translated | OpenAI image generation request is converted to Codex Responses-compatible image work. Pool image permission applies before body parsing. |
POST /v1/images/edits | /backend-api/codex/responses | Yes | Translated | OpenAI image edit request is converted to Codex Responses-compatible image work. Pool image permission applies before body parsing. |
For explicit remote compaction on the narrow public surface, the request must contain visible input followed by exactly one final {"type":"compaction_trigger"} item. Invalid placement returns 400 invalid_request on input before upstream dispatch. Successful HTTP JSON returns one completed Responses object; public SSE emits response.output_item.done, response.completed, and [DONE]; narrow Responses websocket completion emits the same two Responses events without [DONE].
The returned replay item has type: "compaction", nonblank opaque encrypted_content, and optional id whose absence, string value, or explicit null is preserved. Start the next request as a new chain without previous_response_id, put the compaction item first, and append new visible input after it. When an accepted narrow Responses websocket compaction continuation carries an explicit opaque response anchor, Codex Pooler preserves it only on the current live upstream websocket connection with the same generation and effective Full/Lite mode. That incremental compact collects provider output before validation, settlement, and adaptation; it never reconnects, retries, switches assignment, or falls back to HTTP. If that connection or mode is unavailable, the request returns the existing previous_response_not_found recovery result and the client can submit a separate no-anchor full-history request. When no anchor is present, Codex Pooler sends the supplied full history through the existing HTTP compact path. Unknown replay fields and malformed values reject before upstream dispatch. Malformed upstream compact JSON or missing encrypted content returns sanitized 502 invalid_compaction_response. Direct POST /v1/responses/compact remains unsupported.
Pool image permission
Section titled “Pool image permission”One Pool setting, allow_image_generation, controls exactly four authenticated
POST routes: /backend-api/codex/images/generations,
/backend-api/codex/images/edits, /v1/images/generations, and
/v1/images/edits. It defaults to true for new Pools and existing routing
rows without a stored value. When it is disabled, runtime ingress authenticates
the Pool API key, then returns 403 with code image_generation_disabled
before decompression, request parsing, compatibility coercion, admission, or
upstream dispatch.
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:
- Unrestricted preserves the current route behavior. Omission stays absent, and any currently accepted explicit effort, including a custom value, passes through this policy.
- Allow up to permits only known efforts at or below the selected ceiling:
none,minimal,low,medium,high,xhigh,max, andultra. 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. - 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.
Direct public Responses requests also accept exact executable custom tools on
POST /v1/responses and websocket response.create. Exact top-level custom
definitions and nested custom definitions are accepted in an already-valid
namespace. functions is the
canonical Codex namespace example, not a restriction: any nonblank valid
namespace accepts the same flat function and exact custom children. A custom
tool requires type: "custom" and a nonblank name. It may include a
description, boolean defer_loading, nullable allowed_callers using direct
or programmatic, and omitted, unconstrained text, or a lark/regex grammar
format. Hosted, MCP, tool-search, nested-namespace, malformed, and duplicate
executable-name shapes are rejected; executable names must be globally unique
across top-level and namespace children.
A typed custom tool_choice resolves only a declared same-kind custom tool with
the same exact name, whether it is top-level or an accepted namespace child.
Full mode preserves that typed choice. Lite mode rejects every map-shaped
tool_choice before upstream dispatch with unsupported_parameter and
param: "tool_choice"; use automatic or explicit Full mode when a client needs
forced typed selection. That rejection follows the model’s serving mode rather
than the endpoint, so any map-shaped tool_choice is rejected on a Lite-served
model, including a Chat Completions named-function choice. See
Responses Lite and Full for what the two
serving modes change on the outgoing request. String choices such
as auto are accepted in both modes. This is separate from accepted
custom_tool_call replay input.
Translated Chat Completions accepts the official nested custom definition
shape, with type: "custom" and a nested custom object containing a nonblank
name plus optional description and format. Its named custom choice uses the
same outer wrapper and a nested custom name. Codex Pooler flattens those values
into the supported Responses request shape, then projects completed and streamed
custom_tool_call output back into the Chat custom object. Custom input stays
free-form text across split SSE deltas and is never parsed as function JSON.
Direct-Responses-only fields such as defer_loading and allowed_callers are
not accepted inside the Chat wrapper. Malformed wrappers and unrelated tool
families still fail before dispatch.
Actual execution availability still depends on the selected model and upstream account. Smoke verification retains metadata only. This narrow contract does not imply backend or broad OpenAI tool parity.
When an accepted namespace custom declaration has one exact executable name,
public Responses HTTP, SSE, and websocket output
restores that namespace on a custom_tool_call only if the provider omits it or
returns null. An explicit provider namespace is preserved. Flat, unknown, and
non-unique names remain unchanged rather than guessed.
For direct public Responses only, a strict flat function tool whose parameters
already have an object root may receive a missing nested object or array
type when the surrounding schema provides complete, unambiguous structural
evidence. This covers top-level flat functions and flat function children of an
accepted namespace, and the same repair applies to websocket response.create.
It does not repair the parameters root, explicit type values, refs, definition
tables, combinators or their descendants, annotations, unknown keywords,
ambiguous or incomplete evidence, structured outputs, Chat Completions, the
older nested function wrapper shape, or backend routes. Public Responses and
Chat reject malformed, duplicate, and unsupported explicit type values. This
strict compatibility repair is not non-strict schema lowering.
Strict structured output and function parameters on the narrow public
OpenAI-compatible surface require a direct concrete object root. A root
$ref or root anyOf is rejected. Supported nested constructs, including
local refs, remain valid below that root. Non-strict requests and native backend
Responses behavior are unchanged. POST /backend-api/codex/v1/chat/completions
uses translated Chat semantics, so it follows this public strict-root contract.
Invalid strict structured output returns HTTP 400 with
invalid_json_schema at its root schema parameter, such as
text.format.schema or response_format.json_schema.schema. Invalid strict
function parameters return HTTP 400 with invalid_function_parameters at
the applicable root parameter family: tools.<index>.parameters,
tools.<index>.function.parameters, or
tools.<namespace_index>.tools.<tool_index>.parameters. These public
rejections occur before upstream dispatch and durable accounting.
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.
Unsupported /v1 Responses request shapes
Section titled “Unsupported /v1 Responses request shapes”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"withtools[].type = "mcp"
Routed but unsupported /v1 endpoints
Section titled “Routed but unsupported /v1 endpoints”These routes are deliberately present so clients receive deterministic OpenAI-shaped unsupported endpoint errors before gateway admission or upstream dispatch.
| Exposed endpoint | Upstream destination | Translated to Codex? | Support | Notes |
|---|---|---|---|---|
POST /v1/responses/compact | None | No | Unsupported | The backend compact route exists under /backend-api/codex; the public /v1 compact route returns unsupported_endpoint. |
POST /v1/images/variations | None | No | Unsupported | Image variations are not implemented. |
POST /v1/content_provenance_checks | None | No | Unsupported | Content provenance checks require a Platform API surface that Codex Pooler does not expose. |
POST /v1/embeddings | None | No | Unsupported | Embeddings are outside the Codex Pooler route surface. |
POST /v1/batches | None | No | Unsupported | Batch jobs are not dispatched by Codex Pooler. |
POST /v1/moderations | None | No | Unsupported | Moderations are not implemented. |
POST /v1/fine_tuning/jobs | None | No | Unsupported | Fine-tuning jobs are not implemented. |
GET /v1/responses/:response_id | None | No | Unsupported | Response retrieval by id is not part of the public compatibility surface. |
POST /v1/responses/:response_id/cancel | None | No | Unsupported | Response cancellation by id is not part of the public compatibility surface. |
DELETE /v1/responses/:response_id | None | No | Unsupported | Response deletion by id is not part of the public compatibility surface. |
Intentionally absent /v1 route families
Section titled “Intentionally absent /v1 route families”/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.
MCP endpoint
Section titled “MCP endpoint”The operator MCP endpoint is rooted at /mcp, not under /backend-api or /v1.
| Route | Meaning |
|---|---|
POST /mcp | JSON-RPC Streamable HTTP endpoint |
GET /mcp | Routed endpoint, but stateless SSE is unavailable today |
OPTIONS /mcp | Allowed 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 and continuity boundaries
Section titled “Prompt-cache and continuity boundaries”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 and never guarantees a provider cache hit or cached-token accounting.
Websocket Guardrails
Section titled “Websocket Guardrails”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. Its default is 1_800_000 ms, and accepted values are 60_000..3_600_000 ms.
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 boundaries
Section titled “Request compression boundaries”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.
Recognized same-frame command-backed file reads are also protected byte-for-byte
before output-range lookup, content detection, or any compression strategy. The
bounded read grammar accepts direct cat, nl, head, tail, and print-only
sed reads, plus one nl-to-print-only-sed pipeline. Function calls publish
call_id; native local-shell calls publish call_id and id; matching outputs
must resolve through those same-frame identifiers. Duplicate, cross-kind, or
conflicting identifiers preserve the original output. Malformed or unrecognized
commands retain existing behavior.
Eligible route families are exact:
| Family | Eligible routes |
|---|---|
| Backend Responses | POST /backend-api/codex/responses |
Backend /v1/responses | POST /backend-api/codex/v1/responses |
| Translated chat completions | POST /backend-api/codex/v1/chat/completions and POST /v1/chat/completions |
Public /v1/responses | POST /v1/responses |
| Compact backend routes | POST /backend-api/codex/responses/compact and POST /backend-api/codex/v1/responses/compact |
| Responses websocket | backend 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. This does not change support for backend compact compatibility.
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:
x-codex-window-idx-codex-session-idsession-idx-session-idx-session-affinitysession_idx-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.
Related references
Section titled “Related references”- Routing Strategies explains Pool routing policy, account selection, and prompt-cache locality.
Frequently Asked Questions
Section titled “Frequently Asked Questions”Is /v1 the same as the OpenAI API?
Section titled “Is /v1 the same as the OpenAI API?”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.
Can a Pool API key call /mcp?
Section titled “Can a Pool API key call /mcp?”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.