SpyBara
Go Premium Account
2026
15 Apr 2026, 18:31
18 May 2026, 22:01 14 May 2026, 21:00 14 May 2026, 07:00 13 May 2026, 00:57 12 May 2026, 01:59 11 May 2026, 18:00 7 May 2026, 20:02 7 May 2026, 17:08 5 May 2026, 23:00 2 May 2026, 06:45 2 May 2026, 00:48 1 May 2026, 18:29 30 Apr 2026, 18:36 29 Apr 2026, 12:40 29 Apr 2026, 00:50 25 Apr 2026, 06:37 25 Apr 2026, 00:42 24 Apr 2026, 18:20 24 Apr 2026, 12:28 23 Apr 2026, 18:31 23 Apr 2026, 12:28 23 Apr 2026, 00:46 22 Apr 2026, 18:29 22 Apr 2026, 00:42 21 Apr 2026, 18:29 21 Apr 2026, 12:30 21 Apr 2026, 06:45 20 Apr 2026, 18:26 20 Apr 2026, 06:53 18 Apr 2026, 18:18 17 Apr 2026, 00:44 16 Apr 2026, 18:31 16 Apr 2026, 00:46 15 Apr 2026, 18:31 15 Apr 2026, 06:44 14 Apr 2026, 18:31 14 Apr 2026, 12:29 13 Apr 2026, 18:37 13 Apr 2026, 00:44 12 Apr 2026, 06:38 10 Apr 2026, 18:23 9 Apr 2026, 00:33 8 Apr 2026, 18:32 8 Apr 2026, 00:40 7 Apr 2026, 00:40 2 Apr 2026, 18:23 31 Mar 2026, 06:35 31 Mar 2026, 00:39 28 Mar 2026, 06:26 28 Mar 2026, 00:36 27 Mar 2026, 18:23 27 Mar 2026, 00:39 26 Mar 2026, 18:27 25 Mar 2026, 18:24 23 Mar 2026, 18:22 20 Mar 2026, 00:35 18 Mar 2026, 12:23 18 Mar 2026, 00:36 17 Mar 2026, 18:24 17 Mar 2026, 00:33 16 Mar 2026, 18:25 16 Mar 2026, 12:23 14 Mar 2026, 00:32 13 Mar 2026, 18:15 13 Mar 2026, 00:34 11 Mar 2026, 00:31 9 Mar 2026, 00:34 8 Mar 2026, 18:10 8 Mar 2026, 00:35 7 Mar 2026, 18:10 7 Mar 2026, 06:14 7 Mar 2026, 00:33 6 Mar 2026, 00:38 5 Mar 2026, 18:41 5 Mar 2026, 06:22 5 Mar 2026, 00:34 4 Mar 2026, 18:18 4 Mar 2026, 06:20 3 Mar 2026, 18:20 3 Mar 2026, 00:35 27 Feb 2026, 18:15 24 Feb 2026, 06:27 24 Feb 2026, 00:33 23 Feb 2026, 18:27 21 Feb 2026, 00:33 20 Feb 2026, 12:16 19 Feb 2026, 20:53 19 Feb 2026, 20:37
18 May 2026, 22:01
18 May 2026, 22:01 14 May 2026, 21:00 14 May 2026, 07:00 13 May 2026, 00:57 12 May 2026, 01:59 11 May 2026, 18:00 7 May 2026, 20:02 7 May 2026, 17:08 5 May 2026, 23:00 2 May 2026, 06:45 2 May 2026, 00:48 1 May 2026, 18:29 30 Apr 2026, 18:36 29 Apr 2026, 12:40 29 Apr 2026, 00:50 25 Apr 2026, 06:37 25 Apr 2026, 00:42 24 Apr 2026, 18:20 24 Apr 2026, 12:28 23 Apr 2026, 18:31 23 Apr 2026, 12:28 23 Apr 2026, 00:46 22 Apr 2026, 18:29 22 Apr 2026, 00:42 21 Apr 2026, 18:29 21 Apr 2026, 12:30 21 Apr 2026, 06:45 20 Apr 2026, 18:26 20 Apr 2026, 06:53 18 Apr 2026, 18:18 17 Apr 2026, 00:44 16 Apr 2026, 18:31 16 Apr 2026, 00:46 15 Apr 2026, 18:31 15 Apr 2026, 06:44 14 Apr 2026, 18:31 14 Apr 2026, 12:29 13 Apr 2026, 18:37 13 Apr 2026, 00:44 12 Apr 2026, 06:38 10 Apr 2026, 18:23 9 Apr 2026, 00:33 8 Apr 2026, 18:32 8 Apr 2026, 00:40 7 Apr 2026, 00:40 2 Apr 2026, 18:23 31 Mar 2026, 06:35 31 Mar 2026, 00:39 28 Mar 2026, 06:26 28 Mar 2026, 00:36 27 Mar 2026, 18:23 27 Mar 2026, 00:39 26 Mar 2026, 18:27 25 Mar 2026, 18:24 23 Mar 2026, 18:22 20 Mar 2026, 00:35 18 Mar 2026, 12:23 18 Mar 2026, 00:36 17 Mar 2026, 18:24 17 Mar 2026, 00:33 16 Mar 2026, 18:25 16 Mar 2026, 12:23 14 Mar 2026, 00:32 13 Mar 2026, 18:15 13 Mar 2026, 00:34 11 Mar 2026, 00:31 9 Mar 2026, 00:34 8 Mar 2026, 18:10 8 Mar 2026, 00:35 7 Mar 2026, 18:10 7 Mar 2026, 06:14 7 Mar 2026, 00:33 6 Mar 2026, 00:38 5 Mar 2026, 18:41 5 Mar 2026, 06:22 5 Mar 2026, 00:34 4 Mar 2026, 18:18 4 Mar 2026, 06:20 3 Mar 2026, 18:20 3 Mar 2026, 00:35 27 Feb 2026, 18:15 24 Feb 2026, 06:27 24 Feb 2026, 00:33 23 Feb 2026, 18:27 21 Feb 2026, 00:33 20 Feb 2026, 12:16 19 Feb 2026, 20:53 19 Feb 2026, 20:37
Fri 1 18:29 Sat 2 00:48 Sat 2 06:45 Tue 5 23:00 Thu 7 17:08 Thu 7 20:02 Mon 11 18:00 Tue 12 01:59 Wed 13 00:57 Thu 14 07:00 Thu 14 21:00 Mon 18 22:01

After 2026-05-02 06:45 UTC, this monitor no longer uses markdownified HTML/MDX. Comparisons across that boundary can therefore show more extensive diffs.

app-server.md +370 −41

Details

