# Authentication & scopes

How API keys, bearer tokens, scopes, and project restrictions work.

Every request to an authenticated aclipp API endpoint needs an API key. The key identifies the workspace, the principal, and exactly what the request is allowed to do. The generated OpenAPI schema at `/api/v1/openapi.json` is public and does not require a key.

## API keys

Create and revoke keys in [workspace settings](https://app.aclipp.com/settings/api). A key looks like `aclipp_live_...` and is shown in full only once, at creation. Send it as a bearer token on every request:

```
Authorization: Bearer aclipp_live_...
```

The workspace is implied by the key, so it never appears in the URL. Revoking a key takes effect within about a minute.

## Scopes

Every key is granted a set of scopes and can only do what they allow. Scopes follow a `resource:action` pattern:

- `:read` grants read access to a resource.
- `:write` allows creating, updating, and deleting.

| Scope                                  | Grants                                                    |
| -------------------------------------- | --------------------------------------------------------- |
| `projects:read` / `projects:write`     | Read / manage projects                                    |
| `clippings:read` / `clippings:write`   | Read / manage clippings                                   |
| `outlets:read` / `outlets:write`       | Read / manage the workspace outlet catalog                |
| `reports:read` / `reports:write`       | Read / manage reports                                     |
| `dashboards:read` / `dashboards:write` | Read / manage dashboards                                  |
| `analytics:read`                       | Read the analytics catalog and query aggregate analytics  |
| `ai-visibility:read`                   | Read AI visibility chats, source domains, and source URLs |

Grant a key only the scopes it needs. A reporting script, for example, might get `reports:read` and nothing else. A request missing a required scope is rejected with `403 FORBIDDEN`.

## Project restrictions

A key can optionally be restricted to specific projects. A restricted key can only read or write project-owned resources within its project set; anything outside it is treated as not found.

Outlets are workspace-owned rather than project-owned. A project-restricted key must provide one of its allowed project IDs when reading outlets. The outlet catalog remains workspace-wide, while `clippingsCount` is calculated only for that project. Outlet mutations require an unrestricted key.

## Errors

Authentication and authorization failures use the standard error shape:

- `401` — missing, invalid, or revoked key.
- `403` — the key is valid but lacks the required scope.
- `404` — the resource doesn't exist, or it's outside the key's project scope.

See the [API reference](/docs/api-reference) for the required scope on each endpoint.
