cc-libs/docs/opencode_api.md

6.4 KiB

opencode serve — HTTP API reference

Minimal reference for the endpoints used by libai.lua. Full spec served at GET /doc when the server is running.

Running the server

Local/dev uses opencode's default port 4096:

opencode serve \
  --hostname 127.0.0.1 \
  --port 4096

Public production uses port 4242; see public-ports.md:

opencode serve \
  --hostname 0.0.0.0 \
  --port 4242

With Basic Auth (recommended):

OPENCODE_SERVER_PASSWORD=secret opencode serve \
  --hostname 127.0.0.1 \
  --port 4096

Default username is opencode. Override with OPENCODE_SERVER_USERNAME.

Authentication

All requests must include Authorization: Basic <base64(username:password)> when the server was started with a password. No auth header is needed if no password is set.

Authorization: Basic base64("opencode:secret")

Endpoints

GET /global/health

Health check. Returns 200 when the server is up.


GET /session

List all sessions for the current project.

Optional query parameters used by ai:

  • directory — scope results to an opencode project directory.

Response 200:

[
  { "id": "ses_abc123", "title": "my session", "time": { "created": 1234567890, "updated": 1234567890 } }
]

POST /session

Create a new session.

Request body:

{ "title": "optional title", "parentID": "optional" }

Response 200:

{ "id": "ses_abc123", "title": "my session" }

POST /session/:id/message

Send a message and wait for the AI reply (blocking). Returns when the assistant has finished responding.

Request body:

{
  "parts": [
    { "type": "text", "text": "your prompt here" }
  ],
  "agent": "atm10-expert",
  "model": { "providerID": "anthropic", "modelID": "claude-opus-4-7" }
}

agent and model are optional — omit them to use the server's configured defaults.

Response 200:

{
  "info": { "id": "msg_xyz", "sessionID": "ses_abc123", "role": "assistant" },
  "parts": [
    { "type": "text", "text": "the reply" }
  ]
}

Parts can include non-text types (tool-call, step-start, etc.) — collect all type == "text" entries to reconstruct the reply.

Errors:

  • 401 — wrong credentials
  • 404 — session not found (may have been deleted or server restarted)
  • 504 — AI took too long

GET /session/:id/message/:messageID

Get a message by ID. Opencode validates caller-provided message IDs; use IDs starting with msg.

Response 200:

{
  "info": { "id": "msg_xyz", "sessionID": "ses_abc123", "role": "assistant", "time": { "completed": 1234567890 } },
  "parts": [
    { "type": "text", "text": "the reply" }
  ]
}

DELETE /session/:id

Delete a session.


POST /session/:id/abort

Abort a running generation.


POST /session/:id/prompt_async

Fire-and-forget variant. Returns 204 immediately and starts generation in the background. Include messageID in the request body so the submitted user message can be matched to the later assistant response. Opencode validates caller-provided message IDs; use IDs starting with msg.

Request body:

{
  "messageID": "msg_xyz",
  "parts": [
    { "type": "text", "text": "your prompt here" }
  ],
  "agent": "atm10-expert",
  "model": { "providerID": "anthropic", "modelID": "claude-opus-4-7" }
}

agent and model are optional. Omit model to use the server/session default model, or include it to force a specific provider/model for this prompt.

ai uses this endpoint by default to avoid 504 failures from the blocking /message endpoint when the LLM takes longer than one HTTP request timeout. The submitted messageID identifies the user message; ai polls GET /session/:id/message and reads the completed assistant message after it. If opencc.agent or --agent <name> is set, ai includes it as agent in the request body. If generation fails in the background, opencode records the failure on the assistant message or session event stream; ai surfaces assistant message errors while polling.


GET /global/event (SSE)

Server-Sent Events stream. Delivers all server bus events in real time. Useful for async workflows or watching a session from outside the TUI.


opencode attach

opencode attach opens the TUI and connects it to an already-running opencode serve instance. Both the TUI and any HTTP clients operate on the same session state.

opencode attach http://127.0.0.1:4096
opencode attach http://127.0.0.1:4096 --session ses_abc123

To send messages to the session currently open in the TUI, set opencc.session_id in CC to the session ID shown in the TUI, then run ai:

set opencc.session_id ses_abc123

TUI control

When a TUI is attached, these endpoints drive that TUI programmatically. They operate on the attached TUI prompt/dialog state, not on a specific /session/:id.

Method Path Effect Body
POST /tui/append-prompt Append text to the prompt { "text": "..." }
POST /tui/submit-prompt Submit the current prompt none
POST /tui/clear-prompt Clear the prompt none
POST /tui/open-help Open the help dialog none
POST /tui/open-sessions Open the session selector none
POST /tui/open-themes Open the theme selector none
POST /tui/open-models Open the model selector none
POST /tui/execute-command Execute a TUI command { "command": "prompt.submit" }
POST /tui/show-toast Show a notification { "message": "...", "variant": "info" }
GET /tui/control/next Wait for the next TUI control request none
POST /tui/control/response Respond to a TUI control request response body

/tui/show-toast also accepts optional title and duration fields. variant is one of info, success, warning, or error.

Example: prefill and submit the attached TUI prompt:

curl -X POST http://127.0.0.1:4096/tui/append-prompt \
  -H 'Content-Type: application/json' \
  -d '{"text":"reply with exactly: pong"}'

curl -X POST http://127.0.0.1:4096/tui/submit-prompt

POST /tui/publish also exists as a lower-level endpoint for publishing TUI events such as tui.prompt.append, tui.command.execute, and tui.toast.show. Prefer the specific endpoints above unless you need that raw event surface.