Authentication
Exactly one credential kind per request. Mixing them is not additive and is not supported.
Authorization: Bearer <access_token | service_key>X-Api-Key: <service_key> alternative to Authorization for keysThe three credentials
Section titled “The three credentials”Access token
Section titled “Access token”A user’s session. It comes from POST /auth/login — possibly via an MFA challenge — and is
rotated with POST /auth/refresh.
Refresh rotates the token family. A client that races two refreshes will have one of them rejected; retry with the token the successful call returned, not the one you sent.
A session here is a device family: revoking one logs out one device, and revoke-others
logs out the rest while keeping the caller signed in.
Service key
Section titled “Service key”A long-lived credential for a backend. Issued once by POST /service-keys, and its plaintext
is never shown again — not by the list endpoint, not by the detail endpoint, not by anything.
Rotating a key issues a new plaintext and retires the old hash immediately.
This is the credential a server-to-server integration should hold. Send it as X-Api-Key, or
as a bearer token; the two are equivalent.
Stream token
Section titled “Stream token”Short-lived, from POST /runs/{run_id}/stream-token, and it authenticates a socket and
nothing else — one run, for a short window. On the WebSocket it travels in the first frame
rather than in the URL, which keeps it out of proxy logs and browser history. See
Streaming a run.
Other headers the contract reads
Section titled “Other headers the contract reads”| Header | What it does |
|---|---|
X-Acting-User: <user_id> | Delegation — act as another user. Admin and above. |
X-View-Organization / X-View-Workspace | Operator narrowing. |
Idempotency-Key: <key> | On any POST that creates or triggers work. |
If-Match: <etag> | On PATCH/PUT of an ETag’d resource. |
X-Correlation-Id: <uuid> | Accepted from trusted sources; always echoed. |
Every response carries X-Correlation-Id and X-Request-Duration-Ms. Quote the correlation
id in a support request — it is how an operator finds your request in the logs, and it turns
“it was slow around four” into one row.
Role floors
Section titled “Role floors”Every endpoint declares the lowest role that may call it. The floors, in order: viewer,
member, admin, owner, operator.
Two things this does not mean:
A floor is a minimum, not a grant. A floor of member means a viewer is refused with
403. It does not mean a member sees every row — scope filtering is applied on top of the
floor, always.
Another tenant’s resource answers 404, never 403. A 403 would confirm that the id
exists. The one real 403 is a resource you can see but may not modify.
Operator-only operations are excluded from this documentation. They are in the OpenAPI document your deployment serves.
Public operations
Section titled “Public operations”Some operations take no platform credential at all: the ingress endpoints and the health probes. Each authenticates by its own mechanism — a webhook signature, a channel’s shared token — rather than by anything on this page. Every such operation is marked in the reference.
Where to next
Section titled “Where to next”- Conventions — the rules that hold across every authenticated endpoint.
- Errors — including what a
401and a403actually look like.