Skip to main content

codex-backend-sdk

Unofficial Python SDK for building independent harnesses and integrations on top of the backend capabilities available to an authenticated Codex/ChatGPT subscriber.

The package intentionally separates three kinds of API:

Surface Purpose Typical stability
client.* OpenAI-shaped inference and media primitives exposed by Codex Most familiar and typed
client.codex.* Codex-specific account, cloud, search, and Remote Control capabilities Product-specific
client.chatgpt.* ChatGPT product surfaces observed in the official Desktop client Broadest, often raw

Requirements: a ChatGPT Plus, Pro, or Enterprise subscription. Authentication uses the official Codex OAuth client and stores compatible credentials in ~/.codex/auth.json.

Independent project: this library reverse-engineers undocumented backend contracts. It is not affiliated with, endorsed by, or supported by OpenAI. Availability can vary by plan, workspace, rollout, and backend revision.

Install

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

Quickstart

from codex_backend_sdk import OpenAI

client = OpenAI().authenticate()

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

print(response.output_text)

authenticate() reuses existing Codex credentials when possible and otherwise opens the browser OAuth flow. Most examples below assume an authenticated client created this way.

Choose the right surface

Direct client: inference and reusable primitives

Start here for the common building blocks of an agent or application:

client.responses       # text/reasoning/tool inference, parsing, compaction
client.models          # Codex model catalog
client.files           # upload files for Apps/MCP parameters
client.images          # Codex-backed image generation and editing
client.audio           # ChatGPT-backed transcription
client.embeddings      # OpenAI embeddings endpoint through OAuth
client.live            # OpenAI-shaped GPT-Live creation and sideband attachment
client.realtime        # additive low-level Codex Realtime v3 transport

These resources follow openai-python conventions where the backend overlaps with the public OpenAI API. Backend-specific restrictions remain explicit. See the compatibility matrix for the audited signatures, transport adaptations, and intrinsic OAuth/backend boundaries.

client.codex: Codex product capabilities

Use this namespace for capabilities owned by Codex rather than the general Responses API:

client.codex.web_search          # structured search/page/weather/etc. commands
client.codex.usage               # quota plus detailed usage
client.codex.tasks               # Codex cloud tasks and turns
client.codex.environments        # cloud environments and machines
client.codex.repositories        # repository and branch discovery
client.codex.remote_control      # Remote Control server and host discovery
client.codex.config              # managed Codex settings/configuration
client.codex.profile             # Codex profile
client.codex.memories            # account memories and trace summarization
client.codex.worktree_snapshots  # cloud-task archive uploads

client.chatgpt: Desktop-observed product APIs

Use this namespace when an integration needs ChatGPT product state or hosted Apps rather than Codex inference:

client.chatgpt.conversations  # ChatGPT history and streaming conversation API
client.chatgpt.projects       # projects, files, saves, connector scopes
client.chatgpt.files          # file library, attachments, downloads, processing
client.chatgpt.search         # cross-product indexed search
client.chatgpt.apps           # hosted Apps/MCP transports and widgets
client.chatgpt.plugins        # plugin catalogs, skills, bundles, sharing
client.chatgpt.connectors     # connector discovery, linking, external actions
client.chatgpt.models         # ChatGPT and third-party model catalogs
client.chatgpt.voice          # voices, dictation metadata, read-aloud speech
client.chatgpt.account        # account metadata and explicit preferences

These private product schemas evolve more often. The SDK therefore returns raw dictionaries or raw streams when imposing a stable model would be misleading.

Common workflows

Generate a response

response = client.responses.create(
    model="gpt-5.5",
    instructions="Be concise.",
    input="Summarize the CAP theorem.",
    reasoning={"effort": "medium", "summary": "auto"},
)

print(response.output_text)
print(response.reasoning_summary)

The backend always streams internally. Without stream=True, the SDK collects events and returns a typed Response.

Stream output

stream = client.responses.create(
    input="Write a short limerick about Linux.",
    stream=True,
)

