CodeBuddy Code HTTP API Beta โ
Beta: This API is in Beta. Interfaces may be adjusted. Feedback is welcome.
CodeBuddy Code provides two public interface sets for developers building Agent applications:
- REST API (
/api/v1/*) โ Stateless HTTP request/response, suitable for webhook integration, management operations, and simple queries - ACP (
/api/v1/acp) โ Stateful streaming protocol (JSON-RPC over SSE), suitable for building full Agent client applications
Quick Start โ
Starting the HTTP Service โ
bash
codebuddy --serve --port 8080 --session-id my-sessionIf a reverse proxy mounts the instance under a subpath, add --base-path (or CODEBUDDY_GATEWAY_BASE_PATH) at startup. The public URL becomes http://127.0.0.1:8080/<prefix>/api/v1/..., while in-process routes remain /api/v1/.... See the CLI Reference and Environment Variables for details.
API Documentation (Swagger UI) โ
Once the service is running, visit:
- Interactive docs:
http://127.0.0.1:8080/api/docs - OpenAPI spec:
http://127.0.0.1:8080/api/openapi.json
Swagger UI provides an interactive testing interface for all public endpoints.
Verify the Service โ
bash
curl http://127.0.0.1:8080/api/v1/health
# {"data":{"status":"ok","uptime":12.3,"platforms":["generic","wecom","wechat-kf"]}}API Layers โ
| Layer | Route Prefix | Compatibility Promise | Description |
|---|---|---|---|
| Public REST API | /api/v1/* | Semantic versioning, no breaking changes | Covered in this document |
| Public ACP Protocol | /api/v1/acp | Follows ACP specification | Full conversation capabilities, see ACP Documentation |
| Internal RPC | /internal/* | No compatibility guarantee | For internal CLI use, not publicly available; when authentication is enabled, credentials are also required (see Authentication); only the Hook service proxy and MCP OAuth callback paths are exempt |
Security โ
Custom Request Header โ
All API requests (except exempt paths) must include the custom request header:
X-CodeBuddy-Request: 1Rationale: A custom request header makes cross-origin browser requests "non-simple requests", forcing a CORS preflight. Combined with a CORS allowlist, requests from unauthorized origins are blocked. Even if an attacker uses fetch(url, { mode: 'no-cors' }), browsers do not allow custom headers in no-cors mode, so the request is rejected by the server (403) due to the missing header.
Exempt Paths โ
The following paths do not require the X-CodeBuddy-Request header:
| Path | Description |
|---|---|
GET / | SPA entry page |
GET /assets/* | Static assets |
GET /docs/* | API documentation pages |
GET /manifest.webmanifest | PWA manifest |
GET /api/v1/auth/status | Authentication status check |
POST /api/v1/auth/login | Login |
*/api/v1/webhooks/* | Webhooks (verified by platform signature) |
GET /api/openapi.json | OpenAPI spec |
GET /api/docs* | Swagger UI |
This validation can be disabled via the environment variable CODEBUDDY_DISABLE_REQUEST_VALIDATION=1.
CORS Allowlist โ
Cross-origin request Origin headers are matched against the server's CORS allowlist. Sources not on the allowlist are rejected (preflight returns 204 without CORS headers; actual requests return 403 Origin not allowed). Allowlist sources:
- Local endpoint's own loopback variants (
localhost/127.0.0.1/[::1], only for the port the service is actually listening on) - Tunnel URL (if enabled)
- Configuration item
gateway.corsOrigins - Environment variable
CODEBUDDY_CODE_CORS_ORIGINS(comma-separated, supports exact origin,*.domainsubdomain wildcards, and*for all)
โ ๏ธ Loopback origins are no longer unconditionally allowed. The earlier implementation allowed any
localhost/127.0.0.1origin (regardless of port), which meant any page occupying a local port in the user's browser (e.g., a malicious page running athttp://localhost:3000) could cross-origin call this service's process execution / file read-write interfaces. CookieSameSite=Strictcannot protect against this scenario โ ports are not part of a "site",localhost:3000andlocalhost:8321are same-site different-origin, and the browser will carry the session Cookie as usual.Local development (Vite dev server 5173 โ backend 8321 is cross-origin) requires explicitly declaring the origin:
bashCODEBUDDY_CODE_CORS_ORIGINS=http://localhost:5173 codebuddy --serveWhen rejected, both the server logs and the
hintfield in the 403 response body will suggest this configuration.
When binding to 0.0.0.0 (e.g., --host 0.0.0.0, common in cloud VM / LAN exposure scenarios), if CODEBUDDY_CODE_CORS_ORIGINS is not explicitly set, the server automatically allows all origins (equivalent to configuring *), enabling access to the Web UI via any IP or domain without additional configuration. When this environment variable is explicitly set, the user configuration takes precedence. In this scenario, authentication is forcibly enabled (see below), and credentials are still required.
Authentication โ
--serve enables password authentication by default. On first startup, a random password is generated and written to ~/.codebuddy/settings.json, and a clickable link with the password is printed in the terminal:
Endpoint http://127.0.0.1:8321
Web UI http://127.0.0.1:8321/?password=<generated-password>
Password <generated-password>
Config ~/.codebuddy/settings.jsonClick the link to log in to the Web UI (the server issues a gateway_session Cookie valid for 30 days; subsequent direct access to the endpoint requires no re-entry).
Authentication mode priority (high โ low):
| Source | Value | Description |
|---|---|---|
Environment variable CODEBUDDY_GATEWAY_AUTH | password / none | Highest priority, suitable for CI |
Command-line --auth <mode> | password / none | Explicit escape hatch; can override the non-loopback enforcement below |
Bound to non-loopback address (e.g., --host 0.0.0.0) | Forced password | Cannot be disabled by the configuration item; an explicit --auth none or the environment variable can still override it |
Configuration item gateway.auth | password / none | |
| Default value | password | Fallback mode for --serve |
Security note: These endpoints include sensitive capabilities such as process execution (
/api/v1/process/*), arbitrary file read/write (/api/v1/files/*,/api/v1/fs/*), and interactive terminal (/api/v1/pty/*). Therefore, authentication is enforced by default (secure by default, consistent with E2B Secured Access default behavior). Disabling authentication means any process on the same machine can execute commands and read/write files via this service. Only recommended in isolated environments (containers / one-shot sandboxes) or CI.
Disabling authentication (only use when you clearly understand the risks; a warning is printed at startup):
bash
codebuddy --serve --auth none
# or
CODEBUDDY_GATEWAY_AUTH=none codebuddy --serveCarrying Credentials โ
API requests (/api/v1/*) only accept headers or Cookies:
bash
# 1) Bearer Token (recommended, also carries the security header)
curl -H "X-CodeBuddy-Request: 1" \
-H "Authorization: Bearer YOUR_PASSWORD" \
http://host:port/api/v1/sessions
# 2) X-Access-Token (equivalent to Bearer, aligned with E2B envd's credential header convention)
curl -H "X-CodeBuddy-Request: 1" \
-H "X-Access-Token: YOUR_PASSWORD" \
http://host:port/api/v1/sessions
# 3) Cookie (automatically carried after browser login)
curl -H "X-CodeBuddy-Request: 1" \
-H "Cookie: gateway_session=<sha256(password)>" \
http://host:port/api/v1/sessionsโ ๏ธ
?password=is only valid forGET /andPOST /api/v1/auth/login; it has no effect on other/api/v1/*endpoints (returns 401). This is by design: URLs are recorded in browser history, server access logs, and leaked when users copy and share links, so passwords do not appear in API request URLs. The sole purpose of?password=is the initial entry to obtain thegateway_sessionCookie.Testing APIs with
?password=will return 401 โ this is not an authentication implementation issue.
Response Format โ
All /api/v1/* endpoints use a unified envelope format:
jsonc
// Success
{
"data": { ... }
}
// Error
{
"error": {
"code": "AUTH_REQUIRED", // Machine-readable error code
"message": "Authentication required" // Human-readable description
}
}Endpoint Overview โ
System โ
| Method | Endpoint | Description |
|---|---|---|
| GET | /api/v1/health | Health check |
| GET | /api/v1/info | Environment info (version, OS, CWD, etc.) |
| GET | /api/v1/metrics | System resource metrics + instance process metrics |
| GET | /api/v1/envs | Environment variables (aligned with E2B envd) |
Authentication โ
| Method | Endpoint | Description |
|---|---|---|
| GET | /api/v1/auth/status | Get authentication status |
| POST | /api/v1/auth/login | Password login, returns token |
Runs (Agent Execution) โ
| Method | Endpoint | Description |
|---|---|---|
| POST | /api/v1/runs | Initiate Agent execution (async, returns runId) |
| GET | /api/v1/runs/:runId | Query execution status |
| GET | /api/v1/runs/:runId/stream | SSE streaming of execution results |
| POST | /api/v1/runs/:runId/cancel | Cancel execution |
Webhooks (Third-party Platform Integration) โ
| Method | Endpoint | Description |
|---|---|---|
| GET | /api/v1/webhooks/:platform | Platform URL verification (WeCom, etc.) |
| POST | /api/v1/webhooks/:platform | Platform message webhook entry |
Supported platforms: generic, wecom (WeCom), wechat-kf (WeChat Customer Service)
Sessions โ
| Method | Endpoint | Description |
|---|---|---|
| GET | /api/v1/sessions | Get session list (supports cwd query parameter) |
| DELETE | /api/v1/sessions/:id | Delete session |
| POST | /api/v1/sessions/:id/rename | Rename session |
| GET | /api/v1/sessions/across-projects | โ ๏ธ Deprecated, use GET /api/v1/sessions?cwd=* instead |
| GET | /api/v1/sessions/workspaces | โ ๏ธ Deprecated |
PTY (Terminal) โ
| Method | Endpoint | Description |
|---|---|---|
| POST | /api/v1/pty | Create PTY session |
| GET | /api/v1/pty | List PTY sessions |
| GET | /api/v1/pty/:id | Query PTY session |
| DELETE | /api/v1/pty/:id | Destroy PTY session |
| GET | /api/v1/pty/:id/output | SSE streaming of PTY output (replaces WebSocket) |
| POST | /api/v1/pty/:id/input/send | Send PTY input (aligned with E2B Process.SendInput) |
| POST | /api/v1/pty/:id/resize | Resize PTY (aligned with E2B Process.Update) |
| WebSocket | /api/v1/pty/:id/ws | PTY bidirectional data transport (legacy compatible) |
Workers & Daemon โ
A Worker is a running CLI process (interactive / bg / daemon), managed through a PID file registry.
| Method | Endpoint | Description |
|---|---|---|
| GET | /api/v1/workers | Get all active Worker list |
| POST | /api/v1/workers | Manually add remote Worker |
| GET | /api/v1/workers/:id | Get Worker details (by PID or name) |
| GET | /api/v1/workers/:id/logs | Get Worker logs (supports multiple types) |
| DELETE | /api/v1/workers/:id | Terminate Worker process |
| GET | /api/v1/daemon/status | Query Daemon status |
| POST | /api/v1/daemon/start | Start Daemon |
| POST | /api/v1/daemon/stop | Stop Daemon |
| POST | /api/v1/daemon/restart | Restart Daemon |
Workers query parameters:
?kind=bgโ Filter by type (interactive / bg / daemon / daemon-worker)?local=trueโ Return local Workers only (used for remote proxy calls)
Log type parameters (GET /api/v1/workers/:id/logs):
?type=telemetryโ Telemetry logs (~/.codebuddy/logs/{date}/)?type=processโ Process stdout/stderr (bg/daemon logs)?type=debugโ Debug logs (~/.codebuddy/debug/, requires--debug)?type=transcriptโ Conversation history summary?tail=200โ Return only the last N lines- When type is omitted, the best source is automatically selected (telemetry > process > debug > transcript)
Jobs (Background Agent Instances) โ
Jobs are background agent instances dispatched by /bg, the left-arrow handoff, or codebuddy agents. They share the JobStore and lifecycle semantics with CLI agent-view / TUI.
| Method | Endpoint | Description |
|---|---|---|
| GET | /api/v1/jobs | List jobs; supports all=1 and cwd |
| POST | /api/v1/jobs | Dispatch a background agent or shell job |
| GET | /api/v1/jobs/events | SSE subscription: snapshot / added / changed / removed / keepalive |
| GET | /api/v1/jobs/prefs | Read pinned/project-group preferences |
| PUT | /api/v1/jobs/prefs | Update pinned/project-group preferences |
| GET | /api/v1/jobs/dispatch-context | Get launch directory, agent catalog (four built-in modes + custom, same as the chat picker), and repository targets; response includes defaultAgentName, agents, permissionMode (process --permission-mode) |
| GET | /api/v1/jobs/resumable | List resumable sessions; supports cwd and includeAttached=1 |
| POST | /api/v1/jobs/resume | Restore a historical session as a job |
| GET | /api/v1/jobs/:id | Get job details; id accepts stable ID, short ID, or sessionId |
| PATCH | /api/v1/jobs/:id/name | Rename a job |
| POST | /api/v1/jobs/:id/reply | Reply to a job waiting for input |
| POST | /api/v1/jobs/:id/stop | Stop a job |
| POST | /api/v1/jobs/:id/respawn | Restart a job and restore its conversation |
| DELETE | /api/v1/jobs/:id | Delete a job record |
| GET | /api/v1/jobs/:id/stream | SSE transcript replay and tailing |
| GET | /api/v1/jobs/:id/transcript | Return the latest 1000 lines as ACP replay updates |
The dispatch body supports prompt, cwd, model, effort, permissionMode, agent, name, bash, sourceSessionId, and bgIsolation (none / worktree).
agentis the main agent:cli/ptc/minimal/createor a custom name. If omitted: process--agent>lastUsed>default> productcli. Shipped mode names are ignored when the master switch is off.minimalwithpermissionMode=planreturns400 BAD_REQUEST.permissionModeacceptsdefault/acceptEdits/plan/auto/dontAsk/bypassPermissions.fullAccessis only allowed for dispatches initiated from the local Web UI; remote, Tunnel, LAN, or proxy-forwarded calls that pass this value return400 BAD_REQUEST.
GET /api/v1/jobs/dispatch-context returns cwd, defaultAgentName (process --agent first, else lastUsed / default / product default), agents (same catalog as the chat chip), permissionMode (process --permission-mode; when set, the UI overrides the lastUsed permission chip), and repoTargets.
Invalid enum values return 400 BAD_REQUEST; omitted optional fields follow configured and process defaults.
Lifecycle fields: state is working / blocked / done / failed / stopped; status is busy / waiting / idle / stopped; alive and settled are independent. A missing job returns 404 JOB_NOT_FOUND; a delete guard returns HTTP 200 with { "deleted": false, "reason": "..." }.
bash
curl -H "X-CodeBuddy-Request: 1" -H "Authorization: Bearer $PASSWORD" \
-H 'Content-Type: application/json' -X POST http://127.0.0.1:8080/api/v1/jobs \
-d '{"prompt":"Check the repository tests","cwd":"/repo/app"}'
curl -N -H "X-CodeBuddy-Request: 1" -H "Authorization: Bearer $PASSWORD" \
http://127.0.0.1:8080/api/v1/jobs/eventsChannels (Remote Control) โ
| Method | Endpoint | Description |
|---|---|---|
| GET | /api/v1/channels | Get client list |
| POST | /api/v1/channels/:type/:id/start | Start client |
| POST | /api/v1/channels/:type/:id/stop | Stop client |
| PATCH | /api/v1/channels/:type/:id | Update WeCom options (streaming / cards). Returns 409 if writing to disk fails |
| POST | /api/v1/channels/wechat | Create WeChat instance |
| POST | /api/v1/channels/wecom | Create WeCom instance |
Filesystem (E2B Compatible) โ
File content operations (aligned with E2B envd HTTP endpoints):
| Method | Endpoint | Description |
|---|---|---|
| GET | /api/v1/files/download?path=... | Download file (aligned with E2B envd GET /files) |
| POST | /api/v1/files/upload?path=... | Upload file (aligned with E2B envd POST /files) |
| POST | /api/v1/files/compose | Compose multiple files (aligned with E2B envd POST /files/compose) |
File operations (aligned with E2B filesystem.proto):
| Method | Endpoint | Description |
|---|---|---|
| POST | /api/v1/fs/stat | Get file/directory info (aligned with Filesystem.Stat) |
| POST | /api/v1/fs/list | List directory contents (aligned with Filesystem.ListDir) |
| POST | /api/v1/fs/mkdir | Create directory (aligned with Filesystem.MakeDir) |
| POST | /api/v1/fs/remove | Remove file/directory (aligned with Filesystem.Remove) |
| POST | /api/v1/fs/move | Move/rename (aligned with Filesystem.Move) |
File watching (aligned with E2B filesystem.proto):
| Method | Endpoint | Description |
|---|---|---|
| POST | /api/v1/fs/watch | Streaming directory watch SSE (aligned with Filesystem.WatchDir) |
| POST | /api/v1/fs/watcher/create | Create watcher (aligned with Filesystem.CreateWatcher) |
| POST | /api/v1/fs/watcher/events | Get watcher events (aligned with Filesystem.GetWatcherEvents) |
| POST | /api/v1/fs/watcher/remove | Remove watcher (aligned with Filesystem.RemoveWatcher) |
CBC enhancements:
| Method | Endpoint | Description |
|---|---|---|
| GET | /api/v1/fs/search?query=... | Fuzzy file search (based on ripgrep, no E2B equivalent) |
| GET | /api/v1/fs/locate?path=...&cwd=... | Locate a file reference from the conversation: first looks for an exact match in cwd and its parent directories (up to the git root), then matches workspace files by path suffix (no E2B equivalent) |
| POST | /api/v1/fs/locate-batch | Batch-locate file references: request { references, cwd? }; each reference returns found / ambiguous / missing / unknown. Same rules as locate, results are cached for 5 seconds, and at most 100 references are processed per call (no E2B equivalent) |
Process Management (E2B Compatible) โ
Aligned with E2B process.proto, mapping gRPC methods to REST endpoints:
| Method | Endpoint | Description |
|---|---|---|
| POST | /api/v1/process/start | Start process (aligned with Process.Start, supports SSE/JSON) |
| GET | /api/v1/process/list | List running processes (aligned with Process.List) |
| POST | /api/v1/process/connect | Connect to process SSE stream (aligned with Process.Connect) |
| POST | /api/v1/process/input/send | Send stdin (aligned with Process.SendInput) |
| POST | /api/v1/process/input/stream | Stream stdin (aligned with Process.StreamInput) |
| POST | /api/v1/process/signal/send | Send signal (aligned with Process.SendSignal) |
| POST | /api/v1/process/stdin/close | Close stdin (aligned with Process.CloseStdin) |
| POST | /api/v1/process/update | Update process config such as PTY resize (aligned with Process.Update) |
ACP (Agent Client Protocol) โ
| Method | Endpoint | Description |
|---|---|---|
| POST | /api/v1/acp/connect | Establish ACP connection, returns connectionId and sessionToken |
| GET | /api/v1/acp | SSE notification subscription (requires acp-connection-id Header) |
| POST | /api/v1/acp | Send JSON-RPC requests (newSession, prompt, cancelRun, etc.) |
| DELETE | /api/v1/acp | Disconnect |
File Changes (Checkpoint) โ Internal โ
| Method | Endpoint | Description |
|---|---|---|
| POST | /internal/file-changes/diff | Get diff content for a single file |
| POST | /internal/file-changes/checkpoints | List checkpoints available for rollback |
| POST | /internal/file-changes/revert | Revert file changes or rollback to a checkpoint |
Note: These are internal endpoints with no stability guarantee, consumed only by the Web UI. When authentication is enabled, credentials are also required (
x-codebuddy-request: 1+Authorization: Bearer <password>); the Web UI satisfies this automatically via the same-origin Cookie. Scripts that call/internal/*directly must add both headers, otherwise they receive 401.
Plugin Management โ
| Method | Endpoint | Description |
|---|---|---|
| GET | /api/v1/plugins | List installed plugins (optional includeBuiltin=false to filter out built-in plugins) |
| POST | /api/v1/plugins | Install plugin |
| POST | /api/v1/plugins/reconcile | Idempotently materialize the plugin state declared by Host Product/settings; waits up to 120 seconds per request |
| POST | /api/v1/plugins/reload | Rescan and activate the committed plugin state; request body is empty |
| POST | /api/v1/plugins/validate | Validate plugin/marketplace manifest file |
| POST | /api/v1/plugins/enable | Enable plugin |
| POST | /api/v1/plugins/disable | Disable plugin |
| POST | /api/v1/plugins/uninstall | Uninstall plugin |
| POST | /api/v1/plugins/update | Update plugin to latest version |
| GET | /api/v1/plugins/marketplaces | List configured plugin marketplaces (optional includeBuiltin=false to filter out built-in marketplaces) |
| POST | /api/v1/plugins/marketplaces | Add plugin marketplace (optional autoUpdate to enable auto-update on add) |
| POST | /api/v1/plugins/marketplaces/browse | Browse available plugins in marketplace |
| POST | /api/v1/plugins/marketplaces/update | Update marketplace (sync remote repository content) |
| POST | /api/v1/plugins/marketplaces/auto-update | Enable/disable marketplace auto-update |
| DELETE | /api/v1/plugins/marketplaces/:name | Delete plugin marketplace |
Settings Management โ
| Method | Endpoint | Description |
|---|---|---|
| GET | /api/v1/settings | List all settings |
| GET | /api/v1/settings/:key | Get a single setting value |
| PUT | /api/v1/settings/:key | Set a setting value |
| POST | /api/v1/settings/:key/items | Append values to an array-type setting |
| POST | /api/v1/settings/:key/remove | Remove values from an array-type setting |
Scenario Variant Models โ
| Method | Endpoint | Description |
|---|---|---|
| GET | /api/v1/model-variants/lite | Query the Lite model catalog, user configuration, current effective model, and its source |
| PUT | /api/v1/model-variants/lite | Set the user-level Lite model; equivalent to /model:lite <model-id> |
| POST | /api/v1/model-variants/lite/reset | Restore default Lite resolution; equivalent to /model:lite default |
Workspace Directories โ
| Method | Endpoint | Description |
|---|---|---|
| GET | /api/v1/workspace-dirs | List current attached working directories |
| POST | /api/v1/workspace-dirs | Add a single working directory |
| DELETE | /api/v1/workspace-dirs?path= | Remove a single working directory |
| PUT | /api/v1/workspace-dirs/sync | Full sync of working directory list |
Task Templates โ
| Method | Endpoint | Description |
|---|---|---|
| GET | /api/v1/tasks/templates | Get task templates |
| POST | /api/v1/tasks/templates/refresh | Refresh (trigger AI recommendations) |
Usage Statistics โ
| Method | Endpoint | Description |
|---|---|---|
| GET | /api/v1/stats | Historical usage statistics (across all projects) |
| GET | /api/v1/stats/session | Current session real-time statistics |
Traces โ
| Method | Endpoint | Description |
|---|---|---|
| GET | /api/v1/traces | Get trace list (supports pagination and filtering) |
| GET | /api/v1/traces/:traceId | Get trace details (with spans) |
| DELETE | /api/v1/traces | Clear all traces |
Traces query parameters:
?offset=0&limit=50โ Pagination (limit max 200)?session_id=xxxโ Filter by session ID?worker_pid=12345โ Specify Worker instance (supports remote proxy)?worker_pid=allโ Scan all instances
Scheduled Tasks โ
| Method | Endpoint | Description |
|---|---|---|
| GET | /api/v1/scheduled-tasks | Get scheduled task list |
| POST | /api/v1/scheduled-tasks | Create scheduled task |
| PATCH | /api/v1/scheduled-tasks/:id | Edit, pause, or resume scheduled task |
| GET | /api/v1/scheduled-tasks/:id/executions | Get execution records (including durable, queued/running status, and ownerKind, ownerId, ownerPid, sessionId, runId) |
| DELETE | /api/v1/scheduled-tasks/:id | Delete scheduled task |
Scheduled task query parameters:
?sessionId=xxxโ Session ID (required, uses current active session if not provided)
Usage Examples โ
The following examples omit the common request headers to highlight each endpoint's own parameters. When actually calling
/api/v1/*, you need to include:-H "X-CodeBuddy-Request: 1" -H "Authorization: Bearer $PASSWORD"Where
$PASSWORDis the password printed at--servestartup (see Authentication). Missing the security header results in 403Missing required header; missing credentials results in 401AUTH_REQUIRED. Only/api/v1/health,/api/v1/auth/status, and other exempt endpoints can be accessed directly.
Health Check โ
bash
curl http://127.0.0.1:8080/api/v1/healthInitiate Agent Execution โ
bash
# Send message (body is Gateway Protocol format, id/type required)
curl -X POST http://127.0.0.1:8080/api/v1/runs \
-H "Content-Type: application/json" \
-H "X-CodeBuddy-Request: 1" \
-d '{
"id": "run-1",
"type": "message",
"source": {"platform": "generic", "sender": {"id": "dev", "name": "Developer"}, "conversation": {"id": "run-1", "type": "direct"}},
"payload": {"text": "Help me analyze code performance"}
}'
# Response: {"data": {"runId": "uuid-xxx", "status": "accepted"}}
# Get results via SSE stream (also requires X-CodeBuddy-Request header)
curl -H "X-CodeBuddy-Request: 1" http://127.0.0.1:8080/api/v1/runs/uuid-xxx/streamRequest Body Fields (Gateway Protocol) โ
The request body for POST /api/v1/runs uses the Gateway Protocol inbound message format:
| Field | Required | Type | Description |
|---|---|---|---|
id | โ | string | Unique message ID, generated by the caller, used for deduplication and tracing |
type | โ | "message" | "action" | Message type. message initiates a conversation, action sends a control command |
payload.text | โ | string | Prompt text (also accepts top-level text / prompt) |
payload.attachments | โ | array | Attachment list, elements contain type (image/voice/video/file), url, urlType (local-path/url), etc. |
version | โ | string | Protocol version, default "1.0" |
source.platform | โ | string | Source platform, default "generic" |
source.sender.id | โ | string | Sender ID, used for rate limiting; defaults to "unknown" |
source.sender.name | โ | string | Sender name |
source.conversation.id | โ | string | Conversation ID, defaults to id |
source.conversation.type | โ | "direct" | "group" | Conversation type, default "direct" |
action | โ | "cancel" | "status" | Control action, only used when type="action" |
callback.url | โ | string | Callback URL for async result delivery (mode B) |
callback.headers | โ | object | Custom headers for the callback request |
timeoutMs | โ | number | Single execution timeout (milliseconds), takes priority over settings.gateway.runTimeoutMs; can also use the X-Codebuddy-Run-Timeout request header. Set to 0 or negative to disable timeout protection |
The authoritative definition is in the source code
src/node/remote-gateway/gateway-protocol.tsasGatewayInboundMessage.
PTY Terminal Management โ
bash
# Create terminal
curl -X POST http://127.0.0.1:8080/api/v1/pty \
-H "Content-Type: application/json" \
-d '{"cols": 120, "rows": 40}'
# List terminals
curl http://127.0.0.1:8080/api/v1/pty
# SSE streaming output (replaces WebSocket)
curl http://127.0.0.1:8080/api/v1/pty/SESSION_ID/output
# Send input
curl -X POST http://127.0.0.1:8080/api/v1/pty/SESSION_ID/input/send \
-H "Content-Type: application/json" \
-d '{"data": "ls -la\n"}'
# Resize
curl -X POST http://127.0.0.1:8080/api/v1/pty/SESSION_ID/resize \
-H "Content-Type: application/json" \
-d '{"cols": 200, "rows": 50}'
# Destroy terminal
curl -X DELETE http://127.0.0.1:8080/api/v1/pty/SESSION_IDFilesystem Operations (E2B Compatible) โ
bash
# Download file
curl "http://127.0.0.1:8080/api/v1/files/download?path=/tmp/test.txt"
# Upload file
curl -X POST "http://127.0.0.1:8080/api/v1/files/upload?path=/tmp/upload.txt" \
-H "Content-Type: application/octet-stream" \
--data-binary @local-file.txt
# Get file info
curl -X POST http://127.0.0.1:8080/api/v1/fs/stat \
-H "Content-Type: application/json" \
-d '{"path": "/tmp"}'
# List directory
curl -X POST http://127.0.0.1:8080/api/v1/fs/list \
-H "Content-Type: application/json" \
-d '{"path": "/tmp", "depth": 2}'
# Create directory
curl -X POST http://127.0.0.1:8080/api/v1/fs/mkdir \
-H "Content-Type: application/json" \
-d '{"path": "/tmp/new-dir"}'
# Fuzzy file search (CBC enhancement)
curl "http://127.0.0.1:8080/api/v1/fs/search?query=component&limit=10"
# Locate a file reference (CBC enhancement): utils/git.ts is found even without the src/ prefix
curl "http://127.0.0.1:8080/api/v1/fs/locate?path=utils/git.ts&cwd=/path/to/project"
# Batch-locate file references (CBC enhancement): validate all references in a message at once
curl -X POST http://127.0.0.1:8080/api/v1/fs/locate-batch \
-H "Content-Type: application/json" \
-d '{"references": ["README.md", "utils/git.ts", "nope/missing.ts"], "cwd": "/path/to/project"}'Process Management (E2B Compatible) โ
bash
# Start process (JSON mode)
curl -X POST http://127.0.0.1:8080/api/v1/process/start \
-H "Content-Type: application/json" \
-d '{"process": {"cmd": "python3", "args": ["script.py"]}, "tag": "my-script"}'
# Start process (SSE streaming output)
curl -X POST http://127.0.0.1:8080/api/v1/process/start \
-H "Content-Type: application/json" \
-H "Accept: text/event-stream" \
-d '{"process": {"cmd": "python3", "args": ["script.py"]}}'
# List running processes
curl http://127.0.0.1:8080/api/v1/process/list
# Send stdin
curl -X POST http://127.0.0.1:8080/api/v1/process/input/send \
-H "Content-Type: application/json" \
-d '{"process": {"pid": 12345}, "input": {"stdin": "hello\n"}}'
# Send signal (SIGTERM)
curl -X POST http://127.0.0.1:8080/api/v1/process/signal/send \
-H "Content-Type: application/json" \
-d '{"process": {"tag": "my-script"}, "signal": 15}'
# System metrics + instance process metrics
curl http://127.0.0.1:8080/api/v1/metrics
# Response: { data: { ts, cpuCount, cpuUsedPct, memTotalMib, memUsedMib, diskUsed, diskTotal, instances: [{ id, cwd, pid, rssMib, heapUsedMib, heapTotalMib, uptimeSeconds, ... }] } }Session Management โ
bash
# Get session list for the current workspace
curl http://127.0.0.1:8080/api/v1/sessions
# Get session list across all workspaces
curl http://127.0.0.1:8080/api/v1/sessions?cwd=*
# Get session list for a specific working directory
curl http://127.0.0.1:8080/api/v1/sessions?cwd=/path/to/workspace
# Get session list for a specific project (filter by compressed working directory name)
curl http://127.0.0.1:8080/api/v1/sessions?cwd=*&projectId=workspace-hash
# Rename session
curl -X POST http://127.0.0.1:8080/api/v1/sessions/SESSION_ID/rename \
-H "Content-Type: application/json" \
-d '{"name": "Performance Optimization Discussion"}'cwd query parameter reference:
| cwd Value | Description |
|---|---|
| Not provided | Returns sessions for the current workspace |
* | Returns sessions across all workspaces |
/path/to/workspace | Returns sessions for the specified working directory |
File Change Management (Internal) โ
The
/internal/*examples below omit authentication headers for brevity. When authentication is enabled, every request must add-H "x-codebuddy-request: 1" -H "Authorization: Bearer $PASSWORD", otherwise it returns 401.
bash
# Get file diff (requires file to be tracked in a checkpoint)
curl -X POST http://127.0.0.1:8080/internal/file-changes/diff \
-H "Content-Type: application/json" \
-d '{"path": "/path/to/file.ts"}'
# Response: {"data": {"path": "/path/to/file.ts", "oldText": "...", "newText": "..."}}
# List checkpoints available for rollback
curl -X POST http://127.0.0.1:8080/internal/file-changes/checkpoints \
-H "Content-Type: application/json" \
-d '{}'
# Response: {"data": {"checkpoints": [{"id": "xxx", "label": "...", "createdAt": 1234567890, "files": [...], "additions": 5, "deletions": 2}]}}
# Revert changes by file
curl -X POST http://127.0.0.1:8080/internal/file-changes/revert \
-H "Content-Type: application/json" \
-d '{"paths": ["/path/to/file.ts"]}'
# Response: {"data": {"success": true, "revertedFiles": ["/path/to/file.ts"]}}
# Rollback to a specific checkpoint
curl -X POST http://127.0.0.1:8080/internal/file-changes/revert \
-H "Content-Type: application/json" \
-d '{"checkpointId": "checkpoint-uuid", "scope": "CodeAndConversation"}'
# scope options: "Code" (revert files only), "Conversation" (revert conversation only), "CodeAndConversation" (revert all)
# Revert all changes (rollback to the earliest checkpoint)
curl -X POST http://127.0.0.1:8080/internal/file-changes/revert \
-H "Content-Type: application/json" \
-d '{}'Plugin Management โ
bash
# List installed plugins (each item includes an isBuiltIn boolean field indicating whether it belongs to the built-in marketplace)
curl http://127.0.0.1:8080/api/v1/plugins
# List only user-installed plugins, filtering out built-in marketplace plugins
curl "http://127.0.0.1:8080/api/v1/plugins?includeBuiltin=false"
# Install plugin ("name@marketplace" format)
curl -X POST http://127.0.0.1:8080/api/v1/plugins \
-H "Content-Type: application/json" \
-d '{"plugin": "my-plugin@my-marketplace"}'
# Idempotently materialize all plugin states declared by the current Host Product/settings
curl -X POST http://127.0.0.1:8080/api/v1/plugins/reconcile
# The Host can also submit a complete Product snapshot; multiple snapshots are processed in request order
curl -X POST http://127.0.0.1:8080/api/v1/plugins/reconcile \
-H "Content-Type: application/json" \
-d '{"reason":"product-update","productConfig":{"builtInMarketPlugins":[]}}'
# 204 means strict materialization completed; 409 means the runtime disabled plugin management;
# 503 means strict materialization partially failed and can be retried idempotently; 504 only ends the current HTTP wait,
# while shared materialization already in progress continues in the background and subsequent requests join that operation.
# Rescan and activate the committed state; request body is empty
curl -X POST http://127.0.0.1:8080/api/v1/plugins/reload \
-H "Content-Type: application/json" \
-d '{}'
# Enable plugin
curl -X POST http://127.0.0.1:8080/api/v1/plugins/enable \
-H "Content-Type: application/json" \
-d '{"plugin": "my-plugin@my-marketplace"}'
# Disable plugin
curl -X POST http://127.0.0.1:8080/api/v1/plugins/disable \
-H "Content-Type: application/json" \
-d '{"plugin": "my-plugin@my-marketplace"}'
# Uninstall plugin
curl -X POST http://127.0.0.1:8080/api/v1/plugins/uninstall \
-H "Content-Type: application/json" \
-d '{"plugin": "my-plugin@my-marketplace"}'
# Update plugin to latest version (pass waitForApply=true to wait for rebuild to take effect before returning)
curl -X POST http://127.0.0.1:8080/api/v1/plugins/update \
-H "Content-Type: application/json" \
-d '{"plugin": "my-plugin@my-marketplace"}'
# List plugin marketplaces (each item includes an isBuiltIn boolean field)
curl http://127.0.0.1:8080/api/v1/plugins/marketplaces
# List only user-added marketplaces, filtering out built-in marketplaces
curl "http://127.0.0.1:8080/api/v1/plugins/marketplaces?includeBuiltin=false"
# Add plugin marketplace
curl -X POST http://127.0.0.1:8080/api/v1/plugins/marketplaces \
-H "Content-Type: application/json" \
-d '{"source": "https://example.com/marketplace", "name": "my-marketplace"}'
# Add plugin marketplace with auto-update enabled by default (equivalent to adding and then calling marketplaces/auto-update)
curl -X POST http://127.0.0.1:8080/api/v1/plugins/marketplaces \
-H "Content-Type: application/json" \
-d '{"source": "https://example.com/marketplace", "name": "my-marketplace", "autoUpdate": true}'
# Browse plugins in marketplace
curl -X POST http://127.0.0.1:8080/api/v1/plugins/marketplaces/browse \
-H "Content-Type: application/json" \
-d '{"marketplace": "my-marketplace"}'
# Update marketplace (actually pulls latest content from remote)
curl -X POST http://127.0.0.1:8080/api/v1/plugins/marketplaces/update \
-H "Content-Type: application/json" \
-d '{"marketplace": "my-marketplace"}'
# Enable/disable marketplace auto-update (when enabled, periodically syncs and upgrades installed plugins in the background)
curl -X POST http://127.0.0.1:8080/api/v1/plugins/marketplaces/auto-update \
-H "Content-Type: application/json" \
-d '{"marketplace": "my-marketplace", "autoUpdate": true}'
# Delete plugin marketplace
curl -X DELETE http://127.0.0.1:8080/api/v1/plugins/marketplaces/my-marketplaceSettings Management โ
bash
# List all settings
curl http://127.0.0.1:8080/api/v1/settings
# List settings by scope
curl "http://127.0.0.1:8080/api/v1/settings?scope=user"
# Get a single setting
curl http://127.0.0.1:8080/api/v1/settings/model
# Set a setting value
curl -X PUT http://127.0.0.1:8080/api/v1/settings/theme \
-H "Content-Type: application/json" \
-d '{"value": "dark"}'
# Append values to an array-type setting
curl -X POST http://127.0.0.1:8080/api/v1/settings/permissions/items \
-H "Content-Type: application/json" \
-d '{"values": ["Allow: Read(**)"]}'
# Remove values from an array-type setting
curl -X POST http://127.0.0.1:8080/api/v1/settings/permissions/remove \
-H "Content-Type: application/json" \
-d '{"values": ["Allow: Read(**)"]}'Scenario Variant Models โ
The Lite API reads and writes the same setting used by /model:lite. Setting a value only writes the user-level variantModels.lite (nothing is written to disk if the value is unchanged); the environment variable CODEBUDDY_SMALL_FAST_MODEL and the project-level variantModels.lite still take precedence per the existing priority order, in which case source is env-variant / settings-project.
All three endpoints accept an optional ?sessionId= to compute the dynamic Default based on that session's main model; the session must already be active in this process, otherwise 404 SESSION_NOT_FOUND is returned. modelId only accepts models[].id, not display names.
bash
# Query Lite
curl "http://127.0.0.1:8080/api/v1/model-variants/lite?sessionId=<session-id>"
# {"data":{"configuredModelId":null,"effectiveModelId":"<lite-id>","source":"related-models",
# "models":[{"id":"<lite-id>","name":"<Lite Name>","disabled":false}]}}
# Set Lite
curl -X PUT http://127.0.0.1:8080/api/v1/model-variants/lite \
-H "Content-Type: application/json" \
-d '{"modelId": "<model-id>"}'
# Restore default Lite resolution
curl -X POST http://127.0.0.1:8080/api/v1/model-variants/lite/reset \
-H "Content-Type: application/json" \
-d '{}'Workspace Directories โ
Manage attached working directories so that the permission system allows file operations under these directories (same effect as the /add-dir command).
bash
# List current attached working directories
curl http://127.0.0.1:8080/api/v1/workspace-dirs
# Add a working directory
curl -X POST http://127.0.0.1:8080/api/v1/workspace-dirs \
-H "Content-Type: application/json" \
-d '{"path": "/Users/me/other-project"}'
# Remove a working directory
curl -X DELETE "http://127.0.0.1:8080/api/v1/workspace-dirs?path=/Users/me/other-project"
# Full sync (call after page refresh recovery)
curl -X PUT http://127.0.0.1:8080/api/v1/workspace-dirs/sync \
-H "Content-Type: application/json" \
-d '{"dirs": ["/Users/me/project-a", "/Users/me/project-b"]}'Notes:
- Added directories are stored in CLI scope (process memory) and are lost when the instance shuts down
- The frontend persists them via the Web UI's workspace storage and automatically syncs to the backend on page refresh
- After adding, Agent tools (Read/Write/Glob/Grep/Bash) can access these directories without asking
Usage Statistics โ
bash
# Get historical usage statistics (activity heatmap, model/tool usage rankings, consecutive active days, etc.)
curl http://127.0.0.1:8080/api/v1/stats
# Get current session real-time cost statistics
curl http://127.0.0.1:8080/api/v1/stats/sessionTraces โ
bash
# Get trace list (paginated)
curl "http://127.0.0.1:8080/api/v1/traces?offset=0&limit=20"
# Filter by session ID
curl "http://127.0.0.1:8080/api/v1/traces?session_id=SESSION_ID"
# Get trace details (with all spans)
curl http://127.0.0.1:8080/api/v1/traces/TRACE_ID
# Get traces from a remote Worker
curl "http://127.0.0.1:8080/api/v1/traces?worker_pid=12345"
# Clear all traces
curl -X DELETE http://127.0.0.1:8080/api/v1/tracesScheduled Task Management โ
bash
# Get scheduled task list
curl "http://127.0.0.1:8080/api/v1/scheduled-tasks?sessionId=SESSION_ID"
# Create scheduled task (every 5 minutes)
curl -X POST http://127.0.0.1:8080/api/v1/scheduled-tasks \
-H "Content-Type: application/json" \
-d '{"cron": "*/5 * * * *", "prompt": "Check build status", "sessionId": "SESSION_ID"}'
# Create one-time task (every Monday at 9 AM)
curl -X POST http://127.0.0.1:8080/api/v1/scheduled-tasks \
-H "Content-Type: application/json" \
-d '{"cron": "0 9 * * 1", "prompt": "Generate weekly report", "recurring": false, "sessionId": "SESSION_ID"}'
# Create durable task (persists after restart)
curl -X POST http://127.0.0.1:8080/api/v1/scheduled-tasks \
-H "Content-Type: application/json" \
-d '{"cron": "0 0 * * *", "prompt": "Daily cleanup", "durable": true, "sessionId": "SESSION_ID"}'
# Pause scheduled task
curl -X PATCH http://127.0.0.1:8080/api/v1/scheduled-tasks/TASK_ID \
-H "Content-Type: application/json" \
-d '{"enabled": false, "sessionId": "SESSION_ID"}'
# View execution records
curl "http://127.0.0.1:8080/api/v1/scheduled-tasks/TASK_ID/executions?sessionId=SESSION_ID"
# Delete scheduled task
curl -X DELETE "http://127.0.0.1:8080/api/v1/scheduled-tasks/TASK_ID?sessionId=SESSION_ID"Error Codes โ
| Error Code | HTTP Status | Description |
|---|---|---|
AUTH_REQUIRED | 401 | Authentication required |
AUTH_INVALID | 401 | Invalid authentication |
AUTH_RATE_LIMITED | 429 | Too many login attempts |
NOT_FOUND | 404 | Resource not found |
BAD_REQUEST | 400 | Invalid request parameters |
RATE_LIMITED | 429 | Request rate too high |
INTERNAL_ERROR | 500 | Internal server error |
SESSION_NOT_FOUND | 404 | Session not found |
SESSION_DELETE_CURRENT | 400 | Cannot delete current session |
TERMINAL_NOT_FOUND | 404 | PTY not found |
PROCESS_NOT_FOUND | 404 | Process not found |
PATH_REQUIRED | 400 | Missing path parameter |
PATH_NOT_DIRECTORY | 400 | Path is not a directory |
INSUFFICIENT_STORAGE | 507 | Insufficient disk space |
RUN_NOT_FOUND | 404 | Run not found |
PLATFORM_UNSUPPORTED | 400 | Unsupported webhook platform |
SIGNATURE_INVALID | 403 | Signature verification failed |