> ## Documentation Index
> Fetch the complete documentation index at: https://docs.reinx.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Limits & Boundaries

> What an organization API key can never do — and how to read a 403

This page answers "why did my key get a `403` — or a `401`?" There are three **authorization**
`403`s — scope, binding rung, target — each with its own fix, and they are the focus of this page.
But a reachable route can 403 for other reasons that are NOT about your key's authorization —
`KYC_REQUIRED` or `PLAN_LIMIT_REACHED` on create, `MACHINE_ARCHIVE_DENIED` on archive, `ORG_CLOSED`
on a terminally-closed org — and those are org-state or evidence failures, not "widen the key"
signals. A `401`, meanwhile, usually means the route is **session-only** and never open to keys at
all. Do not rotate or widen a key over any of these — read the specific code first.

## The three `403` gates — and the `401` boundary

On a route an organization key **can** reach, three checks run in order, each with its own
`403`:

| Code                        | Meaning                                                                        | Fix                                                      |
| --------------------------- | ------------------------------------------------------------------------------ | -------------------------------------------------------- |
| `403 INSUFFICIENT_SCOPE`    | The key lacks the scope for this **kind** of action                            | Mint a new key with the scope — scopes are fixed at mint |
| `403 BINDING_NOT_ALLOWED`   | The key's binding **rung** cannot call this route at all                       | Use a key bound higher up (see the fence below)          |
| `403 OUT_OF_SCOPE` or `404` | The rung may call the route, but the **target** is outside the key's container | Act on a target inside the binding, or use a wider key   |

The middle two are easy to confuse and need different fixes. `BINDING_NOT_ALLOWED` means
*this route is above your rung* — a wider key fixes it. `OUT_OF_SCOPE` means *you may call this
route, just not on that object* — a wider key or a different target fixes it. Some routes
return `404` instead of `OUT_OF_SCOPE`, deliberately: for a resource your key cannot see, "not
found" and "not yours" are the same answer, and distinguishing them would leak that it exists.

<Warning>
  **The never-machine-reachable routes below are a `401`, not a fourth `403`.** Funding, key
  management, memberships, billing, org settings, and org/account deletion are **session-only** —
  they do not recognise an organization key at all, so presenting one is rejected at authentication
  as an invalid token (`401`), before any scope or binding gate runs.

  Crucially, that `401` is **not diagnostic of your key**: because these routes never run org-key
  verification, a **valid** key and a **revoked or malformed** one get the *same* `401` here. So the
  code proves only "this route is session-only" — it does **not** prove your key is good, and it does
  **not** prove it is bad. Do not conclude either from it. If you actually need to know whether a key
  is still valid, call a **management endpoint** (e.g. `GET /v1/agents`): a `2xx`/`403` there means
  the key authenticated; a `401` there means the key itself is bad and should be rotated.
</Warning>

## Never machine-reachable

The following are unreachable for **every** organization key, regardless of scopes or binding —
not a setting that can be relaxed for your integration:

* **Moving money out** — withdrawals, transfers to external destinations, treasury movement.
* **Approving payments** — approval is where a human decides; a bearer token cannot stand in.
* **Minting or revoking API keys** — with one exception: the single bundled worker key issued
  inside a machine agent-create.
* **Memberships and roles** — inviting, removing, or re-scoping humans.
* **Billing and plan** — subscription, payment method, tier.
* **Organization settings and security.**
* **The organization envelope** — the org spend cap and org approval rules
  (`/v1/org/budget`, `/v1/org/approval-rules`). Session-only. Reading them needs an Owner or
  Admin session; changing them is Owner-only and step-up gated. No key reaches either.
* **Deleting an organization or account.**

Two different mechanisms enforce that list, and the distinction matters if you are wondering
whether a capability might appear later:

* **Most have no scope at all** — there is simply nothing to grant.
* **A few scope strings exist but are not grantable.** Requesting one when minting a key is
  rejected with `400 INVALID_SCOPE`, which lists the grantable set. The notable one is
  `transactions:approve`: it is held back pending its own security review, because approving a
  payment is the second fence — the point where a human decides — and handing that to a bearer
  token is a different risk class from provisioning. Treat any non-grantable scope as
  unavailable rather than as coming soon; **only the scopes the mint UI offers are real.**

