Skip to content
UseAgent star-knot markUseAgent
Esc
navigateopen⌘Jpreview
On this page

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/runs and POST /api/skills/:id/run accept an Idempotency-Key header, so a retried command replays instead of duplicating work (a reused key against a different payload is 409 idempotency_key_reused).
  • Release compatibility. Every /api/* response carries x-useagent-release-fingerprint (run-events-v1:<commit>) and x-useagent-api-compat (run-events-v1). A client may send x-useagent-client-release; a mutating request (POST, PUT, PATCH, DELETE) with an incompatible value is rejected 409 { "error": "frontend_release_mismatch", "release" }. A request is compatible when it sends no client header, its value matches exactly, or the server is a :dev build.
  • Server-owned fields. Tenant identity and provenance (org_id, user_id, origin) are set server-side. POST /api/runs rejects a client-supplied origin with 400.

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

Was this page helpful?