# API keys and scopes

> The two kinds of key, the scopes available to each, and what every scope unlocks.

Mint keys at **Dashboard → Settings → API keys & MCP**
(`/dashboard/settings/developer`). The plaintext is shown once; Blueprintr
stores only a hash of it.

## Two kinds of key

The prefix tells you which. They are separate credentials: they reach
different servers and are offered different scopes.

![blueprint:josh/two-keys-two-servers](https://blueprintr.io/embed/josh/two-keys-two-servers#h=540)

## Personal key scopes

Ten, and every one of them is optional.

| Scope | Unlocks | Tools |
| --- | --- | ---: |
| `read:blueprints` | Blueprints, portfolios, strata, diagram tabs, templates, tags, analytics, change requests | 20 |
| `read:vellums` | Standalone vellum diagrams, including `docYaml` | 2 |
| `read:foliums` | Foliums, their pages and their strata | 4 |
| `read:organization` | The orgs and teams you belong to, so an agent can file work in the right workspace | 4 |
| `search` | Search across everything the key can already see | 1 |
| `write:blueprints` | Create and update your own drafts, publish them, build strata and diagram tabs, manage portfolios | 22 |
| `write:vellums` | Create and update vellums you can edit | 6 |
| `write:foliums` | Create and update foliums, pages and folium strata | 7 |
| `write:sharing` | Narrow a blueprint's audience | 2 |
| `write:review` | Submit your own work into a governance workflow | 3 |

`write:sharing` is monotonic. Its two tools, `restrict_blueprint_audience` and
`raise_blueprint_classification`, can only ever make content *more* private.
No tool widens an audience, so a leaked key cannot publish your private work.

There is no `write:organization`. Membership and roles stay out of scope
permanently, and tenant cosmetics are excluded because a mistake there reaches
every user in the organisation.

## Organisation key scopes

Five. Names shared with the personal list mean different things here.

| Scope | Unlocks |
| --- | --- |
| `read:blueprints` | Public blueprints belonging to the organisation |
| `read:docs` | Public folium pages |
| `read:private-docs` | Private folium pages as well, gated to owners and admins at mint time |
| `search` | Search within that scope |
| `mcp` | The host-scoped documentation MCP server, on an org or team subdomain |

Grant `read:private-docs` only where the key needs private pages. It turns a
key that reads your published documentation into one that reads all of it.

## Choosing scopes

New keys default to read-only, and scopes **cannot be edited after creation**.
Minting a new key is the only way to change them.

> [!IMPORTANT]
> A personal key with a write scope acts as you, with your access. Store it in
> a secret manager, never in source control, and never in a command-line flag:
> argv is visible in `ps` and lands in shell history. Pass it through an
> environment variable or a file instead.

## Limits

| | |
| --- | ---: |
| Active personal keys per user | 10 |
| Key creations per hour | 10 |
| Requests per key, per 5 minutes | 600 |
| Requests per IP, per 5 minutes | 60 |
| Write tool calls per key, per 5 minutes | 40 |

## Checking a key

`whoami` needs no scope. It reports whether the key is live and what it can
do, in one call:

```bash
curl -fsS https://blueprintr.io/api/mcp \
  -H "Authorization: Bearer $BLUEPRINTR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"jsonrpc":"2.0","id":1,"method":"tools/call",
       "params":{"name":"whoami","arguments":{}}}' \
  | jq -r '.result.content[0].text | fromjson | {username, plan, scopes}'
```

A live personal key returns your handle, plan and its scopes. If it returns
the public documentation tool set instead, the key was not accepted: it is
missing, malformed or revoked.

## Rotating

Use one key per client, so a single connection can be revoked without breaking
the others. Revocation takes effect on the next request.

Rotate in this order: mint the replacement, deploy it, confirm with `whoami`,
then revoke the old one.
