# ChatGPT Desktop API

A localhost OpenAI-compatible interface to the authenticated ChatGPT section of the official macOS desktop app.

This platform is independent from the hosted Codex OAuth API. The bridge runs on your Mac, binds to `127.0.0.1`, and does not extract ChatGPT credentials or proxy prompts through codexauthapi.dev.

## Requirements

- macOS
- Official ChatGPT app, signed in
- Node.js 22 or newer

## Install

Open <https://chatgpt.codexauthapi.dev/dashboard> for the copyable one-line terminal connection command and live bridge status. The equivalent manual commands are:

```sh
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 `install` command registers a per-user macOS LaunchAgent. The bridge starts immediately, restarts if it exits, starts automatically at login, and remains available after the terminal closes.

Manage it with:

```sh
~/.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
```

Logs are written to `~/Library/Logs/ChatGPTDesktopAPI/bridge.log`.

## Chat completions

`POST http://127.0.0.1:1456/v1/chat/completions`

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

Request fields:

- `model`: optional. Use an `id` returned by `GET /v1/models` to select that real desktop model. The backward-compatible `chatgpt-desktop` alias preserves the app's current selection.
- `messages`: required non-empty array. String content and OpenAI-style text content parts are accepted.
- `stream`: optional. Set to `true` for OpenAI-compatible server-sent event chunks as text appears in the desktop app.
- `stream_options.include_usage`: optional. When true, emits a final usage chunk with zero counts before `[DONE]`.
- `timeout_ms`: optional, defaults to 180000 and is capped at 300000.

Without streaming, the response uses an OpenAI-style `chat.completion` envelope. With streaming, the response is `text/event-stream`, contains `chat.completion.chunk` objects, and ends with `data: [DONE]`. Usage token counts are zero because authoritative token counts are not exposed by the desktop UI.

```sh
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."}]
  }'
```

If a streaming client disconnects, the bridge cancels that desktop generation and releases the serialized request queue.

## Image generations

`POST http://127.0.0.1:1456/v1/images/generations`

```sh
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"
  }'
```

The response is the OpenAI image envelope `{ "created": ..., "data": [{ "b64_json": "..." }] }`. Decode `b64_json` as PNG bytes. `prompt` is required. This bridge supports only `model: "gpt-image-1"`, `n: 1`, and `response_format: "b64_json"`. `timeout_ms` defaults to 300000 and must be an integer between 1000 and 600000. 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.

Image generation uses a fresh regular chat because ChatGPT does not generate images in Temporary Chat. After the image is stable and generation has stopped, the bridge copies the loaded image through a renderer canvas, deletes that exact active conversation, and restores Temporary Chat. Cleanup phases continue independently after a client disconnect, and the request fails closed if exact deletion or restoration cannot be verified. Image, chat, and model requests share one serialized queue capped at eight pending requests.

## Models

`GET http://127.0.0.1:1456/v1/models`

Returns the models currently visible in the authenticated ChatGPT app's real model picker. Each item includes a stable request `id`, the desktop `display_name`, and whether it is currently `active`. Send that `id` in a completion request and the bridge selects and verifies the model before submitting the prompt.

The list is discovered live rather than hard-coded, so availability follows the signed-in ChatGPT account.

## Health

`GET http://127.0.0.1:1456/health`

Reports bridge health and whether the authenticated ChatGPT renderer is currently reachable. The first completion may launch a separate desktop app instance with CDP enabled.

## Configuration

- `CHATGPT_BRIDGE_HOST` defaults to `127.0.0.1`; only loopback addresses are accepted so the unauthenticated bridge cannot be exposed to a network.
- `CHATGPT_BRIDGE_PORT` defaults to `1456`.
- `CHATGPT_CDP_PORT` defaults to `9223`.
- `CHATGPT_APP` defaults to `/Applications/ChatGPT.app`.

Keep the loopback host default. Do not expose the bridge on a public or LAN interface.

## Security and privacy

- No ChatGPT cookies, OAuth tokens, passwords, or API keys are extracted.
- Playground traffic goes from the browser directly to localhost.
- Browser CORS is restricted to the platform and documented local development origins.
- Temporary Chat is enabled before each completion. Image generation uses a fresh regular chat, deletes it, then restores Temporary Chat.
- Requests are serialized.

## Limitations

- Experimental and unofficial; not an OpenAI-supported API.
- macOS and the official ChatGPT desktop app only.
- Text chat completions support non-streaming JSON and streaming SSE; text-to-image supports one base64 PNG per request.
- No image edits, files, tools, audio, or authoritative token usage.
- Available models are discovered and selected through the desktop app's live model picker; desktop UI changes may require bridge updates.

Human documentation: https://chatgpt.codexauthapi.dev/docs

OpenAPI: https://chatgpt.codexauthapi.dev/openapi.json
