Skip to main content
The Runtimes API covers the four non-OpenClaw runtimes (claude-code, codex, hermes, clawboo-native): listing their capabilities and connection state, installing their CLI, storing provider keys in the encrypted vault, verifying a key before persisting it, and driving a board task end-to-end on a chosen runtime. This group also covers POST /api/onboarding/seed-native-team, which mints a default native leader + specialist team for first-run users.
OpenClaw is not in this group — it is a connected substrate driven over the Gateway, not a CLI you install or a key you paste. Any route in this group returns 404 for the openclaw id. See the System API for OpenClaw lifecycle and the Agents API for the agent registry.
An unknown :id returns 404 { "error": "unknown runtime '<id>'" } on every route.

Routes

MethodPathSummary
GET/api/runtimesList runtimes with capabilities, health, and connection state
POST/api/runtimes/:id/installInstall the runtime CLI (SSE)
POST/api/runtimes/:id/connectStore a provider key in the encrypted vault
POST/api/runtimes/:id/disconnectClear the stored credential
POST/api/runtimes/:id/healthcheckVerify a pasted key without persisting it
POST/api/runtimes/:id/runDrive a board task on this runtime end-to-end
POST/api/onboarding/seed-native-teamMint a default native leader + specialist team

GET /api/runtimes

Lists every runtime with its capabilities, live health, and install/auth status. The available[] array advertises the full catalog for runtimes the user has not yet connected.

Response 200 OK

runtimes
array
Connected runtimes with their full status.
available
array
Full runtime catalog including runtimes not yet connected.
curl http://localhost:18790/api/runtimes

POST /api/runtimes/:id/install (SSE)

Installs the runtime’s CLI. npm runtimes (claude-code, codex) run npm install -g <pkg>. The pip runtime (hermes) uses pipx install with a fallback to pip install --user. The built-in clawboo-native returns 400 before any stream opens. The response is Server-Sent Events (Content-Type: text/event-stream). Use curl -N to stream the output. Each frame is data: <json>\n\n.

Event catalog

typeWhenPayload fields
progressInstall start, and on PEP-668 retrystep ('installing''retrying'), message
outputPer stdout/stderr lineline
errorTooling missing, permission denied, or non-zero exitcode, message
completeProcess exits 0success: true, optional warning
Terminal error codes:
CodeMeaning
NPM_MISSINGnpm not found
PYTHON_MISSINGPython 3 with pip/pipx not found
EACCESPermission denied
SPAWN_THROWThe spawn call threw synchronously
EXIT_<n>Non-zero process exit
curl -N -X POST http://localhost:18790/api/runtimes/claude-code/install
Example SSE frames:
data: {"type":"progress","step":"installing","message":"Installing Claude Code…"}

data: {"type":"output","line":"added 1 package in 3s"}

data: {"type":"complete","success":true}

POST /api/runtimes/:id/connect

Stores a provider key in the encrypted vault and marks the runtime connected. The key is never echoed in the response. For the OAuth runtime (codex), this is a no-op that returns the terminal login command instead.

Request body

apiKey
string
Required for api-key runtimes. Must be non-empty.
provider
string
For clawboo-native only: routes the key to a specific provider ('anthropic', 'openai', 'openrouter', 'ollama'). Omit to store under ANTHROPIC_API_KEY.

Responses

200 OK — key stored, runtime is ready:
{ "ok": true, "connectionState": "ready" }
200 OK — Codex (OAuth) returns the login command:
{ "ok": true, "connectionState": "needs-login", "loginCommand": "codex login" }
For clawboo-native, pass provider: "openrouter" to store an OpenRouter key, or provider: "ollama" for a keyless Ollama configuration.
# Claude Code
curl -X POST http://localhost:18790/api/runtimes/claude-code/connect \
  -H 'Content-Type: application/json' \
  -d '{"apiKey":"sk-ant-..."}'

# Native runtime with OpenRouter
curl -X POST http://localhost:18790/api/runtimes/clawboo-native/connect \
  -H 'Content-Type: application/json' \
  -d '{"apiKey":"sk-or-...","provider":"openrouter"}'

POST /api/runtimes/:id/disconnect

Clears the stored credential for the runtime. The binary stays installed; the card returns to needs-auth.

Response 200 OK

{ "ok": true, "connectionState": "needs-auth" }
curl -X POST http://localhost:18790/api/runtimes/hermes/disconnect

