CGChatGPT Desktop API
Reference · version 1

ChatGPT Desktop API

A localhost OpenAI-compatible interface to the authenticated ChatGPT section of the official macOS desktop app. The bridge runs on your computer and drives the app through Chrome DevTools Protocol.

This is an experimental, unofficial automation bridge. It is not an OpenAI-supported API and does not turn a ChatGPT account into a remotely hosted service.

Quickstart

Requirements: macOS, the official ChatGPT app signed in with an account, and Node.js 22 or newer.

Open the ChatGPT dashboard for the copyable one-line terminal connection command and live bridge status.

Install the bridge

mkdir -p ~/.local/bin
curl -fsSL https://chatgpt.codexauthapi.dev/bridge.js \
  -o ~/.local/bin/chatgpt-api
chmod +x ~/.local/bin/chatgpt-api
~/.local/bin/chatgpt-api install

The installer registers a per-user macOS LaunchAgent. The bridge starts now, restarts if it exits, starts automatically at login, and remains available after you close the terminal.

Manage the background service

~/.local/bin/chatgpt-api status
~/.local/bin/chatgpt-api restart
~/.local/bin/chatgpt-api stop
~/.local/bin/chatgpt-api start
~/.local/bin/chatgpt-api uninstall

Send your first request

curl http://127.0.0.1:1456/v1/chat/completions \
  -H 'Content-Type: application/json' \
  -d '{
    "model": "chatgpt-desktop",
    "messages": [
      {"role": "user", "content": "Reply with: connected"}
    ]
  }'

Chat completions

POSThttp://127.0.0.1:1456/v1/chat/completions

Submits one serialized request through the ChatGPT desktop composer and returns an OpenAI-style JSON completion or live server-sent event stream.

Request body

FieldTypeDescription
modelstringOptional. Use an id returned by GET /v1/models to select that real desktop model. chatgpt-desktop preserves the app's current selection.
messagesarrayRequired, non-empty conversation messages. Roles and text are flattened into the desktop prompt.
streambooleanOptional. When true, returns OpenAI-compatible chat.completion.chunk server-sent events ending in data: [DONE].
stream_optionsobjectOptional. Set include_usage: true for a final zero-count usage chunk before [DONE].
timeout_msnumberOptional desktop response timeout. Defaults to 180,000 ms and is capped at 300,000 ms.

Message content may be a string or an array of text parts using type: "text" or type: "input_text".

Example response

{
  "id": "chatcmpl_…",
  "object": "chat.completion",
  "created": 1787670000,
  "model": "chatgpt-desktop",
  "choices": [{
    "index": 0,
    "message": {
      "role": "assistant",
      "content": "connected"
    },
    "logprobs": null,
    "finish_reason": "stop"
  }],
  "usage": {
    "prompt_tokens": 0,
    "completion_tokens": 0,
    "total_tokens": 0
  }
}

Token counts are zero because the desktop UI does not expose authoritative usage accounting to the bridge.

Streaming example

curl -N http://127.0.0.1:1456/v1/chat/completions \
  -H 'Content-Type: application/json' \
  -d '{
    "model": "chatgpt-desktop",
    "stream": true,
    "messages": [{"role":"user","content":"Count from one to five."}]
  }'

Streaming starts as text appears in ChatGPT. Disconnecting the client cancels the desktop generation and releases the serialized request queue.

Image generations

POSThttp://127.0.0.1:1456/v1/images/generations

Generates one PNG through a fresh regular ChatGPT conversation and returns an OpenAI-compatible base64 image response.

curl http://127.0.0.1:1456/v1/images/generations \
  -H 'Content-Type: application/json' \
  -d '{
    "model": "gpt-image-1",
    "prompt": "A watercolor fox reading beside a window",
    "n": 1,
    "response_format": "b64_json"
  }'
FieldRequirement
promptRequired non-empty string.
modelOptional; only gpt-image-1 is accepted.
nOptional; must be 1.
response_formatOptional; must be b64_json.
timeout_msOptional integer; 1,000–600,000 ms, default 300,000.

