Skip to main content

Unofficial Python SDK for the ChatGPT Codex backend API

Project description

codex-backend-sdk

Unofficial Python SDK for the ChatGPT Codex backend API (chatgpt.com/backend-api/codex).

This package mirrors the official OpenAI Python SDK shape for the API surface that the Codex backend exposes. Use OpenAI, client.responses.create(...), and client.models.list() just as you would with openai-python, with Codex-specific authentication and backend limitations under the hood.

Requirements: a ChatGPT Plus, Pro, or Enterprise subscription. Authentication goes through ChatGPT OAuth and stores tokens in ~/.codex/auth.json.

Disclaimer: This is an independent, community-maintained library that reverse-engineers undocumented endpoints of chatgpt.com. It is not affiliated with, endorsed by, or supported by OpenAI.

Installation

git clone https://github.com/B4PT0R/codex-backend-sdk.git
cd codex-backend-sdk
pip install -e .

Basic Usage

from codex_backend_sdk import OpenAI

client = OpenAI().authenticate()

response = client.responses.create(
    model="gpt-5.4",
    input="Explain quicksort in one paragraph.",
)

print(response.output_text)

Streaming

stream = client.responses.create(
    model="gpt-5.4",
    input="Say 'hi' five times.",
    stream=True,
)

for event in stream:
    if event.type in {"response.output_text.delta", "response.content_part.delta"}:
        delta = event.delta
        print(delta if isinstance(delta, str) else delta.get("text", ""), end="")

Models

models = client.models.list()
for model in models:
    print(model.id, model.display_name, model.context_window)

info = client.models.retrieve("gpt-5.4")

Multi-Turn Input

The Codex backend does not expose previous_response_id, so pass prior input/output items explicitly.

history = [
    {"role": "user", "content": "My name is Alice. Say OK."},
]

reply1 = client.responses.create(input=history).output_text
history.append({"role": "assistant", "content": reply1})
history.append({"role": "user", "content": "What is my name?"})

reply2 = client.responses.create(input=history).output_text
print(reply2)

Function Calling

import json

tools = [{
    "type": "function",
    "name": "get_weather",
    "description": "Get the current weather for a city.",
    "parameters": {
        "type": "object",
        "properties": {"city": {"type": "string"}},
        "required": ["city"],
        "additionalProperties": False,
    },
}]

first = client.responses.create(
    input="What's the weather in Paris?",
    tools=tools,
)

call = next(item for item in first.output if item["type"] == "function_call")
result = {"temperature": 18, "unit": "celsius", "condition": "cloudy"}

second = client.responses.create(
    input=[
        call,
        {
            "type": "function_call_output",
            "call_id": call["call_id"],
            "output": json.dumps(result),
        },
    ],
    tools=tools,
)

print(second.output_text)

Structured Output

schema = {
    "title": "person",
    "type": "object",
    "properties": {
        "name": {"type": "string"},
        "age": {"type": "integer"},
    },
    "required": ["name", "age"],
    "additionalProperties": False,
}

response = client.responses.create(
    input="Extract: Bob is 42 years old.",
    text={
        "format": {
            "type": "json_schema",
            "name": "person",
            "schema": schema,
            "strict": True,
        }
    },
)

Supported Backend Endpoints

The SDK exposes the supported backend endpoints through either OpenAI-shaped resources (responses, models, realtime) or Codex-only resources (codex).