for event in stream:
    if event.type == "response.output_text.delta":
        print(event.delta, end="", flush=True)

For long-lived integrations, the alternate WebSocket transport keeps one connection reusable across sequential turns:

with client.responses.websocket.connect() as ws:
    for event in ws.create({"model": "gpt-5.5", "input": "Say hello."}):
        if event.get("type") == "response.output_text.delta":
            print(event.get("delta", ""), end="")

Maintain a multi-turn conversation

The Codex backend does not expose previous_response_id; preserve prior items in the next request:

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

first = client.responses.create(input=history)
history.extend(first.output)
history.append({"role": "user", "content": "What is my name?"})

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

Compact a long context

compacted = client.responses.compact(
    model="gpt-5.5",
    instructions="Preserve task-critical decisions and unresolved work.",
    input=history,
)

history = compacted.output

Compaction items are opaque encrypted backend state. Replay them as input; do not parse or modify their contents.

Call a function

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 is the weather in Paris?",
    tools=tools,
)
call = first.tool_calls[0]

second = client.responses.create(
    input=[
        call,
        {
            "type": "function_call_output",
            "call_id": call["call_id"],
            "output": json.dumps({"temperature": 18, "unit": "celsius"}),
        },
    ],
    tools=tools,
)
print(second.output_text)

Parse structured output

from pydantic import BaseModel

class Person(BaseModel):
    name: str
    age: int

result = client.responses.parse(
    input="Extract: Ada is 37 years old.",
    text_format=Person,
)

print(result.output_parsed)

Discover available models

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

model = client.models.retrieve("gpt-5.5")

Upload a file

uploaded = client.files.upload("report.csv")
print(uploaded.uri)  # sediment://file_...

The helper creates ChatGPT file metadata, uploads to the backend-issued signed URL, and finalizes the file for Apps/MCP file parameters.

Transcribe audio

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

print(transcript.text)

Generate or edit an image

import base64

image = client.images.generate(
    model="gpt-image-2",
    prompt="A cheerful blue robot holding a red flower",
)

with open("robot.png", "wb") as output:
    output.write(base64.b64decode(image.data[0].b64_json))

edited = client.images.edit(
    image=open("robot.png", "rb"),
    mask=open("mask.png", "rb"),
    prompt="Add a small red star in the center",
)

Codex workflows

result = client.codex.web_search.search(
    id="search-session-1",
    model="gpt-5-search-api",
    commands={
        "search_query": [{"q": "Python packaging PEP 735"}],
        "response_length": "short",
    },
)

print(result["output"])
continuation = result.get("encrypted_output")

The same transport supports page operations, image search, finance, weather, sports, and time commands. See the API reference for command validation.

Inspect quota and detailed usage

quota = client.codex.usage()
daily = client.codex.usage_details.daily_token_breakdown()
credits = client.codex.usage_details.credit_events()
plugin_metrics = client.codex.usage_details.plugin_usage_metrics(
    start_date="2026-09-01",
    end_date="2026-09-18",
)

print(quota.get("rate_limit", {}).get("primary_window"))

Work with Codex cloud tasks

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"])
logs = client.codex.tasks.turns.logs(task["task"]["id"], turns[0]["id"])

environments = client.codex.environments.list()
repositories = client.codex.repositories.search(
    "codex",
    connector_id="github-connector-id",
)

Creation, cancellation, environment updates, cache resets, and pull-request operations are explicit mutations; discovery methods never invoke them.

Run a Remote Control server

server = client.codex.remote_control.enroll(
    name="My workstation",
    installation_id="stable-installation-id",
    os="linux",
    arch="x86_64",
    app_server_version="0.147.0",
)

pairing = client.codex.remote_control.pairing.start(server, manual_code=True)
print(pairing.manual_pairing_code)

with client.codex.remote_control.connect(
    server,
    installation_id="stable-installation-id",
    server_name="My workstation",
) as connection:
    for envelope in connection:
        print(envelope)

The transport deliberately leaves protocol-v3 envelopes raw. A bridge must preserve client, stream, sequence, ACK, chunk, and cursor semantics. Never log pairing codes or Remote Control tokens.