Other image parameters such as size, quality, background, and image edits are rejected because the desktop UI does not expose a reliable contract for them.

{
  "created": 1787670000,
  "data": [{ "b64_json": "iVBORw0KGgo…" }]
}

The bridge waits for the final stable generated image after the stop control disappears, copies the loaded image through a canvas, and transfers the PNG in bounded chunks. It captures the exact active conversation key created by the request, deletes that conversation, then restores Temporary Chat. Cleanup phases continue independently after client cancellation, and a cleanup failure fails the request closed. Image, chat, and model requests share one serialized queue capped at eight pending requests.

Models

GEThttp://127.0.0.1:1456/v1/models

Returns the models currently visible in the authenticated ChatGPT app's real model picker. The bridge discovers this list live, and sending an item's id selects and verifies that desktop model before the prompt is submitted.

{
  "object": "list",
  "data": [{
    "id": "gpt-5.6-sol",
    "object": "model",
    "created": 0,
    "owned_by": "chatgpt-desktop",
    "display_name": "GPT-5.6 Sol",
    "active": true
  }]
}

Health

GEThttp://127.0.0.1:1456/health

Reports whether the bridge is running and whether an authenticated ChatGPT renderer is currently reachable through CDP.

{
  "ok": true,
  "bridge": "chatgpt-desktop",
  "version": 6,
  "service": {
    "managed": true,
    "id": "…"
  },
  "app": {
    "reachable": true,
    "authenticated": true,
    "temporaryChat": true
  }
}

The first completion can launch a separate ChatGPT app instance with CDP enabled even when app.reachable is initially false.

Errors

Failures use an OpenAI-style error envelope:

{
  "error": {
    "message": "Human-readable detail",
    "type": "invalid_request_error",
    "param": null,
    "code": "invalid_messages"
  }
}
StatusCommon codeMeaning
400invalid_jsonMalformed JSON, empty messages, or an unsupported model.
403origin_not_allowedA browser origin outside the bridge allowlist attempted access.
404not_foundThe local route or method does not exist.
413invalid_jsonThe request body exceeded the 1 MiB bridge limit.
502desktop_bridge_failedThe app, renderer, composer, Temporary Chat flow, or response collection failed.

Configuration

Set environment variables on the install command. Their current values are saved in the LaunchAgent.

VariableDefaultPurpose
CHATGPT_BRIDGE_HOST127.0.0.1HTTP bind address. Only loopback addresses are accepted so the unauthenticated bridge cannot be exposed to a network.
CHATGPT_BRIDGE_PORT1456Local OpenAI-compatible HTTP port.
CHATGPT_CDP_PORT9223DevTools port used for the isolated ChatGPT app instance.
CHATGPT_APP/Applications/ChatGPT.appPath to the official ChatGPT macOS application.
CHATGPT_BRIDGE_PORT=1460 ~/.local/bin/chatgpt-api install

Logs are written to ~/Library/Logs/ChatGPTDesktopAPI/bridge.log. The LaunchAgent definition is stored at ~/Library/LaunchAgents/dev.codexauthapi.chatgpt-bridge.plist.

Security model

  • The bridge binds to 127.0.0.1 by default and should not be exposed to a network interface.
  • Browser CORS is restricted to codexauthapi.dev plus the documented local development origins.
  • No ChatGPT cookies, OAuth tokens, passwords, or API keys are extracted from the desktop app.
  • The hosted website does not proxy or store playground prompts and responses.
  • Temporary Chat is enabled before each completion. Image generation uses a fresh regular chat, deletes it, and restores Temporary Chat.
  • Requests are serialized so multiple clients cannot type into the same desktop composer concurrently.

Current limitations

  • macOS and the official ChatGPT desktop app only.
  • Text completions support JSON and streaming SSE; text-to-image supports one base64 PNG. Image edits, files, tools, and audio are not supported.
  • Available models are discovered and selected through the authenticated desktop app's live model picker.
  • Desktop UI changes can break selectors and require a bridge update.
  • Responses complete only after the desktop UI appears stable; authoritative token usage is unavailable.
  • This automation may be subject to the terms governing your ChatGPT account and desktop application.