API overview
The control-plane API is versioned under /v1/* on your API host
(hosted default: <api-origin>; self-hosted: whatever you
front the apps/api service with).
Machine-readable spec
Section titled “Machine-readable spec”- OpenAPI —
GET /openapi.jsonreturns the current spec, generated from the running Fastify route schemas. Feed it to your OpenAPI tooling, or ingest it into another Carbon runtime. - Interactive docs —
GET /docsserves a Scalar-powered browser for the same spec: try requests, see schemas, copy curl.
Authenticating
Section titled “Authenticating”Carbon accepts three auth mechanisms, in this order of preference for programmatic callers:
1. API key — recommended for CLI, CI, servers
Section titled “1. API key — recommended for CLI, CI, servers”curl -H "x-carbon-key: ck_live_…" <api-origin>/v1/mex-carbon-key is the canonical header. The API also accepts
x-carbon-api-key and Authorization: Bearer ck_live_... for
generated clients and environments with fixed auth-header conventions.
Send only one API-key carrier per request.
Keys are minted per-org and carry a scope (read, write, admin).
Rotate them from the dashboard or via POST /v1/api-keys. See
Compliance export for how key lifecycle
data shows up in audit bundles.
2. Session bearer — for dashboard-issued tokens
Section titled “2. Session bearer — for dashboard-issued tokens”The Better Auth session token, sent as a Bearer on the
Authorization header. Used by the dashboard’s own requests to the
API host when it isn’t same-origin.
curl -H "Authorization: Bearer <session-token>" <api-origin>/v1/me3. Session cookie — for same-origin browser calls
Section titled “3. Session cookie — for same-origin browser calls”When the dashboard and API share a public origin, the Better Auth session cookie is sent automatically. Nothing to configure on the caller side; the API validates it exactly the same way as the bearer form.
Scopes
Section titled “Scopes”Every route declares a required scope. The three that matter:
read— GETs, list endpointswrite— mutations that don’t affect billing or identityadmin— usage, exports, api-key rotation, SSO/SCIM configuration
carbon whoami prints the scopes attached to your current key so you
can tell what a call will be allowed to do before you make it.
Rate limits and idempotency
Section titled “Rate limits and idempotency”- Every mutation route accepts an
Idempotency-Keyheader; a repeated key returns the previously stored response for 24 hours. - Rate limits are per-org, keyed off the API key or session. When
Redis is unreachable the API degrades to an in-memory bucket —
watch for
redis.unreachablein the log if numbers look off.