ChatGPT product workflows

Search and retrieve ChatGPT history

page = client.chatgpt.conversations.list(limit=20)
matches = client.chatgpt.conversations.search("release notes")
conversation = client.chatgpt.conversations.retrieve("conv_...")

global_matches = client.chatgpt.search.global_search(
    "release notes",
    sources=("conversation",),
    limit=20,
)

ChatGPT conversations are product history, not Codex App Server threads and not Responses API state.

Browse projects and files

projects = client.chatgpt.projects.list_all()
project = client.chatgpt.projects.retrieve(projects[0]["id"])
project_conversations = client.chatgpt.projects.conversations(projects[0]["id"])

library = client.chatgpt.files.list_library_files()
content = client.chatgpt.files.download("file_...")

Download helpers can return bytes, BytesIO, a persisted Path, or the raw HTTP response. OAuth is retained for ChatGPT URLs and omitted from signed CDN URLs.

Use hosted Apps/MCP

tools = client.chatgpt.apps.list_tools()
result = client.chatgpt.apps.call_tool("connector_tool_name", {"query": "..."})

with client.chatgpt.apps.connect_hosted_mcp() as mcp:
    hosted_tools = mcp.list_tools()["tools"]
    resources = mcp.list_resources()["resources"]

Hosted tools may mutate external services. The calling harness must inspect tool annotations and own user confirmation; the SDK never auto-invokes tools.

Discover plugins and skills

plugins = client.chatgpt.plugins.list_all(scope="GLOBAL")
installed = client.chatgpt.plugins.installed_all()
suggested = client.chatgpt.plugins.suggested()
home = client.chatgpt.plugins.home()
skill = client.chatgpt.plugins.skill("plugins~...", "skill-name")

checkout = client.chatgpt.plugins.bundles.extract_plugin(
    "plugins~...",
    "./plugins/example",
)

Bundle helpers enforce HTTPS, download limits, archive limits, safe relative paths, manifest checks, and atomic extraction. Signed download URLs never receive the user's OAuth bearer.

Discover connectors safely

connectors = client.chatgpt.connectors.directory.list_all()
detail = client.chatgpt.connectors.retrieve(
    connectors[0]["id"],
    include_actions=True,
)
links = client.chatgpt.connectors.links.list_accessible()

Read-only discovery is separate from client.chatgpt.connectors.authentication and client.chatgpt.connectors.external_actions. Linking, email, contacts, and Google Drive conversion require explicit method calls and caller-owned approval.

Generate subscription-backed speech

speech = client.chatgpt.voice.synthesize_pronunciation(
    text="Bonjour Baptiste",
    pronunciation_language="fr-FR",
)

speech.write_to_file("bonjour.mp3")

The ChatGPT read-aloud service is smaller than the public speech API: it exposes language and playback speed, not arbitrary model and voice selection. It can return a typed in-memory object, bytes, BytesIO, a data URI, or a file path.

Advanced transports

Realtime voice

live = client.live.create(
    session={
        "model": "gpt-live-1-codex",
        "instructions": "Speak naturally and stay concise.",
        "delegation": {"type": "client"},
    },
    transport={"type": "webrtc", "sdp": offer_sdp},
)
apply_remote_sdp(live.transport.sdp)

with client.live.sideband.connect(session_id=live.session.id) as sideband:
    for event in sideband:
        print(event.type)

Live probes confirmed gpt-live-1-codex and gpt-live-1-boulder-alpha. They are Codex Realtime v3 snapshots, not aliases for the public gpt-live-1 model. client.live follows the current openai-python creation, response, and sideband idioms while adapting them to the ChatGPT OAuth call transport.

The earlier low-level surface remains available for backend-specific code:

answer = client.realtime.calls.create_v3(
    sdp=offer_sdp,
    session={"model": "gpt-live-1-codex"},
)
with client.realtime.sideband.connect(call_id=answer.call_id) as sideband:
    sideband.send({"type": "session.close"})

