The two API-key types are not interchangeable and never overlap. An agent key can spend
but cannot create or reconfigure agents. An organization key can create and reconfigure
agents but can never move money. That separation is structural, not a setting.
An organization key is recognised only on the management endpoints — the routes that compose
requireOrgOrKey (agent read/write, transactions read, audit read, project/team create + budget +
approval rules). It is not a general /v1/* credential: money-out, funding, bank-linking, and
key-management routes require a human dashboard session and reject an org key as an invalid token.
The exact list is the management endpoint matrix (and its REST
equivalents); anything outside it is a 401, not a scope error.Agent API keys
Keys are minted per agent, use thesk_reinx_live_ prefix, and are sent as a Bearer token:
- Shown once at creation — only a hash is stored. If lost, revoke and mint a new one.
- One active key per agent. Revocation propagates in seconds.
- Keys can be scoped to a subset of MCP tools at creation.
- An invalid or revoked key returns
401. Archiving an agent revokes its key, so an archived agent’s requests also return401. A paused agent keeps its key and returns403 AGENT_PAUSED.
Organization API keys
An organization key is a machine principal — it has no human identity behind it. Mint one in Settings → Organization → API Keys (minting requires step-up re-verification; that ceremony is what authorizes the key, so requests carrying it are never re-challenged).1. Scopes — what kind of action
Six scopes are grantable at mint:
Write scopes cover their own preconditions. These reads require the write scope, not
the matching read scope, because each is a write-precondition — it returns the
version
token the follow-up write needs (a full-replacement PUT for the project/team envelopes; a
partial PATCH for the agent budget-policy, which leaves omitted fields unchanged):
GET /v1/projects/:id/budgetand/approval-rules→projects:writeGET /v1/teams/:id/budgetand/approval-rules→teams:writeGET /v1/agents/:id/budget-policy→agents:write
agents:write key is self-sufficient for the read-modify-write loop; it does not also
need agents:read.
2. Binding — where the action may land
Every key is bound to a container at mint: the organization, a single project, or a single team. The binding filters every read and gates every write.
A binding never reaches the route that edits its own container’s envelope. A
project-bound key cannot raise its own project’s budget cap, and a team-bound key cannot
raise its own team’s. That route lives one rung up, by design — a key must not be able to
widen the ceiling it operates under. Attempting it returns
403 BINDING_NOT_ALLOWED.
Team-bound keys cannot create agents because human Team Leads cannot either; a machine never
exceeds the human rung it mirrors.
Read the full model — including everything an organization key can never do regardless of scopes
— on Organization key limits and boundaries.
Base URL
/v1/. Breaking changes will be introduced under /v2/ without disrupting existing integrations.
Rate limits
Per-organization request ceiling, by plan:
MCP has its own, lower ceiling — 60 / 600 / 3,000 per minute for Free / Pro / Enterprise.
No single field is present on every
429 — not retry_after_seconds, not retry-after, not
even a stable error code. Which limiter tripped decides the shape, so branch on the source and
treat every field as optional:
The last row is not an HTTP
429. The other MCP rows (gateway L2, pre-auth IP) reject at the
transport and return an actual HTTP 429. But when a management tool’s downstream REST call is
throttled, the tool has already dispatched — the proxy wraps the upstream limit as an MCP tool
result (isError: true) and the outer JSON-RPC HTTP response stays 200. So for management
tools you cannot detect a throttle from the HTTP status; parse the relayed error /
retry_after_seconds out of the tool-result body instead.x-ratelimit-reset is seconds remaining on REST and a Unix epoch on MCP.
Daily creation quota
Every organization key carries a daily quota on resource creation — agents, projects, and teams share one counter. Default 100/day, resetting at 00:00 UTC (not on a rolling window).- Exhaustion returns
429 CREATE_QUOTA_EXHAUSTED— with noretry-afterheader and noretry_after_seconds, because there is no short window to wait out. Backing off will not clear it; it clears at 00:00 UTC. Do not feed this429into a generic rate-limit retry loop. - If the quota store is unreachable you get
503 QUOTA_UNAVAILABLE— safe to retry. The quota is deliberately fail-closed, so it denies rather than admits. - The quota is charged per admitted attempt, not per success, and is never refunded. A create that passes the quota and then fails during provisioning has still consumed a unit. Retries within the same UTC day are never re-charged — same key, same payload, complete or not, the attempt marker dedupes it. The one case that costs another unit is resuming an incomplete attempt after 00:00 UTC, because the marker is day-scoped.
- Rotating a key does not reset the counter — it follows the key’s lineage.
Errors
Errors use a flat envelope:error is a stable machine-readable code and message is
human-readable and may change — branch on error. Two responses do not follow it (both noted
above): the REST pre-auth IP limiter’s 429 puts the human string "Too Many Requests" in
error, and request-validation failures put the stable code in code (with error set to
"Bad Request"). So detect rate limiting from the 429 status, and read validation codes from
code — never assume error is a stable code on those two. See the
error reference for the full list, including the organization-key codes
(INSUFFICIENT_SCOPE, BINDING_NOT_ALLOWED, VERSION_CONFLICT, and others).