Regent has three production hosts and two kinds of key. Sending the wrong kind returns a 401 on every host, so check this table first:
| Host | What it is | Key to send | Where you get it |
|---|---|---|---|
api.regentprotocol.org | Platform API — organizations, agents, mandates, audit, KYC | Org API key rgnt_… | Dashboard → API Keys → Create API key |
control-api.regentprotocol.org | Regent Control decision API — /v1/control/decisions, /complete, receipts, JWKS | Control key rgnt_ctrl_… | Dashboard → Control → Onboarding, or Admin MCP create_control_key |
gw.regentprotocol.org | Cloud Gateway — governed tool calls on the agent’s behalf | Control key rgnt_ctrl_… + X-Agent-Id header | same as above |
An org key on control-api answers 401 {"code":"UNAUTHORIZED","message":"invalid API key"}; a control key on
api.regentprotocol.org answers 401 {"code":"INVALID_API_KEY"}. The two are different secrets scoped to the same
organization — the control key never reaches the platform API and never reads your org’s data.
The rest of this page is about the platform API. Its requests authenticate with a single header:
Authorization: Bearer rgnt_<your-api-key>Or equivalently (some tools prefer the explicit header name):
X-API-Key: rgnt_<your-api-key>Get an API key
From the dashboard: API Keys → Create API Key. The rgnt_… value is shown once.
Smoke test
curl https://api.regentprotocol.org/v1/organizations/<org-id>/agents \
-H "Authorization: Bearer rgnt_..."A 200 with a JSON array (possibly empty) means auth and org scoping are both working.
A 401 means the key is missing/expired. A 403 with code: NOT_MEMBER means the key is for a different org than the one in the path.
Org scoping
Every /v1/organizations/{org_id}/... endpoint requires the org ID to match the org your API key is scoped to. The gateway enforces this server-side — you can’t access another org’s data even if you guess UUIDs.
Rate limits
Current per-IP limits: 30 requests/second (burst 20) on API routes; login and
signup are limited to 5/min. Rate-limited responses return 429 RATE_LIMITED with a
Retry-After header.
Error format
Every non-2xx returns the same shape:
{
"detail": {
"code": "MANDATE_LIMIT_EXCEEDED",
"category": "PER_TX",
"message": "amount exceeds the per-transaction allowance",
"authorization_id": "abc..."
}
}See the error code reference for the full list.