Backend endpoint SDK method Notes
POST /backend-api/codex/responses client.responses.create(...) Stream-only backend; non-streaming SDK calls are collected from SSE events.
POST /backend-api/codex/responses/compact client.responses.compact(...) Codex-specific helper for encrypted context compaction.
GET /backend-api/codex/models client.models.list() / client.models.retrieve(...) OpenAI-shaped model objects with Codex metadata preserved as extra fields.
POST /backend-api/codex/realtime/calls client.realtime.calls.create(...) OpenAI-shaped SDP call creation for realtime sessions.
wss://api.openai.com/v1/realtime?model=... client.realtime_websocket_url(...) / client.realtime_websocket_headers(...) Helper surface used by codex-agent's realtime plugin.
POST /v1/embeddings client.embeddings.create(...) Uses the Codex OAuth access token against api.openai.com; verified with text-embedding-3-small.
POST /v1/audio/transcriptions client.audio.transcriptions.create(...) Uses the Codex OAuth access token against api.openai.com; verified with gpt-4o-mini-transcribe.
GET /backend-api/wham/usage client.codex.usage() Codex/ChatGPT quota and rate-limit status.
GET /backend-api/wham/tasks/list client.codex.tasks.list(...) Raw Codex cloud task listing.
GET /backend-api/wham/tasks/{task_id} client.codex.tasks.retrieve(task_id) Raw Codex cloud task detail.
GET /backend-api/wham/tasks/{task_id}/turns client.codex.tasks.turns.list(task_id) Raw task turn mapping.
GET /backend-api/wham/tasks/{task_id}/turns/{turn_id}/sibling_turns client.codex.tasks.turns.sibling_turns(task_id, turn_id) Raw sibling turn list.
GET /backend-api/wham/environments client.codex.environments.list() Raw Codex cloud environment list.
GET /backend-api/memories client.codex.memories.list() Raw ChatGPT memory payload for the authenticated account.
GET /backend-api/user_system_messages client.codex.user_system_messages.retrieve() Raw ChatGPT customization/system-message payload.

Responses

client.responses.create(...) follows the official OpenAI Responses API where the Codex backend overlaps with it.

Supported request fields:

  • model
  • input
  • instructions
  • include
  • parallel_tool_calls
  • prompt_cache_key
  • reasoning
  • service_tier
  • store=False
  • stream
  • text
  • tool_choice
  • tools

The backend itself requires streaming. When stream=True, the SDK yields ResponseStreamEvent objects directly. When stream is omitted or false, the SDK consumes the SSE stream and returns a collected Response.

response = client.responses.create(
    model="gpt-5.4",
    instructions="Be concise.",
    input=[
        {"role": "user", "content": "Summarize this API shape."},
    ],
    reasoning={"effort": "medium", "summary": "auto"},
    include=["reasoning.encrypted_content"],
    text={"verbosity": "medium"},
    prompt_cache_key="session-123",
)

Unsupported official Responses parameters are rejected explicitly with CodexBackendUnsupportedParameterError, including temperature, top_p, max_output_tokens, metadata, user, safety_identifier, truncation, previous_response_id, conversation, background, prompt, prompt_cache_retention, and stream_options.

Context Compaction

client.responses.compact(...) is specific to the Codex backend. It compresses a long Responses-style input list into an opaque encrypted compaction summary that can be replayed in later input arrays.

compacted = client.responses.compact(
    model="gpt-5.4",
    instructions="Keep task-critical context.",
    input=history,
)

history = compacted.output

The returned CompactedResponse.output contains regular response items plus one or more {"type": "compaction_summary", ...} items. Treat those summaries as opaque backend state.

Models

client.models.list() and client.models.retrieve(model) mirror the official OpenAI models resource, while preserving Codex-specific metadata as extra Pydantic fields.

models = client.models.list()
for model in models:
    print(
        model.id,
        model.context_window,
        model.supported_in_api,
        model.supports_reasoning_summaries,
    )

Common extra fields include:

  • display_name
  • description
  • context_window
  • supported_in_api
  • supports_reasoning_summaries
  • support_verbosity
  • default_verbosity
  • default_reasoning_level
  • supported_reasoning_levels
  • auto_compact_token_limit
  • prefer_websockets
  • input_modalities
  • available_in_plans
  • base_instructions
  • priority
  • raw

Realtime

The SDK keeps the realtime surface available for integrations that bridge Codex auth with voice sessions.

client.realtime.calls.create(...) mirrors the official OpenAI SDK call shape:

answer = client.realtime.calls.create(
    sdp=offer_sdp,
    session={"type": "realtime", "model": "gpt-realtime-1.5"},
)

print(answer.text)

For WebSocket-based plugins such as codex-agent, the client also exposes small helpers that reuse the OpenAI API key stored by the Codex OAuth flow:

