Skip to main content
The Clawboo dashboard server (apps/web/server/index.ts) is an Express app wrapped in a raw http.Server so it can also handle the WebSocket upgrade for the Gateway proxy. Every JSON route lives under /api/, is registered in one router (apps/web/server/api/index.ts), and returns the standard { error: string } envelope on failure. This page covers the cross-cutting facts: base URL, the proxy, auth, body limits, the error shape, and the streaming endpoints, then links to the per-resource reference pages.
These docs describe Clawboo v0.3.1, the current release.

Base URL

The server picks its port at boot, so there is no single hardcoded URL. The default is 18790; if it is taken the server scans upward through 18809 (20 consecutive ports) and binds the first free one.
  • CLAWBOO_API_PORT=N pins the port exactly (no fallback; the server throws if N is taken).
  • CLAWBOO_API_PORT_START=M changes where the auto-scan begins (default 18790).
  • In a non---dev (production / CLI) boot with neither Clawboo override set, the legacy PORT env var is honored (Heroku/Render/Cloud Run compatibility).
After a successful bind the chosen port is written to <clawboo-home>/api-port.txt so the CLI, the Vite dev proxy, and e2e helpers can discover it without scanning. All curl examples in the per-resource pages assume the default 18790.

Host binding

The server binds loopback (127.0.0.1) by default; a fresh install is never reachable by other hosts. Set HOST to widen the bind (e.g. a headless/remote box); HOSTNAME is deliberately ignored. Binding a non-loopback interface without an access token makes the server refuse to start (a SECURITY: error, exit 1), so pair a wide bind with STUDIO_ACCESS_TOKEN, or opt in explicitly with CLAWBOO_ALLOW_INSECURE=1.

How the SPA reaches /api

The SPA and the API are served from the same origin in production: the Express app serves the Vite build (dist/ui/) as static files with a GET catch-all that returns index.html for client-side routes, and the same app mounts the API router. So a browser at http://localhost:18790 hits /api/... on that same origin with no CORS. In dev (pnpm dev), Vite serves the SPA on :5173 and proxies /api to the dynamic API port; CORS (origin: true, credentials: true) is enabled only in dev mode.

Request body limit

All routes share one JSON body parser, applied before the router:
A body larger than 2 MB is rejected by the parser. Routes that take no body (most GET/DELETE routes) ignore it.

The access gate

Authentication is opt-in via the STUDIO_ACCESS_TOKEN env var. When it is unset or blank, the gate is disabled and every route is open; the secure-by-default posture relies on the loopback bind, not on a token. When the token is set, the gate (packages/gateway-proxy/src/access-gate.ts) is enforced as middleware before the router:
The cookie is marked Secure only when the request arrives over TLS (X-Forwarded-Proto: https). On a plain-http loopback origin the cookie is set without Secure so the gate still works.
The /api/ prefix check is case-folded (pathname.toLowerCase()), so /API/settings, /Api/..., etc. are gated identically; there is no case-sensitivity bypass (the server also sets Express case sensitive routing: true). The configured token is validated against a safe charset (^[A-Za-z0-9._~-]+$) when the gate is built; a token containing a disallowed character disables the gate with a loud warning (fail-loud, never a silent lockout).
The query param (access_token) and cookie name (clawboo_access) are the defaults; both are configurable in createAccessGate(...) but the server passes neither, so the defaults apply.

The WebSocket upgrade: /api/gateway/ws

The one non-HTTP endpoint. The raw http.Server routes the upgrade event: a request whose pathname is exactly /api/gateway/ws is handed to the Gateway proxy; every other upgrade has its socket destroyed (Vite HMR runs on its own port). The proxy opens an upstream WebSocket to the OpenClaw Gateway, injects the server-side auth token + device signature into the connect frame, and forwards frames bidirectionally; the browser never sees the upstream token. This is a protocol stream, not a request/response endpoint. The frame shapes and lifecycle are documented in the Gateway & events concept page, not here.
The access gate’s allowUpgrade(req) check runs before the proxy forwards the upgrade. If STUDIO_ACCESS_TOKEN is set, a browser must already hold the clawboo_access cookie or the upgrade is refused (socket destroyed).

The error envelope

Every JSON route returns the same envelope on failure:
The HTTP status carries the category; the error string is the human-readable message. Common statuses across the surface: A handful of routes deviate from the bare { error } shape, and those deviations are documented on the resource page:
  • The native /api/runtimes/:id/healthcheck route returns { ok: false, error } (success is { ok: true }).
  • /api/runtimes/:id/run returns { ok: false, reason } on its non-200 board/runtime refusals.
  • SSE routes emit error-typed event frames inside the stream rather than an HTTP error body (see below).

Streaming endpoints (SSE)

Eight routes stream a Clawboo-shaped Server-Sent Events response, not request/response. (The four MCP session channels at GET /api/mcp/* are SSE too, but they carry MCP JSON-RPC rather than a Clawboo event catalog; see Tools & MCP.) They set Content-Type: text/event-stream, flush headers, and emit data: <json>\n\n frames (the three live-tail routes prefix each persisted row with an id: cursor line, and the two chat streams add named event: frames on top). They are documented with an event-stream catalog (event type → payload) on their resource pages, not with a response body:

Route index

148 routes across 13 resource groups: 64 GET · 60 POST · 11 DELETE · 8 PATCH · 5 PUT. Each group has a dedicated reference page.
The route counts above sum to 148, matching the router exactly; every registered route belongs to one resource page. The “Misc” page is the catch-all for the smaller UI-backing resources that do not warrant their own page.

See also

  • Settings & health API, the one liveness surface that works with the Gateway down
  • System API, OpenClaw install/configure/gateway lifecycle (SSE), plus Clawboo’s own self-version and self-update
  • Runtimes API, the gold-standard per-route reference for this group
  • Gateway & events, the /api/gateway/ws proxy + the Bridge→Policy→Handler pipeline
  • Security, access gate, device auth, redaction, exposing safely
  • Environment variables, STUDIO_ACCESS_TOKEN, CLAWBOO_API_PORT*, HOST
Last modified on August 8, 2026