Authentication
Every API request authenticates with an API key. Keys are workspace-scoped and carry a set of scopes that bound what they can do.
API keys
Create keys from Settings → API Keys in the console. A key looks like:
gsk_acme_8f2a1c9b7d6e5f4a3b2c1d0e9f8a7b6c
The middle segment is your workspace slug (acme above). It’s part of the key, which is why the Agent API needs no slug in the path — ACP reads it from the key. For the Governance API, the slug you put in the path must match the slug in the key.
Treat keys like passwords. They grant every permission their scopes allow, for the whole workspace. Never commit one or ship it in client-side code — the API is server-to-server.
Making an authenticated request
Send the key as a bearer token:
curl https://api.agenticcontrolplane.com/api/v1/agents \
-H "Authorization: Bearer $ACP_KEY"
The Bearer prefix is optional — a bare Authorization: gsk_… is also accepted — but Bearer is conventional and recommended.
import os, requests
ACP = "https://api.agenticcontrolplane.com"
headers = {"Authorization": f"Bearer {os.environ['ACP_KEY']}"}
r = requests.get(f"{ACP}/api/v1/agents", headers=headers)
r.raise_for_status()
print(r.json()["profiles"])
Scopes
A key carries scopes that bound what it can do. Grant the least a key needs.
| Scope | Grants |
|---|---|
* |
Everything — full read/write across agents and governance. Use for your own automation; avoid handing it out. |
admin.audit.read |
Read the audit log. |
agents.write |
Create and modify agent profiles. |
agents.read |
List and read agent profiles. |
Reading the audit log requires admin.audit.read (or *); a key without it gets 403. Writing governance policy additionally requires that the key was created by an owner or admin of the workspace — scopes bound the key, membership bounds the human behind it.
Human auth. The console authenticates with your session (a Firebase ID token), not a
gsk_key. Some governance endpoints accept either. This reference documents the API-key path — the one you’ll script against.
Base URLs
| Surface | Base |
|---|---|
| Agents | https://api.agenticcontrolplane.com/api/v1/agents |
| Governance | https://api.agenticcontrolplane.com/<workspace>/admin |
There is one production host. To isolate testing, create a separate workspace and a key scoped to it rather than reaching for a sandbox URL.
Errors
Non-2xx responses carry a JSON body with a single error field:
{ "error": "api key lacks admin.audit.read scope" }
| Status | Meaning |
|---|---|
400 |
Malformed request — missing a required field, bad JSON, an invalid since timestamp. |
401 |
Missing, malformed, or revoked key. Check the Authorization header and that the key is still active. |
403 |
Authenticated, but the key’s scopes (or the caller’s role) don’t permit this. |
404 |
The resource — usually an agent profile ID — doesn’t exist in this workspace. |
429 |
Rate limited. Back off and retry (see below). |
500 |
Something failed on our side. Safe to retry idempotent reads. |
Write defensively: branch on the status code, not on string-matching the error text, which is meant for humans and may change.
Rate limits
Mutating governance endpoints are rate limited and return 429 when you exceed the budget. On a 429, back off — exponential with jitter — and retry. Bulk operations (seeding many policies, importing a fleet of agents) should be paced rather than fired in parallel.
Versioning
The Agent API is versioned in its path (/api/v1). Within a major version we add fields but never repurpose or remove them — so tolerate unknown keys in responses and you won’t break on an upgrade. Breaking changes ship under a new version with notice.