# Authentication

> Access keys for agents and scripts, the permissions a key holds, and OAuth for hosted apps such as claude.ai and ChatGPT.

> Index of these docs: https://wavegrain.com/developers/llms.txt

Every request to `https://wavegrain.com/api/mcp` carries a token in the `Authorization: Bearer` header.
A token in the address is never read.
There are two kinds of token.

| Token | Starts with | Who uses it | How you get it |
| --- | --- | --- | --- |
| Access key | `wg_pat_` | Claude Code, Codex, Cursor, n8n, Make, Zapier, your own scripts | Settings, Connect an AI agent |
| OAuth access token | `wg_oat_` | Hosted apps that cannot hold a key, such as claude.ai | The app signs you in to Wavegrain |

## Access keys

- In Wavegrain, open Settings and find Connect an AI agent.
- Name the key, tick its permissions, and pick when it expires: 7, 30, 90 or 365 days.
- Set its daily credit limit: the most it may spend in 24 hours. It starts at 50 credits; 0 means it can never spend.
- Copy the key. It is shown once, and Wavegrain stores only a fingerprint of it.
- Keep it in an environment variable such as `WAVEGRAIN_MCP_TOKEN`, not in a shared config file.

Revoke a key in Settings at any time; it stops working on the next request.

## Permissions

A tool that needs a permission the token does not hold is refused before it runs, with `403` and `WWW-Authenticate: Bearer error="insufficient_scope", scope="..."`.
Every tool's description ends with the permission it needs.

| Permission | What it allows |
| --- | --- |
| `read` | Look at brands, brand briefs, formats, slideshows, the Calendar, image collections, credits and styles. Free. |
| `write` | Change saved work without spending credits: slide text, photos, order, styles, uploads, Calendar slots and exports. |
| `generate` | Spend credits to make brands, slideshows and images. Every paid call names the most it may spend (`maxCredits`). |

Give a key only what it needs.
Leave out `generate` if the agent should never spend credits.

No permission lets an agent post to a social network.
Scheduling puts a slideshow on your Wavegrain Calendar; you approve it in Wavegrain, and Wavegrain posts it.

## OAuth for hosted apps

Hosted apps such as claude.ai cannot store a key, so they sign in with OAuth 2.1 instead.
You add `https://wavegrain.com/api/mcp` as a custom connector, sign in to Wavegrain, and choose the permissions and the daily credit limit on the consent page.

What the app does, for developers who build a client:

1. Calls `https://wavegrain.com/api/mcp` with no token and gets `401` with `WWW-Authenticate: Bearer resource_metadata="https://wavegrain.com/.well-known/oauth-protected-resource/api/mcp"`.
2. Reads that document, then the authorization server metadata at `https://wavegrain.com/.well-known/oauth-authorization-server`.
3. Registers itself at `https://wavegrain.com/oauth/register` (dynamic client registration, public clients only).
4. Sends the user to `https://wavegrain.com/oauth/authorize` with PKCE (`S256`).
5. Exchanges the code at `https://wavegrain.com/oauth/token`. Access tokens last 60 minutes; refresh tokens rotate on each use.
6. Revokes at `https://wavegrain.com/oauth/revoke`. Revoking either token disconnects the app.

The user sees and can disconnect each connected app in Settings.
This sign-in path is built and tested against our own test client; we have not yet tested it with every hosted app, so tell us at support@wavegrain.com if one fails.
The [API reference](/developers/api-reference) documents each of these endpoints.
