API reference
The HTTP surface the frontend and integrations call - the auth model, release-compatibility headers, streaming endpoints, and how the reference is organized.
Every product API lives under /api. The browser reaches it through the Next
rewrite (/api/* proxies to the backend); integrations call the backend
directly. This reference is generated from the mounted route files and documents
only behavior that exists in the code today.
Paths below use :param for path parameters.
Auth model
Authentication is a better-auth session, mounted at
/api/auth/* (email/password plus the organization plugin). The browser carries
the session as a cookie; CORS runs with credentials: true so a direct
cross-origin call from the frontend origin still sends it.
Tenancy is server-resolved, never client-supplied. A request is scoped to the
session’s active organization (falling back to the user’s first membership). The
universal adapter runs this for every /api/* path that is not explicitly public,
so a new router is protected by default.
| Scope | Meaning | Failure |
|---|---|---|
| org-session | The default. Scoped to the session’s org + user. | 401 unauthorized when anonymous and dev-org access is off; 403 no_organization when the user belongs to no org. |
| user-scoped | org-session plus a real authenticated user (no dev-org fallback user). | 403 user_required |
| org-admin | org-session plus an owner/admin member role. |
403 organization_admin_required |
| public | Bypasses org scoping; self-authenticates (e.g. Slack signature) or is secret-free. | per route |
In local development, ALLOW_DEV_ORG lets an unauthenticated request resolve to
the seeded dev org so every API stays usable without login. Turning it off
(production) makes every domain route 401 until a session is present. See Auth
and organizations.
API-key bearer lane
A request carrying Authorization: Bearer uak_... is authenticated against a
stored key hash and gated by a deny-by-default allowlist: a valid key reaches
only run dispatch and read paths, and an unknown, revoked, or off-allowlist call
is 401. A request without that header passes straight through to the session
lane untouched. A bearer key can never mint or revoke keys - those routes are
session-only (403 session_required). See API keys.
Public paths
These prefixes carry their own auth boundary and are not org-scoped:
GET /api/health,GET /api/config- secret-free liveness and client config./api/auth/*- better-auth’s own login and session endpoints./api/slack/*- Slack request-signature verified (see Slack).
Internal loopback bridges under /api/internal/* (the sandbox gateway, operator
dispatch, and canonicalization lanes) authenticate themselves with short-lived
run capabilities or a loopback secret and are intentionally omitted from this
product reference.
Conventions
- Idempotent commands.
POST /api/runsandPOST /api/skills/:id/runaccept anIdempotency-Keyheader, so a retried command replays instead of duplicating work (a reused key against a different payload is409 idempotency_key_reused). - Release compatibility. Every
/api/*response carriesx-useagent-release-fingerprint(run-events-v1:<commit>) andx-useagent-api-compat(run-events-v1). A client may sendx-useagent-client-release; a mutating request (POST,PUT,PATCH,DELETE) with an incompatible value is rejected409 { "error": "frontend_release_mismatch", "release" }. A request is compatible when it sends no client header, its value matches exactly, or the server is a:devbuild. - Server-owned fields. Tenant identity and provenance (
org_id,user_id,origin) are set server-side.POST /api/runsrejects a client-suppliedoriginwith400.
Streaming
Live updates use server-sent events and WebSockets. See Events and streaming.
| Method | Path | Stream |
|---|---|---|
| GET | /api/runs/changes |
Org-change invalidations (IDs only, no payloads). |
| GET | /api/runs/:rootRunId/thread-events |
Thread-scoped aggregate of every run in a conversation. |
| GET | /api/runs/:id/events |
Per-run trace (legacy rollback path). |
| POST | /api/chat |
Chat completion tokens. |
| WS | /api/runs/:id/terminal |
Sandbox PTY (xterm bridge). |
| WS | /api/desktop-proxy/:threadId/websockify |
noVNC desktop RFB stream. |
Health and config
| Method | Path | Description | Notes |
|---|---|---|---|
| GET | /api/health |
Liveness. | { status: "ok" }. Public. |
| GET | /api/config |
Client capability contract. | auth (google, emailPassword), allowDevOrg, release, readiness-filtered engines and models, sandbox.provider, capabilities (github, slack, memory, toolGateway), artifacts.fidelity. Public. |
The rest of the surface
Runs, threads and realtime
Create and cancel runs, the SSE streams, chat, commands, gateway approvals, and the terminal/live/desktop transports.
Artifacts and uploads
Durable run artifacts, workpiece editing and proposals, and user uploads.
Knowledge and wiki
Knowledge records and search, documents, learning-lane drafts, and repo-wiki generation.
Memory
The Memory Hub: pool search and browse, item correction, the capture outbox, and the recall ledger.
Skills, tasks and projects
Skills and playbooks, GitHub skill import, learning-lane proposals, and the task board.
Automations, secrets and keys
Scheduled automations, org secrets, and API keys.
Platform and integrations
GitHub repos and pulls, provider connections, tenant integrations, Slack ingress, the dashboard, and fleet usage.