The OAuth backend's event dialect is still experimental and is exposed forward-compatibly through LiveEvent rather than rewritten into invented public fields. The public primary client.live.connect() WebSocket is not available through ChatGPT OAuth; use WebRTC plus the attached sideband.

Embeddings

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

Unlike ChatGPT transcription and Codex image generation, embeddings target the OpenAI Platform endpoint and may consume the associated platform quota.

Authentication and lifecycle

Browser OAuth

client = OpenAI().authenticate()

Use authenticate(interactive=False) to require existing usable credentials without opening a browser, or force=True to request a fresh interactive login.

Device-code OAuth

client = OpenAI().authenticate_device_code(
    on_code=lambda code: print(code.verification_url, code.user_code),
    allowed_workspace_ids=["optional-workspace-id"],
)

This is suited to headless or remote harnesses that cannot receive a loopback OAuth callback.

Logout versus revocation

client.logout()  # local, offline, idempotent
client.revoke()  # remote OAuth revocation, then local cleanup

logout() does not invalidate the account session remotely. revoke() is an explicit network mutation and clears local credentials only after success.

Reliability and safety

  • Transient 429, 5xx, timeout, and connection failures are retried by default; configure max_retries and retry_base_delay on OpenAI(...).
  • Private backend schemas may change without notice. Typed models are used only where a stable boundary is useful.
  • Mutations are explicitly named and separated from discovery where possible.
  • Payments, subscriptions, workspace administration, attestation, reporting, telemetry, analytics, and beacons are deliberately not exposed.
  • Personal access tokens are outside this OAuth-focused SDK surface.

Documentation

Development

uv sync --extra dev
uv run pytest -q
uv run python -m compileall -q codex_backend_sdk
uv build

Live probes are intentionally kept separate from the deterministic test suite: tests must not consume quota, mutate account state, or depend on rollout state.

License

MIT. See LICENSE.

Release files for codex-backend-sdk 0.5.4

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for codex-backend-sdk 0.5.4
File Size Uploaded
codex_backend_sdk-0.5.4.tar.gz 187.8 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for codex-backend-sdk 0.5.4
File Interpreter ABI Platform
codex_backend_sdk-0.5.4-py3-none-any.whl Python 3 none any Details

Total release size: 270.1 kB

Release files / codex_backend_sdk-0.5.4.tar.gz

Download URL codex_backend_sdk-0.5.4.tar.gz
Size 187.8 kB
Tags Source
SHA-256 checksum
How to use checksums
179a411d0d8ec077a0de13b4f3354cf722021150b3fbd0442accf0ac2c81d95a
BLAKE2b-256 checksum
How to use checksums
c011fbb8834975f954fa5e95db52b4eece66df0dd05fa1b93b10268e6a8a4908
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via uv/0.11.7 {"installer":{"name":"uv","version":"0.11.7","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

Release files / codex_backend_sdk-0.5.4-py3-none-any.whl

Download URL codex_backend_sdk-0.5.4-py3-none-any.whl
Size 82.3 kB
Tags Python 3
SHA-256 checksum
How to use checksums
8793bfb6b7d3d7bf0221837f4902b4248599b63963a792ac8bc989b5ec7dbdc4
BLAKE2b-256 checksum
How to use checksums
bbe07acf2885cc9a5f7dd4424f2f5de7d8cfe2909713aeab7a9ba7819d128269
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via uv/0.11.7 {"installer":{"name":"uv","version":"0.11.7","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

Release history Release notifications | RSS feed

This release

0.5.4 This release

2 release files

0.5.3

2 release files

0.5.2

2 release files

0.5.1

2 release files

0.5.0

2 release files

0.4.0

2 release files

0.3.10

2 release files

0.3.9

2 release files

0.3.8

2 release files

0.3.7

2 release files

0.3.6

2 release files

0.3.5

2 release files

0.3.4

2 release files

0.3.3

2 release files

0.3.2

2 release files

0.3.1

2 release files

0.3.0

2 release files

0.2.0

2 release files

0.1.1

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page