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

# Scopes

API key permissions. Coarse (read/write/admin) or granular per-resource (kb:write, agent:read).

# Scopes

API keys carry an array of scope strings. The server resolves whether a
key has access to an action via a small hierarchy:

```
admin            grants everything
write            grants any *:read and *:write (not *:admin)
read             grants any *:read

<resource>:admin grants :read + :write + :admin on that resource
<resource>:write grants :read + :write on that resource
<resource>:read  grants :read only
```

A scope check **succeeds if any** granted scope covers the requested
scope.

## Resources

| Resource | Scope prefix | API tab |
|----------|--------------|---------|
| Conversations | `conversations:*` | [Conversations](/api/conversations) |
| Messages | `messages:*` | [Messages](/api/messages) |
| Contacts | `contacts:*` | [Contacts](/api/contacts) |
| Knowledge Base | `kb:*` | [Knowledge Base](/api/kb/articles) |
| Agent | `agent:*` | [Agent](/api/agent/status) |
| Widget | `widget:*` | [Widget](/api/widget/config) |
| Integrations | `integrations:*` | [Integrations](/api/integrations/list) |
| Forms | `forms:*` | [Forms](/api/forms-and-beacons) |
| Beacons | `beacons:*` | [Beacons](/api/forms-and-beacons) |
| Webhooks | `webhooks:*` | [Webhooks](/api/webhooks) |
| Projects | `projects:*` | [Projects](/api/projects/list) |
| Analytics | `analytics:*` | (dashboard-only) |
| Audit | `audit:*` | (dashboard-only) |

## Method → required scope

The v1 surface enforces a method-based default plus per-route overrides.
The default rule, applied via `requireApiKey`:

| HTTP method | Required (coarse) |
|-------------|-------------------|
| `GET`, `HEAD` | `read` |
| `POST`, `PATCH`, `PUT`, `DELETE` | `write` |

Specific routes also require their resource-scoped verb. So `PATCH
/v1/projects/.../kb/articles/...` needs **either**:

- `write` (or `admin`) coarse — old broad keys, AND
- `kb:write` (or `kb:admin`) granular — new least-privilege keys.

In practice: a key with `["kb:write"]` works. A key with `["read"]`
gets `INSUFFICIENT_SCOPE`.

## Destructive operations

A few routes are gated on `<resource>:admin` (or coarse `admin`):

| Route | Required |
|-------|----------|
| `DELETE /v1/orgs/:orgId/projects/:projectId` | `projects:admin` |

Most `DELETE`s require `<resource>:write`. Project deletion is the
notable exception because it's destructive and cascades.

## Recipes

### Least-privilege key for an AI that drafts KB articles

```bash
rogeriq keys create kb-bot --scopes kb:write,conversations:read
```

The agent can: search KB, list articles, create / update / publish KB
articles, read conversations to pull context. It **cannot**: send
replies, change agent config, modify the widget, manage integrations.

### Read-only metrics scraper

```bash
rogeriq keys create metrics-reader --scopes read
```

Or fully granular:

```bash
rogeriq keys create metrics-reader \
  --scopes conversations:read,contacts:read,analytics:read
```

### Full-access ops key (CI pipelines)

```bash
rogeriq keys create ops-ci --scopes admin
```

Use sparingly. Prefer scoped keys where possible.

## Migration from coarse to granular

You don't have to migrate. Coarse `read` / `write` / `admin` continue to
work everywhere. Granular scopes are additive — issue new keys with
narrower scopes as you tighten security.

The dashboard's API Keys page shows both forms inline and lets you
update scopes in place.