url = client.realtime_websocket_url(model="gpt-realtime-1.5")
headers = client.realtime_websocket_headers(session_id="voice-session")

realtime_websocket_headers(...) requires ~/.codex/auth.json to contain openai_api_key. The default authenticate(request_api_key=True) flow stores that key when available.

Embeddings

client.embeddings.create(...) mirrors the official OpenAI embeddings resource and sends the Codex OAuth access token directly to api.openai.com/v1.

embedding = client.embeddings.create(
    model="text-embedding-3-small",
    input="Embed this sentence.",
    dimensions=256,
)

print(embedding.data[0].embedding)

Audio Transcriptions

client.audio.transcriptions.create(...) mirrors the official OpenAI transcriptions resource for non-streaming calls.

with open("meeting.wav", "rb") as audio:
    transcription = client.audio.transcriptions.create(
        model="gpt-4o-mini-transcribe",
        file=("meeting.wav", audio, "audio/wav"),
        response_format="json",
    )

print(transcription.text)

Quota And Usage

client.codex.usage() calls the ChatGPT WHAM usage endpoint. It returns the raw quota payload from the backend because the shape contains plan-specific fields.

quota = client.codex.usage()
primary = quota.get("rate_limit", {}).get("primary_window", {})
print(primary.get("used_percent"))

Typical fields include:

  • plan_type
  • rate_limit.allowed
  • rate_limit.limit_reached
  • rate_limit.primary_window
  • rate_limit.secondary_window
  • additional_rate_limits
  • credits
  • rate_limit_reached_type

Codex Cloud Tasks

The client.codex.tasks and client.codex.environments namespaces expose read-only WHAM cloud-task payloads as raw backend dictionaries.

tasks = client.codex.tasks.list(limit=10)
task = client.codex.tasks.retrieve(tasks["items"][0]["id"])
turns = client.codex.tasks.turns.list(task["task"]["id"])
environments = client.codex.environments.list()

Supported task-list filters are limit, cursor, task_filter, and environment_id.

ChatGPT Account Data

The client.codex namespace also exposes read-only ChatGPT account data that is not part of the official OpenAI SDK.

memories = client.codex.memories.list()
customization = client.codex.user_system_messages.retrieve()

Both methods return raw backend dictionaries because these payloads can contain personal account-specific fields and may change without notice.

Observed But Not Exposed

The reverse-engineering notes in docs/backend-api.md include additional observed endpoints. They are not exposed as SDK resources yet because they are plan-gated, unavailable on chatgpt.com, or not stable enough:

  • POST /backend-api/codex/memories/trace_summarize
  • GET /backend-api/wham/config/requirements
  • POST /v1/audio/speech (auth reaches the endpoint, but Pro OAuth lacks api.model.audio.request in current tests)

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

codex_backend_sdk-0.3.0.tar.gz (33.6 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

codex_backend_sdk-0.3.0-py3-none-any.whl (27.7 kB view details)

Uploaded Python 3

File details

Details for the file codex_backend_sdk-0.3.0.tar.gz.

File metadata

  • Download URL: codex_backend_sdk-0.3.0.tar.gz
  • Upload date:
  • Size: 33.6 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.13

File hashes

Hashes for codex_backend_sdk-0.3.0.tar.gz
Algorithm Hash digest
SHA256 b2a8acdec294dd260546e8182e46f2938b68dbe4925f74a17f82da4045fef1da
MD5 3a0e955b2c9777ebdde33cba9a74a91c
BLAKE2b-256 fd73707020b891142fb7bb125a208d0c2fa5e91fa1d679b9a3495e801eb8db28

See more details on using hashes here.

File details

Details for the file codex_backend_sdk-0.3.0-py3-none-any.whl.

File metadata

File hashes

Hashes for codex_backend_sdk-0.3.0-py3-none-any.whl
Algorithm Hash digest
SHA256 4d40a75a387d9d218ef7c84b1762016e8536bc0d2d1a357b678045f41a7e5c3f
MD5 3a9d8025fb42cf7d7e68e22f8818eb5b
BLAKE2b-256 445310216326ed039caf001abe1fdc1749dc3b5c1b26028173acd8ad0831ef33

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page