<Note>
  The organization envelope is the one that surprises integrators. Project and team budgets *are*
  machine-writable, so `PUT /v1/org/budget` looks like it should be too. It is not: the org cap is
  the ceiling every key operates beneath, and a key that could raise its own ceiling would make the
  whole model decorative. Even a human Admin cannot move it — Owner only.
</Note>

## The recursive fence

A binding mirrors a human role rung, and a key can never exceed the human it mirrors:

| Binding      | Mirrors         | Can create agents       |
| ------------ | --------------- | ----------------------- |
| Organization | Admin           | Yes                     |
| Project      | Project Manager | Yes, inside the project |
| Team         | Team Lead       | **No**                  |

Team-bound keys cannot create agents because human Team Leads cannot either. If you need a
team-scoped orchestrator that spawns agents, the answer is not a wider key — it is widening the
human Team Lead role first, so machine and human stay in parity.

**A binding also never reaches the route that edits its own container's envelope.** A
project-bound key cannot set its own project's budget; that route requires an organization
binding. Same for team-bound keys and their own team budget. The rule is uniform: the envelope
you operate under is always set one rung above you.

## Archiving is not a normal write

`agents:write` lets a key create, pause, and resume freely. Archiving is different — it is
terminal, so a key may archive only a **zombie of its own making**: an agent that key lineage
created, whose bundled-key re-delivery window has closed, that has never authenticated and has
no activity, holds a zero balance, **and whose keys no human has ever minted or revoked** (any
human key management — a mint or a revoke — permanently disqualifies the machine path; the agent
is a human's to archive even if every other condition holds).

Anything else returns `403 MACHINE_ARCHIVE_DENIED` and a human must archive from the dashboard.

<Warning>
  **`MACHINE_ARCHIVE_DENIED` always means escalate to a human — including the balance case.** A
  non-zero wallet balance produces the same code ("archiving would strand them"), and it is tempting
  to read that as "sweep and retry." Your key cannot — money-out is machine-denied (above). A
  *human* sweep then normally writes an outbound-transfer event, which trips the "never used, zero
  activity" evidence gate — so the machine path may well stay closed afterward anyway. Hand the
  whole thing to a human rather than retrying autonomously, and never branch on the message text (it
  can change; the code cannot).
</Warning>

See the [management band](/mcp-tools/management-band#archiving-why-your-key-usually-cannot) for
the two recoverable `409`s and their replay sequences.

## Quotas

Creation is capped independently of rate limits:

* **100 creations/day** by default, shared across agents, projects, and teams.
* Resets at **00:00 UTC** — not a rolling window. `429 CREATE_QUOTA_EXHAUSTED` will not clear
  by backing off.
* **Fail-closed**: if the quota store is briefly unreachable you get `503 QUOTA_UNAVAILABLE`
  rather than an un-counted create. Retry with the same idempotency key. (Don't confuse this
  with `503 CREATE_RETRYABLE`, which is agent-create saga contention — a different condition,
  and one that project and team creates never emit.)
* **Charged per admitted attempt, never refunded.** A create that clears the quota and then
  fails during provisioning still consumed a unit. **Retrying the same key + payload within the
  same UTC day is never re-charged**, complete or not; only resuming an incomplete attempt
  **after 00:00 UTC** costs another unit.
* Rotating a key does **not** reset the counter — the quota follows the key's lineage.

## Other terminal states

| Code                       | Meaning                                                                                    |
| -------------------------- | ------------------------------------------------------------------------------------------ |
| `403 ORG_CLOSED` (REST)    | The organization is terminally closed. Not a credential problem — do not re-mint or rotate |
| `503 ORG_KEYS_UNAVAILABLE` | Organization-key auth is not configured in this environment. Retryable                     |

<Warning>
  **On MCP, a closed organization returns `401`, not `403 ORG_CLOSED`.** The MCP endpoint
  deliberately collapses every auth failure — unknown, revoked, malformed, closed org — into one
  indistinguishable `401`, because a distinct code at an unauthenticated front door would confirm
  to any caller that a presented key is otherwise *valid*. REST can afford the specific code
  because its check runs later, already authenticated.

  So on MCP, do not read a `401` as "rotate the key." Confirm the organization's status over
  REST (or with a human) before re-minting anything.
</Warning>
