API Reference
The Control Zero backend exposes three families of HTTP endpoints:
- SDK endpoints (
/v1/sdk/*) — called by Control Zero SDKs. Authenticated with a project API key (cz_live_*orcz_test_*). - Public API (
/v1/*) — thin, stable surface for programmatic org-level policy management. Authenticated with a project API key. - Dashboard API (
/api/*) — powers the Control Zero dashboard. Authenticated with a first-partycz_sessioncookie (SaaS) or a database-backed JWT session (self-managed). SDK users do not call these directly.
Use the SDK for normal application code. The direct API is useful for custom tooling, CI/CD, and platform integrations.
Base URL
https://api.controlzero.ai
All endpoints are served from this host. There is no /v1 prefix on the base URL itself — individual routes specify their own prefix (/v1/sdk/..., /v1/policies/..., /api/...).
For self-managed deployments, replace the host with your own backend URL.
Authentication
Project API key (SDK + public API)
Endpoints under /v1/sdk/*, /v1/policies*, and /api/scout/* accept a project API key. Keys start with cz_live_ (production) or cz_test_ (test/development).
Two header forms are accepted, either works:
# Preferred
curl -H "X-API-Key: cz_live_..." \
https://api.controlzero.ai/v1/sdk/bootstrap
# Also accepted
curl -H "Authorization: Bearer cz_live_..." \
https://api.controlzero.ai/v1/sdk/bootstrap
A request missing a valid API key returns 401 MISSING_API_KEY. A key that does not start with cz_live_ or cz_test_ returns 401 INVALID_API_KEY_FORMAT. An unknown key returns 401 INVALID_API_KEY.
The backend at api.controlzero.ai accepts X-API-Key or Authorization: Bearer.
The hosted gateway at gateway.controlzero.ai accepts X-ControlZero-API-Key or
Authorization: Bearer instead (to avoid colliding with the upstream provider's
X-Api-Key header, e.g. Anthropic). If you are calling the gateway directly, use
X-ControlZero-API-Key. If you are calling the backend, use X-API-Key.
Scopes
API keys carry scopes (read, write, scout). SDK endpoints require at least read. Mutating public-API endpoints require write. Scout endpoints require scout. A key without the required scope returns 403 INSUFFICIENT_SCOPE.
Dashboard auth (/api/*)
Dashboard endpoints authenticate with a first-party cz_session cookie (SaaS mode) or a JWT session token (self-managed mode). On SaaS, sign-in (email + password or Google) is handled by Control Zero's self-hosted identity service; the frontend then exchanges the identity session for the cz_session cookie. These endpoints are intended for the Control Zero dashboard frontend. SDK users should not call them directly; there is no stable public contract.
Event stream query param
The SSE stream at /api/events/stream also accepts an access_token query parameter, because browsers cannot set custom headers on EventSource. This is the only endpoint that accepts a key via query string.
Request format
- Request bodies must be JSON with
Content-Type: application/json. - Request bodies are capped at 1 MB. Oversized requests return
413 Request Entity Too Large. - Responses are JSON unless otherwise noted (policy bundles are binary
application/octet-stream). - Timestamps are ISO 8601 in UTC.
HTTP status codes
| Code | Meaning |
|---|---|
200 | Success |
201 | Created |
204 | No content (successful delete) |
304 | Not modified (ETag matched) |
400 | Bad request |
401 | Missing or invalid authentication |
403 | Authenticated but missing scope / role |
404 | Resource not found |
413 | Request body too large |
429 | Rate limit exceeded |
500 | Server error |
503 | Feature disabled or dependency unavailable |
Error format
{
"error": {
"code": "INVALID_API_KEY",
"message": "invalid API key"
}
}
Rate limiting
Every authenticated path runs behind a combined IP + API-key rate limiter:
- 1000 requests / minute per source IP (DDoS guard)
- 500 requests / minute per API key (tenant abuse guard)
When the limit is exceeded, the server returns 429 Too Many Requests. Clients should back off with exponential retry. Rate limit state is keyed in an in-memory cache; limits are shared across backend instances.
SDK endpoints (/v1/sdk/*)
All SDK endpoints require a project API key with read scope (plus any per-endpoint scope noted below). They are what the Python and Node SDKs call under the hood.