POST /api/runtimes/:id/healthcheck

Verifies a pasted provider key with a single authenticated GET to the provider’s models endpoint. The key is used once and never persisted. A bad key or unreachable provider resolves to { ok: false, error } — the handler never throws into the request.
This route is native-only (clawboo-native). Any other valid runtime id returns 400 { "ok": false, "error": "healthcheck is only supported for the native runtime" }.
Provider → probe endpoint mapping:
ProviderEndpoint
anthropichttps://api.anthropic.com/v1/models
openaihttps://api.openai.com/v1/models
openrouterhttps://openrouter.ai/api/v1/models
ollama<OLLAMA_BASE_URL>/api/tags (keyless)
The fetch is bounded by an 8-second timeout.

Request body

provider
string
One of 'anthropic', 'openai', 'openrouter', 'ollama'. Defaults to 'anthropic'.
apiKey
string
Required for all providers except 'ollama'.

Responses

200 OK — provider reachable, key authenticated:
{ "ok": true }
200 OK — provider rejected the key or was unreachable (note: still HTTP 200):
{ "ok": false, "error": "Invalid API key." }
{ "ok": false, "error": "Could not reach anthropic (timed out)." }
curl -X POST http://localhost:18790/api/runtimes/clawboo-native/healthcheck \
  -H 'Content-Type: application/json' \
  -d '{"provider":"anthropic","apiKey":"sk-ant-..."}'

POST /api/runtimes/:id/run

Drives a board task on the runtime end-to-end: claim → worktree → run → report-up, via the server-side executor runner. The runtime’s MCP client attaches to this server’s /api/mcp/* over a server-trusted loopback URL. If the client disconnects before the run finishes, the run and its subprocess are aborted and the task is released.
A 409 from this route means the task could not be atomically claimed — another worker holds it. Do not retry. See the 409 no-retry rule.

Request body

taskId
string
required
The board task to run.
assigneeAgentId
string
The agent id to assign. Defaults to the runtime id. Must match /^[A-Za-z0-9_-]+$/.
repoPath
string
Absolute path to the git repo to branch the worktree from.
kind
string
Task kind → isolation. Defaults to 'code'.
model
string
Model override for this run.
keepForResume
boolean
Pause the worktree and release the task for cross-runtime handoff instead of completing it.

Responses

200 OK — the task ran:
{
  ok: true
  runtimeId: string
  execId: string
  doneReason: 'success' | 'max_turns' | 'aborted' | 'error'
  status: string
  summary: string
  costUsd: number | null
  usedWorktree: boolean
  degradations: string[]
}
409 Conflict — the task could not be claimed — do not retry:
{ "ok": false, "reason": "conflict" }
422 Unprocessable Entity — run refused for a board/runtime reason (reason is one of too_deep, connected_substrate, budget_paused). connected_substrate means the target runtime is a connected substrate and cannot be dispatched through this path:
{ "ok": false, "reason": "too_deep" | "connected_substrate" | "budget_paused" }
curl -X POST http://localhost:18790/api/runtimes/claude-code/run \
  -H 'Content-Type: application/json' \
  -d '{"taskId":"<task-uuid>","repoPath":"/path/to/repo","kind":"code"}'

POST /api/onboarding/seed-native-team

Mints a default native team — a leader (tasks tool enabled, capable model) and a specialist (cheaper model) — for a first-run user who just connected a provider key. Both agents are clawboo-native rows created through the native AgentSource (no Gateway, no provider SDK call). The Know Your Team onboarding flags are pre-satisfied so the user lands straight in chat.
This route is not under /api/runtimes and takes no :id segment.

Request body

provider
string
Provider to use. One of 'anthropic', 'openai', 'openrouter', 'ollama'. Defaults to 'anthropic'.
model
string
Optional leader-model override. The specialist keeps its provider default.
Per-provider default models:
ProviderLeaderSpecialist
anthropicclaude-sonnet-4-6claude-haiku-4-5
openaigpt-4ogpt-4o-mini
openrouteranthropic/claude-haiku-4.5openai/gpt-4o-mini
ollamallama3.2llama3.2

Response 201 Created

{ "teamId": "...", "leaderAgentId": "...", "specialistAgentId": "..." }
curl -X POST http://localhost:18790/api/onboarding/seed-native-team \
  -H 'Content-Type: application/json' \
  -d '{"provider":"anthropic"}'

See also