Authentication
Every request resolves to exactly one workspace — you can never read or mutate assets outside the workspace your credential is bound to. There are three ways to authenticate.
A Netlify Identity cookie (nf_jwt),
used by the first-party dashboard. Sign-in is invite-only — your email has to be on the approved
safelist. The first approved login auto-creates your profile and a personal workspace.
Send Authorization: Bearer csk_....
A key is bound to one workspace, which scopes every request it makes, and to the
services it was created with. Keys are shown in full exactly
once, at creation; only a prefix is shown afterward. Never put a key in client-side code — keep it in
an environment variable, server-side only.
A key is scoped to the services (tools) chosen at
creation, on top of its bound workspace. Today's services:
assets
(uploads, assets, and serve URLs), transcription (audio transcription and stored transcripts), realtime (mint live voice sessions), diagrams (publish and serve agent-authored diagrams), artifacts (validate, publish, and serve agent-composed interactive pages), and charts (preview, publish, and serve data-driven charts). GET /api/v1/me and GET /api/v1/services need no service — any key can call them. Keys created before services shipped were backfilled to the
services that existed then (assets, transcription) — realtime, diagrams, artifacts, and charts shipped later, so no existing key gained any of them automatically.
A key used outside its services gets 403 with a body naming the missing service and what the key IS enabled for:
A key's services and name can be edited any time from its page in the dashboard
(app.cubster.dev/account/keys/<id>) — the secret is shown once, at creation, and never again, but the
services are not fixed at creation. A key removed from a service gets a 403 naming that service on its next call. Manage keys and see the full service registry at app.cubster.dev/account/keys.
A server holding a key mints a short-lived, single-use grant; a third-party browser then uploads one file directly with only that grant — no key, no cookies exposed to the browser.
The approved-users safelist is the waitlist: an email with an "invited" status can sign in;
anything else gets recorded (status "pending") so it can be invited later. A signed-in-but-not-approved
session gets back { isApproved: false, email } from GET /api/v1/me
rather than a hard error, so a client can show a "you're on the list" screen.