3Codex app-server is the interface Codex uses to power rich clients (for example, the Codex VS Code extension). Use it when you want a deep integration inside your own product: authentication, conversation history, approvals, and streamed agent events. The app-server implementation is open source in the Codex GitHub repository ([openai/codex/codex-rs/app-server](https://github.com/openai/codex/tree/main/codex-rs/app-server)). See the [Open Source](https://developers.openai.com/codex/open-source) page for the full list of open-source Codex components.3Codex app-server is the interface Codex uses to power rich clients (for example, the Codex VS Code extension). Use it when you want a deep integration inside your own product: authentication, conversation history, approvals, and streamed agent events. The app-server implementation is open source in the Codex GitHub repository ([openai/codex/codex-rs/app-server](https://github.com/openai/codex/tree/main/codex-rs/app-server)). See the [Open Source](https://developers.openai.com/codex/open-source) page for the full list of open-source Codex components.

4 4 

5If you are automating jobs or running Codex in CI, use the5If you are automating jobs or running Codex in CI, use the

6[Codex SDK](https://developers.openai.com/codex/sdk) instead.6 <a href="/codex/sdk">Codex SDK</a> instead.

7 7 

8## Protocol8## Protocol

9 9 


12Supported transports:12Supported transports:

13 13 

14- `stdio` (`--listen stdio://`, default): newline-delimited JSON (JSONL).14- `stdio` (`--listen stdio://`, default): newline-delimited JSON (JSONL).

15- `websocket` (`--listen ws://IP:PORT`, experimental): one JSON-RPC message per WebSocket text frame.15- `websocket` (`--listen ws://IP:PORT`, experimental and unsupported): one

16 16 JSON-RPC message per WebSocket text frame.

17In WebSocket mode, app-server uses bounded queues. When request ingress is full, the server rejects new requests with JSON-RPC error code `-32001` and message `"Server overloaded; retry later."` Clients should retry with an exponentially increasing delay and jitter.17- Unix socket (`--listen unix://` or `--listen unix://PATH`): WebSocket

18 connections over Codex's default app-server control socket or a custom Unix

19 socket path, using the standard HTTP Upgrade handshake.

20- `off` (`--listen off`): don't expose a local transport.

21 

22When you run with `--listen ws://IP:PORT`, the same listener also serves basic

23HTTP health probes:

24 

25- `GET /readyz` returns `200 OK` once the listener accepts new connections.

26- `GET /healthz` returns `200 OK` when the request doesn't include an `Origin`

27 header.

28- Requests with an `Origin` header are rejected with `403 Forbidden`.

29 

30WebSocket transport is experimental and unsupported. Local listeners such as

31`ws://127.0.0.1:PORT` are appropriate for localhost and SSH port-forwarding

32workflows. Non-loopback WebSocket listeners currently allow unauthenticated

33connections by default during rollout, so configure WebSocket auth before

34exposing one remotely.

35 

36Supported WebSocket auth flags:

37 

38- `--ws-auth capability-token --ws-token-file /absolute/path`

39- `--ws-auth capability-token --ws-token-sha256 HEX`

40- `--ws-auth signed-bearer-token --ws-shared-secret-file /absolute/path`

41 

42For signed bearer tokens, you can also set `--ws-issuer`, `--ws-audience`, and

43`--ws-max-clock-skew-seconds`. Clients present the credential as

44`Authorization: Bearer <token>` during the WebSocket handshake, and app-server

45enforces auth before JSON-RPC `initialize`.

46 

47Prefer `--ws-token-file` over passing raw bearer tokens on the command line. Use

48`--ws-token-sha256` only when the client keeps the raw high-entropy token in a

49separate local secret store; the hash is only a verifier, and clients still need

50the original token.

51 

52In WebSocket mode, app-server uses bounded queues. When request ingress is full,

53the server rejects new requests with JSON-RPC error code `-32001` and message

54`"Server overloaded; retry later."` Clients should retry with an exponentially

55increasing delay and jitter.

18 56 

19## Message schema57## Message schema

20 58 


49 87 

50## Getting started88## Getting started

51 89 

521. Start the server with `codex app-server` (default stdio transport) or `codex app-server --listen ws://127.0.0.1:4500` (experimental WebSocket transport).901. Start the server with `codex app-server` (default stdio transport),

91 `codex app-server --listen ws://127.0.0.1:4500` (TCP WebSocket), or

92 `codex app-server --listen unix://` (default Unix socket).

532. Connect a client over the selected transport, then send `initialize` followed by the `initialized` notification.932. Connect a client over the selected transport, then send `initialize` followed by the `initialized` notification.

543. Start a thread and a turn, then keep reading notifications from the active transport stream.943. Start a thread and a turn, then keep reading notifications from the active transport stream.

55 95 

56Example (Node.js / TypeScript):96Example (Node.js / TypeScript):

57 97 

58```ts98```ts

59import { spawn } from "node:child_process";99 

60import readline from "node:readline";100 

61 101 

62const proc = spawn("codex", ["app-server"], {102const proc = spawn("codex", ["app-server"], {

63 stdio: ["pipe", "pipe", "inherit"],103 stdio: ["pipe", "pipe", "inherit"],


197 237 

198- `thread/start` - create a new thread; emits `thread/started` and automatically subscribes you to turn/item events for that thread.238- `thread/start` - create a new thread; emits `thread/started` and automatically subscribes you to turn/item events for that thread.

199- `thread/resume` - reopen an existing thread by id so later `turn/start` calls append to it.239- `thread/resume` - reopen an existing thread by id so later `turn/start` calls append to it.

200- `thread/fork` - fork a thread into a new thread id by copying stored history; emits `thread/started` for the new thread.240- `thread/fork` - fork a thread into a new thread id by copying stored history; emits `thread/started` for the new thread. Returned threads include `forkedFromId` when available.

201- `thread/read` - read a stored thread by id without resuming it; set `includeTurns` to return full turn history. Returned `thread` objects include runtime `status`.241- `thread/read` - read a stored thread by id without resuming it; set `includeTurns` to return full turn history. Returned `thread` objects include runtime `status`.

202- `thread/list` - page through stored thread logs; supports cursor-based pagination plus `modelProviders`, `sourceKinds`, `archived`, and `cwd` filters. Returned `thread` objects include runtime `status`.242- `thread/list` - page through stored thread logs; supports cursor-based pagination plus `modelProviders`, `sourceKinds`, `archived`, `cwd`, and `searchTerm` filters. Returned `thread` objects include runtime `status`.

243- `thread/turns/list` - page through a stored thread's turn history without resuming it. `itemsView` controls whether turn items are omitted, summarized, or fully loaded.

244- `thread/turns/items/list` - reserved for paged turn-item loading; currently returns unsupported.

203- `thread/loaded/list` - list the thread ids currently loaded in memory.245- `thread/loaded/list` - list the thread ids currently loaded in memory.

204- `thread/name/set` - set or update a thread's user-facing name for a loaded thread or a persisted rollout; emits `thread/name/updated`.246- `thread/name/set` - set or update a thread's user-facing name for a loaded thread or a persisted rollout; emits `thread/name/updated`.

247- `thread/goal/set` - set the goal for a loaded thread (experimental; requires `capabilities.experimentalApi`); emits `thread/goal/updated`.

248- `thread/goal/get` - read the current goal for a loaded thread (experimental; requires `capabilities.experimentalApi`).

249- `thread/goal/clear` - clear the goal for a loaded thread (experimental; requires `capabilities.experimentalApi`); emits `thread/goal/cleared`.

250- `thread/metadata/update` - patch SQLite-backed stored thread metadata; currently supports persisted `gitInfo`.

205- `thread/archive` - move a thread's log file into the archived directory; returns `{}` on success and emits `thread/archived`.251- `thread/archive` - move a thread's log file into the archived directory; returns `{}` on success and emits `thread/archived`.

206- `thread/unsubscribe` - unsubscribe this connection from thread turn/item events. If this was the last subscriber, the server unloads the thread and emits `thread/closed`.252- `thread/unsubscribe` - unsubscribe this connection from thread turn/item events. If this was the last subscriber, the server unloads the thread after a no-subscriber inactivity grace period and emits `thread/closed`.

207- `thread/unarchive` - restore an archived thread rollout back into the active sessions directory; returns the restored `thread` and emits `thread/unarchived`.253- `thread/unarchive` - restore an archived thread rollout back into the active sessions directory; returns the restored `thread` and emits `thread/unarchived`.

208- `thread/status/changed` - notification emitted when a loaded thread's runtime `status` changes.254- `thread/status/changed` - notification emitted when a loaded thread's runtime `status` changes.

209- `thread/compact/start` - trigger conversation history compaction for a thread; returns `{}` immediately while progress streams via `turn/*` and `item/*` notifications.255- `thread/compact/start` - trigger conversation history compaction for a thread; returns `{}` immediately while progress streams via `turn/*` and `item/*` notifications.


211- `thread/backgroundTerminals/clean` - stop all running background terminals for a thread (experimental; requires `capabilities.experimentalApi`).257- `thread/backgroundTerminals/clean` - stop all running background terminals for a thread (experimental; requires `capabilities.experimentalApi`).

212- `thread/rollback` - drop the last N turns from the in-memory context and persist a rollback marker; returns the updated `thread`.258- `thread/rollback` - drop the last N turns from the in-memory context and persist a rollback marker; returns the updated `thread`.

213- `turn/start` - add user input to a thread and begin Codex generation; responds with the initial `turn` and streams events. For `collaborationMode`, `settings.developer_instructions: null` means "use built-in instructions for the selected mode."259- `turn/start` - add user input to a thread and begin Codex generation; responds with the initial `turn` and streams events. For `collaborationMode`, `settings.developer_instructions: null` means "use built-in instructions for the selected mode."

260- `thread/inject_items` - append raw Responses API items to a loaded thread's model-visible history without starting a user turn.

214- `turn/steer` - append user input to the active in-flight turn for a thread; returns the accepted `turnId`.261- `turn/steer` - append user input to the active in-flight turn for a thread; returns the accepted `turnId`.

215- `turn/interrupt` - request cancellation of an in-flight turn; success is `{}` and the turn ends with `status: "interrupted"`.262- `turn/interrupt` - request cancellation of an in-flight turn; success is `{}` and the turn ends with `status: "interrupted"`.

216- `review/start` - kick off the Codex reviewer for a thread; emits `enteredReviewMode` and `exitedReviewMode` items.263- `review/start` - kick off the Codex reviewer for a thread; emits `enteredReviewMode` and `exitedReviewMode` items.


218- `command/exec/write` - write `stdin` bytes to a running `command/exec` session or close `stdin`.265- `command/exec/write` - write `stdin` bytes to a running `command/exec` session or close `stdin`.

219- `command/exec/resize` - resize a running PTY-backed `command/exec` session.266- `command/exec/resize` - resize a running PTY-backed `command/exec` session.

220- `command/exec/terminate` - stop a running `command/exec` session.267- `command/exec/terminate` - stop a running `command/exec` session.

268- `command/exec/outputDelta` (notify) - emitted for base64-encoded stdout/stderr chunks from a streaming `command/exec` session.

269- `process/spawn` - start an explicit process session outside Codex's sandbox (experimental; requires `capabilities.experimentalApi`).

270- `process/writeStdin` - write stdin bytes to a running `process/spawn` session or close stdin (experimental).

271- `process/resizePty` - resize a running PTY-backed process session (experimental).

272- `process/kill` - terminate a running process session (experimental).

273- `process/outputDelta` and `process/exited` (notify) - emitted for streaming process output and process exit status (experimental).

221- `model/list` - list available models (set `includeHidden: true` to include entries with `hidden: true`) with effort options, optional `upgrade`, and `inputModalities`.274- `model/list` - list available models (set `includeHidden: true` to include entries with `hidden: true`) with effort options, optional `upgrade`, and `inputModalities`.

275- `modelProvider/capabilities/read` - read provider capability bounds for model/provider combinations (experimental; requires `capabilities.experimentalApi`).

222- `experimentalFeature/list` - list feature flags with lifecycle stage metadata and cursor pagination.276- `experimentalFeature/list` - list feature flags with lifecycle stage metadata and cursor pagination.

277- `experimentalFeature/enablement/set` - patch in-memory runtime settings for supported feature keys such as `apps` and `plugins`.

223- `collaborationMode/list` - list collaboration mode presets (experimental, no pagination).278- `collaborationMode/list` - list collaboration mode presets (experimental, no pagination).

224- `skills/list` - list skills for one or more `cwd` values (supports `forceReload` and optional `perCwdExtraUserRoots`).279- `skills/list` - list skills for one or more `cwd` values (supports `forceReload` and optional `perCwdExtraUserRoots`).

225- `plugin/list` - list discovered plugin marketplaces and plugin state, including install/auth policy metadata, marketplace errors, featured plugin ids, and the development-only `forceRemoteSync` option.280- `skills/changed` (notify) - emitted when watched local skill files change.

226- `plugin/read` - read one plugin by marketplace path and plugin name, including bundled skills, apps, and MCP server names.281- `marketplace/add` - add a remote plugin marketplace and persist it into the user's marketplace config.

227- `plugin/install` - install a plugin from a marketplace path.282- `marketplace/upgrade` - refresh a configured Git marketplace, or all configured Git marketplaces when you omit the marketplace name.

283- `plugin/list` - list discovered plugin marketplaces and plugin state, including install/auth policy metadata, marketplace load errors, featured plugin ids, and local, Git, or remote plugin source metadata.

284- `plugin/read` - read one plugin by marketplace path or remote marketplace name and plugin name, including bundled skills, apps, and MCP server names when those details are available.

285- `plugin/install` - install a plugin from a marketplace path or remote marketplace name.

228- `plugin/uninstall` - uninstall an installed plugin.286- `plugin/uninstall` - uninstall an installed plugin.

229- `app/list` - list available apps (connectors) with pagination plus accessibility/enabled metadata.287- `app/list` - list available apps (connectors) with pagination plus accessibility/enabled metadata.

230- `skills/config/write` - enable or disable skills by path.288- `skills/config/write` - enable or disable skills by path.


233- `config/mcpServer/reload` - reload MCP server configuration from disk and queue a refresh for loaded threads.291- `config/mcpServer/reload` - reload MCP server configuration from disk and queue a refresh for loaded threads.

234- `mcpServerStatus/list` - list MCP servers, tools, resources, and auth status (cursor + limit pagination). Use `detail: "full"` for full data or `detail: "toolsAndAuthOnly"` to omit resources.292- `mcpServerStatus/list` - list MCP servers, tools, resources, and auth status (cursor + limit pagination). Use `detail: "full"` for full data or `detail: "toolsAndAuthOnly"` to omit resources.

235- `mcpServer/resource/read` - read a single MCP resource through an initialized MCP server.293- `mcpServer/resource/read` - read a single MCP resource through an initialized MCP server.

294- `mcpServer/tool/call` - call a tool on a thread's configured MCP server.

295- `mcpServer/startupStatus/updated` (notify) - emitted when a configured MCP server's startup status changes for a loaded thread.

236- `windowsSandbox/setupStart` - start Windows sandbox setup for `elevated` or `unelevated` mode; returns quickly and later emits `windowsSandbox/setupCompleted`.296- `windowsSandbox/setupStart` - start Windows sandbox setup for `elevated` or `unelevated` mode; returns quickly and later emits `windowsSandbox/setupCompleted`.

237- `feedback/upload` - submit a feedback report (classification + optional reason/logs + conversation id, plus optional `extraLogFiles` attachments).297- `feedback/upload` - submit a feedback report (classification + optional reason/logs + conversation id, plus optional `extraLogFiles` attachments).

238- `config/read` - fetch the effective configuration on disk after resolving configuration layering.298- `config/read` - fetch the effective configuration on disk after resolving configuration layering.

239- `externalAgentConfig/detect` - detect external-agent artifacts that can be migrated with `includeHome` and optional `cwds`; each detected item includes `cwd` (`null` for home).299- `externalAgentConfig/detect` - detect external-agent artifacts that can be migrated with `includeHome` and optional `cwds`; each detected item includes `cwd` (`null` for home).

240- `externalAgentConfig/import` - apply selected external-agent migration items by passing explicit `migrationItems` with `cwd` (`null` for home).300- `externalAgentConfig/import` - apply selected external-agent migration items by passing explicit `migrationItems` with `cwd` (`null` for home). Supported item types include config, skills, `AGENTS.md`, plugins, MCP server config, subagents, hooks, commands, and sessions; plugin imports emit `externalAgentConfig/import/completed`.

241- `config/value/write` - write a single configuration key/value to the user's `config.toml` on disk.301- `config/value/write` - write a single configuration key/value to the user's `config.toml` on disk.

242- `config/batchWrite` - apply configuration edits atomically to the user's `config.toml` on disk.302- `config/batchWrite` - apply configuration edits atomically to the user's `config.toml` on disk.

243- `configRequirements/read` - fetch requirements from `requirements.toml` and/or MDM, including allow-lists, pinned `featureRequirements`, and residency/network requirements (or `null` if you haven't set any up).303- `configRequirements/read` - fetch requirements from `requirements.toml` and/or MDM, including allow-lists, pinned `featureRequirements`, and residency/network requirements (or `null` if you haven't set any up).

244- `fs/readFile`, `fs/writeFile`, `fs/createDirectory`, `fs/getMetadata`, `fs/readDirectory`, `fs/remove`, and `fs/copy` - operate on absolute filesystem paths through the app-server v2 filesystem API.304- `fs/readFile`, `fs/writeFile`, `fs/createDirectory`, `fs/getMetadata`, `fs/readDirectory`, `fs/remove`, `fs/copy`, `fs/watch`, `fs/unwatch`, and `fs/changed` (notify) - operate on absolute filesystem paths through the app-server v2 filesystem API.

305 

306Plugin summaries include a `source` union. Local plugins return

307`{ "type": "local", "path": ... }`, Git-backed marketplace entries return

308`{ "type": "git", "url": ..., "path": ..., "refName": ..., "sha": ... }`,

309and remote catalog entries return `{ "type": "remote" }`. For remote-only

310catalog entries, `PluginMarketplaceEntry.path` can be `null`; pass

311`remoteMarketplaceName` instead of `marketplacePath` when reading or installing

312those plugins.

245 313 

246## Models314## Models

247 315 


310## Threads378## Threads

311 379 

312- `thread/read` reads a stored thread without subscribing to it; set `includeTurns` to include turns.380- `thread/read` reads a stored thread without subscribing to it; set `includeTurns` to include turns.

313- `thread/list` supports cursor pagination plus `modelProviders`, `sourceKinds`, `archived`, and `cwd` filtering.381- `thread/turns/list` pages through a stored thread's turn history without

382 resuming it. Use `itemsView` to choose whether turn items are omitted,

383 summarized, or fully loaded.

384- `thread/list` supports cursor pagination plus `modelProviders`, `sourceKinds`, `archived`, `cwd`, and `searchTerm` filtering.

314- `thread/loaded/list` returns the thread IDs currently in memory.385- `thread/loaded/list` returns the thread IDs currently in memory.

315- `thread/archive` moves the thread's persisted JSONL log into the archived directory.386- `thread/archive` moves the thread's persisted JSONL log into the archived directory.

316- `thread/unsubscribe` unsubscribes the current connection from a loaded thread and can trigger `thread/closed`.387- `thread/metadata/update` patches stored thread metadata, currently including persisted `gitInfo`.

388- `thread/unsubscribe` unsubscribes the current connection from a loaded thread and can trigger `thread/closed` after an inactivity grace period.

317- `thread/unarchive` restores an archived thread rollout back into the active sessions directory.389- `thread/unarchive` restores an archived thread rollout back into the active sessions directory.

318- `thread/compact/start` triggers compaction and returns `{}` immediately.390- `thread/compact/start` triggers compaction and returns `{}` immediately.

319- `thread/rollback` drops the last N turns from the in-memory context and records a rollback marker in the thread's persisted JSONL log.391- `thread/rollback` drops the last N turns from the in-memory context and records a rollback marker in the thread's persisted JSONL log.

392- `thread/inject_items` appends raw Responses API items to a loaded thread's model-visible history without starting a user turn.

320 393 

321### Start or resume a thread394### Start or resume a thread

322 395 


334{ "id": 10, "result": {407{ "id": 10, "result": {

335 "thread": {408 "thread": {

336 "id": "thr_123",409 "id": "thr_123",

410 "sessionId": "thr_123",

337 "preview": "",411 "preview": "",

338 "ephemeral": false,412 "ephemeral": false,

339 "modelProvider": "openai",413 "modelProvider": "openai",


345 419 

346`serviceName` is optional. Set it when you want app-server to tag thread-level metrics with your integration's service name.420`serviceName` is optional. Set it when you want app-server to tag thread-level metrics with your integration's service name.

347 421 

422`thread.sessionId` identifies the current live session tree root. Root threads

423use their own thread id as the session id; forked threads keep the session id

424of the root they came from. Clients should read the session id from

425`thread.sessionId` instead of deriving it from the thread id.

426 

348To continue a stored session, call `thread/resume` with the `thread.id` you recorded earlier. The response shape matches `thread/start`. You can also pass the same configuration overrides supported by `thread/start`, such as `personality`:427To continue a stored session, call `thread/resume` with the `thread.id` you recorded earlier. The response shape matches `thread/start`. You can also pass the same configuration overrides supported by `thread/start`, such as `personality`:

349 428 

350```json429```json


363 442 

364If you resume with a different model than the one recorded in the rollout, Codex emits a warning and applies a one-time model-switch instruction on the next turn.443If you resume with a different model than the one recorded in the rollout, Codex emits a warning and applies a one-time model-switch instruction on the next turn.

365 444 

445### Manage a thread goal

446 

447`thread/goal/set`, `thread/goal/get`, and `thread/goal/clear` are experimental

448and require `capabilities.experimentalApi = true` plus the `goals` feature. Use

449them for the same persisted goal state surfaced by `/goal` in the TUI.

450 

451```json

452{ "method": "thread/goal/set", "id": 13, "params": {

453 "threadId": "thr_123",

454 "objective": "Finish the migration and keep tests green",

455 "status": "active",

456 "tokenBudget": 40000

457} }

458{ "id": 13, "result": { "goal": {

459 "threadId": "thr_123",

460 "objective": "Finish the migration and keep tests green",

461 "status": "active",

462 "tokenBudget": 40000,

463 "tokensUsed": 0,

464 "timeUsedSeconds": 0

465} } }

466{ "method": "thread/goal/updated", "params": {

467 "threadId": "thr_123",

468 "goal": {

469 "threadId": "thr_123",

470 "objective": "Finish the migration and keep tests green",

471 "status": "active",

472 "tokenBudget": 40000,

473 "tokensUsed": 0,

474 "timeUsedSeconds": 0

475 }

476} }

477```

478 

479Goal objectives must be non-empty and at most 4,000 characters. Supplying a new

480objective replaces the goal and resets usage accounting. Supplying the current

481non-terminal objective, or omitting `objective`, updates status or token budget

482while preserving usage history.

483 

366To branch from a stored session, call `thread/fork` with the `thread.id`. This creates a new thread id and emits a `thread/started` notification for it:484To branch from a stored session, call `thread/fork` with the `thread.id`. This creates a new thread id and emits a `thread/started` notification for it:

367 485 

368```json486```json

369{ "method": "thread/fork", "id": 12, "params": { "threadId": "thr_123" } }487{ "method": "thread/fork", "id": 12, "params": { "threadId": "thr_123" } }

370{ "id": 12, "result": { "thread": { "id": "thr_456" } } }488{ "id": 12, "result": { "thread": { "id": "thr_456", "sessionId": "thr_123", "forkedFromId": "thr_123" } } }

371{ "method": "thread/started", "params": { "thread": { "id": "thr_456" } } }489{ "method": "thread/started", "params": { "thread": { "id": "thr_456" } } }

372```490```

373 491 


387 505 

388Unlike `thread/resume`, `thread/read` doesn't load the thread into memory or emit `thread/started`.506Unlike `thread/resume`, `thread/read` doesn't load the thread into memory or emit `thread/started`.

389 507 

508### List thread turns

509 

510Use `thread/turns/list` to page a stored thread's turn history without resuming it. Results default to newest-first so clients can fetch older turns with `nextCursor`. The response also includes `backwardsCursor`; pass it as `cursor` with `sortDirection: "asc"` to fetch turns newer than the first item from the earlier page.

511 

512`itemsView` controls how much turn-item data the response includes:

513 

514- `notLoaded` omits items.

515- `summary` returns summarized item data and is the default when omitted.

516- `full` returns full item data.

517 

518```json

519{ "method": "thread/turns/list", "id": 20, "params": {

520 "threadId": "thr_123",

521 "limit": 50,

522 "sortDirection": "desc",

523 "itemsView": "summary"

524} }

525{ "id": 20, "result": {

526 "data": [],

527 "nextCursor": "older-turns-cursor-or-null",

528 "backwardsCursor": "newer-turns-cursor-or-null"

529} }

530```

531 

532`thread/turns/items/list` is reserved for paged turn-item loading, but the

533current server returns an unsupported-method error.

534 

390### List threads (with pagination & filters)535### List threads (with pagination & filters)

391 536 

392`thread/list` lets you render a history UI. Results default to newest-first by `createdAt`. Filters apply before pagination. Pass any combination of:537`thread/list` lets you render a history UI. Results default to newest-first by `createdAt`. Filters apply before pagination. Pass any combination of:


398- `sourceKinds` - restrict results to specific thread sources. When omitted or `[]`, the server defaults to interactive sources only: `cli` and `vscode`.543- `sourceKinds` - restrict results to specific thread sources. When omitted or `[]`, the server defaults to interactive sources only: `cli` and `vscode`.

399- `archived` - when `true`, list archived threads only. When `false` or omitted, list non-archived threads (default).544- `archived` - when `true`, list archived threads only. When `false` or omitted, list non-archived threads (default).

400- `cwd` - restrict results to threads whose session current working directory exactly matches this path.545- `cwd` - restrict results to threads whose session current working directory exactly matches this path.

546- `searchTerm` - search stored thread summaries and metadata before pagination.

401 547 

402`sourceKinds` accepts the following values:548`sourceKinds` accepts the following values:

403 549 


431 577 

432When `nextCursor` is `null`, you have reached the final page.578When `nextCursor` is `null`, you have reached the final page.

433 579 

580### Update stored thread metadata

581 

582Use `thread/metadata/update` to patch stored thread metadata without resuming the thread. Today this supports persisted `gitInfo`; omitted fields are left unchanged, and explicit `null` clears a stored value.

583 

584```json

585{ "method": "thread/metadata/update", "id": 21, "params": {

586 "threadId": "thr_123",

587 "gitInfo": { "branch": "feature/sidebar-pr" }

588} }

589{ "id": 21, "result": {

590 "thread": {

591 "id": "thr_123",

592 "gitInfo": { "sha": null, "branch": "feature/sidebar-pr", "originUrl": null }

593 }

594} }

595```

596 

434### Track thread status changes597### Track thread status changes

435 598 

436`thread/status/changed` is emitted whenever a loaded thread's runtime status changes. The payload includes `threadId` and the new `status`.599`thread/status/changed` is emitted whenever a loaded thread's runtime status changes. The payload includes `threadId` and the new `status`.


462- `notSubscribed` when the connection wasn't subscribed to that thread.625- `notSubscribed` when the connection wasn't subscribed to that thread.

463- `notLoaded` when the thread isn't loaded.626- `notLoaded` when the thread isn't loaded.

464 627 

465If this was the last subscriber, the server unloads the thread and emits a `thread/status/changed` transition to `notLoaded` plus `thread/closed`.628If this was the last subscriber, the server keeps the thread loaded until it has no subscribers and no thread activity for 30 minutes. When the grace period expires, app-server unloads the thread and emits a `thread/status/changed` transition to `notLoaded` plus `thread/closed`.

466 629 

467```json630```json

468{ "method": "thread/unsubscribe", "id": 22, "params": { "threadId": "thr_123" } }631{ "method": "thread/unsubscribe", "id": 22, "params": { "threadId": "thr_123" } }

469{ "id": 22, "result": { "status": "unsubscribed" } }632{ "id": 22, "result": { "status": "unsubscribed" } }

633```

634 

635If the thread later expires:

636 

637```json

470{ "method": "thread/status/changed", "params": {638{ "method": "thread/status/changed", "params": {

471 "threadId": "thr_123",639 "threadId": "thr_123",

472 "status": { "type": "notLoaded" }640 "status": { "type": "notLoaded" }


615{ "id": 30, "result": { "turn": { "id": "turn_456", "status": "inProgress", "items": [], "error": null } } }783{ "id": 30, "result": { "turn": { "id": "turn_456", "status": "inProgress", "items": [], "error": null } } }

616```784```

617 785 

786### Inject items into a thread

787 

788Use `thread/inject_items` to append prebuilt Responses API items to a loaded thread's prompt history without starting a user turn. These items are persisted to the rollout and included in subsequent model requests.

789 

790```json

791{ "method": "thread/inject_items", "id": 31, "params": {

792 "threadId": "thr_123",

793 "items": [

794 {

795 "type": "message",

796 "role": "assistant",

797 "content": [{ "type": "output_text", "text": "Previously computed context." }]

798 }

799 ]

800} }

801{ "id": 31, "result": {} }

802```

803 

618### Steer an active turn804### Steer an active turn

619 805 

620Use `turn/steer` to append more user input to the active in-flight turn.806Use `turn/steer` to append more user input to the active in-flight turn.


723 909 

724Use this notification to render the reviewer output in your client.910Use this notification to render the reviewer output in your client.

725 911 

912## Process execution

913 

914`process/*` is an experimental, explicit process-control API. It requires

915`capabilities.experimentalApi = true` and runs outside Codex's sandbox. Use it

916only when your client intentionally exposes local process control without a

917sandbox.

918 

919Start a process with `process/spawn` and provide a `processHandle`, then use

920that handle for stdin, resize, and kill requests. Output streams through

921`process/outputDelta` notifications and completion streams through

922`process/exited`.

923 

924```json

925{ "method": "process/spawn", "id": 48, "params": {

926 "command": ["python3", "-m", "pytest", "-q"],

927 "processHandle": "pytest-1",

928 "cwd": "/Users/me/project",

929 "tty": true

930} }

931{ "id": 48, "result": {} }

932{ "method": "process/outputDelta", "params": {

933 "processHandle": "pytest-1",

934 "stream": "stdout",

935 "deltaBase64": "Li4u"

936} }

937{ "method": "process/exited", "params": {

938 "processHandle": "pytest-1",

939 "exitCode": 0

940} }

941```

942 

943Use `process/writeStdin` with `deltaBase64`, `closeStdin`, or both to send

944input. Use `process/resizePty` for PTY resize events and `process/kill` to

945terminate a running process.

946 

726## Command execution947## Command execution

727 948 

728`command/exec` runs a single command (`argv` array) under the server sandbox without creating a thread.949`command/exec` runs a single command (`argv` array) under the server sandbox without creating a thread.


796- `elevated` - run the elevated Windows sandbox setup path.1017- `elevated` - run the elevated Windows sandbox setup path.

797- `unelevated` - run the legacy setup/preflight path.1018- `unelevated` - run the legacy setup/preflight path.

798 1019 

1020## Filesystem

1021 

1022The v2 filesystem APIs operate on absolute paths. Use `fs/watch` when a client needs to invalidate UI state after a file or directory changes.

1023 

1024```json

1025{ "method": "fs/watch", "id": 54, "params": {

1026 "watchId": "0195ec6b-1d6f-7c2e-8c7a-56f2c4a8b9d1",

1027 "path": "/Users/me/project/.git/HEAD"

1028} }

1029{ "id": 54, "result": { "path": "/Users/me/project/.git/HEAD" } }

1030{ "method": "fs/changed", "params": {

1031 "watchId": "0195ec6b-1d6f-7c2e-8c7a-56f2c4a8b9d1",

1032 "changedPaths": ["/Users/me/project/.git/HEAD"]

1033} }

1034{ "method": "fs/unwatch", "id": 55, "params": {

1035 "watchId": "0195ec6b-1d6f-7c2e-8c7a-56f2c4a8b9d1"

1036} }

1037{ "id": 55, "result": {} }

1038```

1039 

1040Watching a file emits `fs/changed` for that file path, including updates delivered by replace or rename operations.

1041 

799## Events1042## Events

800 1043 

801Event notifications are the server-initiated stream for thread lifecycles, turn lifecycles, and the items within them. After you start or resume a thread, keep reading the active transport stream for `thread/started`, `thread/archived`, `thread/unarchived`, `thread/closed`, `thread/status/changed`, `turn/*`, `item/*`, and `serverRequest/resolved` notifications.1044Event notifications are the server-initiated stream for thread lifecycles, turn lifecycles, and the items within them. After you start or resume a thread, keep reading the active transport stream for `thread/started`, `thread/archived`, `thread/unarchived`, `thread/closed`, `thread/status/changed`, `turn/*`, `item/*`, and `serverRequest/resolved` notifications.


866- `item/reasoning/summaryPartAdded` - marks a boundary between reasoning summary sections.1109- `item/reasoning/summaryPartAdded` - marks a boundary between reasoning summary sections.

867- `item/reasoning/textDelta` - streams raw reasoning text (when supported by the model).1110- `item/reasoning/textDelta` - streams raw reasoning text (when supported by the model).

868- `item/commandExecution/outputDelta` - streams stdout/stderr for a command; append deltas in order.1111- `item/commandExecution/outputDelta` - streams stdout/stderr for a command; append deltas in order.

869- `item/fileChange/outputDelta` - contains the tool call response of the underlying `apply_patch` tool call.1112- `item/fileChange/outputDelta` - deprecated compatibility notification for legacy `apply_patch` text output. Current app-server versions no longer emit it; use `fileChange` items and `turn/diff/updated` instead.

870 1113 

871## Errors1114## Errors

872 1115 


925 1169 

926`dynamicTools` on `thread/start` and the corresponding `item/tool/call` request or response flow are experimental APIs.1170`dynamicTools` on `thread/start` and the corresponding `item/tool/call` request or response flow are experimental APIs.

927 1171 

1172Dynamic tool names and namespace names must follow Responses API naming

1173constraints. Avoid reserved namespace names used by built-in Codex tools.

1174 

928When a dynamic tool is invoked during a turn, app-server emits:1175When a dynamic tool is invoked during a turn, app-server emits:

929 1176 

9301. `item/started` with `item.type = "dynamicToolCall"`, `status = "inProgress"`, plus `tool` and `arguments`.11771. `item/started` with `item.type = "dynamicToolCall"`, `status = "inProgress"`, plus `tool` and `arguments`.


1016} }1263} }

1017```1264```

1018 1265 

1266The server also emits `skills/changed` notifications when watched local skill files change. Treat this as an invalidation signal and rerun `skills/list` with your current params when needed.

1267 

1019To enable or disable a skill by path:1268To enable or disable a skill by path:

1020 1269 

1021```json1270```json


1222{ "id": 64, "result": {} }1471{ "id": 64, "result": {} }

1223```1472```

1224 1473 

1225Supported `itemType` values are `AGENTS_MD`, `CONFIG`, `SKILLS`, and `MCP_SERVER_CONFIG`. Detection returns only items that still have work to do. For example, AGENTS migration is skipped when `AGENTS.md` already exists and is non-empty, and skill imports don’t overwrite existing skill directories.1474When a request includes plugin imports, the server emits `externalAgentConfig/import/completed` after the import finishes. This notification may arrive immediately after the response or after background remote imports complete.

1475 

1476Supported `itemType` values are `AGENTS_MD`, `CONFIG`, `SKILLS`, `PLUGINS`,

1477and `MCP_SERVER_CONFIG`. For `PLUGINS` items, `details.plugins` lists each

1478`marketplaceName` and the `pluginNames` Codex can try to migrate. Detection

1479returns only items that still have work to do. For example, Codex skips AGENTS

1480migration when `AGENTS.md` already exists and is non-empty, and skill imports

1481don't overwrite existing skill directories.

1482 

1483When detecting plugins from `.claude/settings.json`, Codex reads configured

1484marketplace sources from `extraKnownMarketplaces`. If `enabledPlugins` contains

1485plugins from `claude-plugins-official` but the marketplace source is missing,

1486Codex infers `anthropics/claude-plugins-official` as the source.

1226 1487 

1227## Auth endpoints1488## Auth endpoints

1228 1489 

1229The JSON-RPC auth/account surface exposes request/response methods plus server-initiated notifications (no `id`). Use these to determine auth state, start or cancel logins, logout, and inspect ChatGPT rate limits.1490The JSON-RPC auth/account surface exposes request/response methods plus server-initiated notifications (no `id`). Use these to determine auth state, start or cancel logins, logout, inspect ChatGPT rate limits, and notify workspace owners about depleted credits or usage limits.

1230 1491 

1231### Authentication modes1492### Authentication modes

1232 1493 

1233Codex supports three authentication modes. `account/updated.authMode` shows the active mode, and `account/read` also reports it.1494Codex supports these authentication modes. `account/updated.authMode` shows the active mode and includes the current ChatGPT `planType` when available. `account/read` also reports account and plan details.

1234 1495 

1235- **API key (`apikey`)** - the caller supplies an OpenAI API key and Codex stores it for API requests.1496- **API key (`apikey`)** - the caller supplies an OpenAI API key with `type: "apiKey"`, and Codex stores it for API requests.

1236- **ChatGPT managed (`chatgpt`)** - Codex owns the ChatGPT OAuth flow, persists tokens, and refreshes them automatically.1497- **ChatGPT managed (`chatgpt`)** - Codex owns the ChatGPT OAuth flow, persists tokens, and refreshes them automatically. Start with `type: "chatgpt"` for the browser flow or `type: "chatgptDeviceCode"` for the device-code flow.

1237- **ChatGPT external tokens (`chatgptAuthTokens`)** - a host app supplies `idToken` and `accessToken` directly. Codex stores these tokens in memory, and the host app must refresh them when asked.1498- **ChatGPT external tokens (`chatgptAuthTokens`)** - experimental and intended for host apps that already own the user's ChatGPT auth lifecycle. The host app supplies an `accessToken`, `chatgptAccountId`, and optional `chatgptPlanType` directly, and must refresh the token when asked.

1238 1499 

1239### API overview1500### API overview

1240 1501 

1241- `account/read` - fetch current account info; optionally refresh tokens.1502- `account/read` - fetch current account info; optionally refresh tokens.

1242- `account/login/start` - begin login (`apiKey`, `chatgpt`, or `chatgptAuthTokens`).1503- `account/login/start` - begin login (`apiKey`, `chatgpt`, `chatgptDeviceCode`, or experimental `chatgptAuthTokens`).

1243- `account/login/completed` (notify) - emitted when a login attempt finishes (success or error).1504- `account/login/completed` (notify) - emitted when a login attempt finishes (success or error).

1244- `account/login/cancel` - cancel a pending ChatGPT login by `loginId`.1505- `account/login/cancel` - cancel a pending managed ChatGPT login by `loginId`.

1245- `account/logout` - sign out; triggers `account/updated`.1506- `account/logout` - sign out; triggers `account/updated`.

1246- `account/updated` (notify) - emitted whenever auth mode changes (`authMode`: `apikey`, `chatgpt`, `chatgptAuthTokens`, or `null`).1507- `account/updated` (notify) - emitted whenever auth mode changes (`authMode`: `apikey`, `chatgpt`, `chatgptAuthTokens`, or `null`) and includes `planType` when available.

1247- `account/chatgptAuthTokens/refresh` (server request) - request fresh externally managed ChatGPT tokens after an authorization error.1508- `account/chatgptAuthTokens/refresh` (server request) - request fresh externally managed ChatGPT tokens after an authorization error.

1248- `account/rateLimits/read` - fetch ChatGPT rate limits.1509- `account/rateLimits/read` - fetch ChatGPT rate limits.

1249- `account/rateLimits/updated` (notify) - emitted whenever a user's ChatGPT rate limits change.1510- `account/rateLimits/updated` (notify) - emitted whenever a user's ChatGPT rate limits change.

1511- `account/sendAddCreditsNudgeEmail` - ask ChatGPT to email a workspace owner about depleted credits or a reached usage limit.

1250- `mcpServer/oauthLogin/completed` (notify) - emitted after a `mcpServer/oauth/login` flow finishes; payload includes `{ name, success, error? }`.1512- `mcpServer/oauthLogin/completed` (notify) - emitted after a `mcpServer/oauth/login` flow finishes; payload includes `{ name, success, error? }`.

1513- `mcpServer/startupStatus/updated` (notify) - emitted when a configured MCP server's startup status changes for a loaded thread; payload includes `{ name, status, error }`.

1251 1514 

1252### 1) Check auth state1515### 1) Check auth state

1253 1516 


1319 ```1584 ```

1320 1585 

1321 ```json1586 ```json

1322 { "method": "account/updated", "params": { "authMode": "apikey" } }1587 {

1588 "method": "account/updated",

1589 "params": { "authMode": "apikey", "planType": null }

1590 }

1323 ```1591 ```

1324 1592 

1325### 3) Log in with ChatGPT (browser flow)1593### 3) Log in with ChatGPT (browser flow)


1351 ```1620 ```

1352 1621 

1353 ```json1622 ```json

1354 { "method": "account/updated", "params": { "authMode": "chatgpt" } }1623 {

1624 "method": "account/updated",

1625 "params": { "authMode": "chatgpt", "planType": "plus" }

1626 }

1627 ```

1628 

1629### 3b) Log in with ChatGPT (device-code flow)

1630 

1631Use this flow when your client owns the sign-in ceremony or when a browser callback is brittle.

1632 

16331. Start:

1634 

1635 ```json

1636 {

1637 "method": "account/login/start",

1638 "id": 4,

1639 "params": { "type": "chatgptDeviceCode" }

1640 }

1641 ```

1642 

1643 ```json

1644 {

1645 "id": 4,

1646 "result": {

1647 "type": "chatgptDeviceCode",

1648 "loginId": "<uuid>",

1649 "verificationUrl": "https://auth.openai.com/codex/device",

1650 "userCode": "ABCD-1234"

1651 }

1652 }

1653 ```

1654 

16552. Show `verificationUrl` and `userCode` to the user; the frontend owns the UX.

16563. Wait for notifications:

1657 

1658 ```json

1659 {

1660 "method": "account/login/completed",

1661 "params": { "loginId": "<uuid>", "success": true, "error": null }

1662 }

1663 ```

1664 

1665 ```json

1666 {

1667 "method": "account/updated",

1668 "params": { "authMode": "chatgpt", "planType": "plus" }

1669 }

1355 ```1670 ```

1356 1671 

1357### 3b) Log in with externally managed ChatGPT tokens (`chatgptAuthTokens`)1672### 3c) Log in with externally managed ChatGPT tokens (`chatgptAuthTokens`)

1358 1673 

1359Use this mode when a host application owns the users ChatGPT auth lifecycle and supplies tokens directly.1674Use this experimental mode only when a host application owns the user's ChatGPT auth lifecycle and supplies tokens directly. Clients must set `capabilities.experimentalApi = true` during `initialize` before using this login type.

1360 1675 

13611. Send:16761. Send:

1362 1677 


1366 "id": 7,1681 "id": 7,

1367 "params": {1682 "params": {

1368 "type": "chatgptAuthTokens",1683 "type": "chatgptAuthTokens",

1369 "idToken": "<jwt>",1684 "accessToken": "<jwt>",

1370 "accessToken": "<jwt>"1685 "chatgptAccountId": "org-123",

1686 "chatgptPlanType": "business"

1371 }1687 }

1372 }1688 }

1373 ```1689 ```


1388 ```json1706 ```json

1389 {1707 {

1390 "method": "account/updated",1708 "method": "account/updated",

1391 "params": { "authMode": "chatgptAuthTokens" }1709 "params": { "authMode": "chatgptAuthTokens", "planType": "business" }

1392 }1710 }

1393 ```1711 ```

1394 1712 


1400 "id": 8,1718 "id": 8,

1401 "params": { "reason": "unauthorized", "previousAccountId": "org-123" }1719 "params": { "reason": "unauthorized", "previousAccountId": "org-123" }

1402}1720}

1403{ "id": 8, "result": { "idToken": "<jwt>", "accessToken": "<jwt>" } }1721{ "id": 8, "result": { "accessToken": "<jwt>", "chatgptAccountId": "org-123", "chatgptPlanType": "business" } }

1404```1722```

1405 1723 

1406The server retries the original request after a successful refresh response. Requests time out after about 10 seconds.1724The server retries the original request after a successful refresh response. Requests time out after about 10 seconds.


1417```json1735```json

1418{ "method": "account/logout", "id": 5 }1736{ "method": "account/logout", "id": 5 }

1419{ "id": 5, "result": {} }1737{ "id": 5, "result": {} }

1420{ "method": "account/updated", "params": { "authMode": null } }1738{ "method": "account/updated", "params": { "authMode": null, "planType": null } }

1421```1739```

1422 1740 

1423### 6) Rate limits (ChatGPT)1741### 6) Rate limits (ChatGPT)


1429 "limitId": "codex",1747 "limitId": "codex",

1430 "limitName": null,1748 "limitName": null,

1431 "primary": { "usedPercent": 25, "windowDurationMins": 15, "resetsAt": 1730947200 },1749 "primary": { "usedPercent": 25, "windowDurationMins": 15, "resetsAt": 1730947200 },

1432 "secondary": null1750 "secondary": null,

1751 "rateLimitReachedType": null

1433 },1752 },

1434 "rateLimitsByLimitId": {1753 "rateLimitsByLimitId": {

1435 "codex": {1754 "codex": {

1436 "limitId": "codex",1755 "limitId": "codex",

1437 "limitName": null,1756 "limitName": null,

1438 "primary": { "usedPercent": 25, "windowDurationMins": 15, "resetsAt": 1730947200 },1757 "primary": { "usedPercent": 25, "windowDurationMins": 15, "resetsAt": 1730947200 },

1439 "secondary": null1758 "secondary": null,

1759 "rateLimitReachedType": null

1440 },1760 },

1441 "codex_other": {1761 "codex_other": {

1442 "limitId": "codex_other",1762 "limitId": "codex_other",

1443 "limitName": "codex_other",1763 "limitName": "codex_other",

1444 "primary": { "usedPercent": 42, "windowDurationMins": 60, "resetsAt": 1730950800 },1764 "primary": { "usedPercent": 42, "windowDurationMins": 60, "resetsAt": 1730950800 },

1445 "secondary": null1765 "secondary": null,

1766 "rateLimitReachedType": null

1446 }1767 }

1447 }1768 }

1448} }1769} }


1463- `usedPercent` is current usage within the quota window.1784- `usedPercent` is current usage within the quota window.

1464- `windowDurationMins` is the quota window length.1785- `windowDurationMins` is the quota window length.

1465- `resetsAt` is a Unix timestamp (seconds) for the next reset.1786- `resetsAt` is a Unix timestamp (seconds) for the next reset.

1787- `planType` is included when the server returns the ChatGPT plan associated with a bucket.

1788- `credits` is included when the server returns remaining workspace credit details.

1789- `rateLimitReachedType` identifies the server-classified limit state when one has been reached.

1790 

1791### 7) Notify a workspace owner about a limit

1792 

1793Use `account/sendAddCreditsNudgeEmail` to ask ChatGPT to email a workspace owner when credits are depleted or a usage limit has been reached.

1794 

1795```json

1796{ "method": "account/sendAddCreditsNudgeEmail", "id": 7, "params": { "creditType": "credits" } }

1797{ "id": 7, "result": { "status": "sent" } }

1798```

1799 

1800Use `creditType: "credits"` when workspace credits are depleted, or `creditType: "usage_limit"` when the workspace usage limit has been reached. If the owner was already notified recently, the response status is `cooldown_active`.