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

# Authentication

> Sessions, API keys, MCP OAuth, and the permission each route checks.

Every pack, evaluation, dataset, and webhook belongs to one user. The server takes `userId` from the credential. It does not take it from the body.

| Caller | Credential |
| - | - |
| App | Better Auth session, from email and password sign-in |
| REST under `/api`, except auth routes | API key |
| `POST /api/webhooks/inbound` | API key |
| MCP at `{origin}/mcp` | OAuth access token |
| Completion POST to your URL | HMAC, not a caller credential |

If a request to a product route includes an API key, the session is not used.

## API keys

Create, rotate, and revoke keys on the Integrations page. There is no `/api/keys` route. The secret is shown once, in the create dialog. After you dismiss it, only the name, prefix, created time, and last-used time remain.

Send the secret on each request:

```bash theme={null}
curl https://judged.systems/api/packs \
  -H "x-api-key: $JUDGED_API_KEY"
```

`Authorization: Bearer $JUDGED_API_KEY` is the same key. `POST /api/judge` and `POST /api/webhooks/inbound` require a key. A session cookie on those two routes is `401`.

## Permissions

A key is checked per route. A missing permission is `403` with `missing permission {resource}:{action}`.

| Permission | Allows |
| - | - |
| `packs:read` | List and read packs, datasets, webhook endpoints, and deliveries |
| `packs:write` | Create and edit packs, datasets, and the completion endpoint |
| `judgments:run` | `POST /api/judge` and the inbound webhook |
| `judgments:read` | Evaluations, reviews, and `GET /api/stats` |
| `simulations:run` | Start and read simulations |
| `labels:write` | Write and delete labels |

A signed-in session has every permission above. An MCP OAuth token uses that same set. A new API key is created with that same default set.

## MCP OAuth

An MCP client opens `{origin}/mcp`. The client is sent to `/login` if needed, then to `/consent` to approve or deny. An API key is not accepted on `/mcp`. See [MCP](/docs/guides/mcp).

## Completion signatures

The completion secret is separate from the API key. It is returned once when you save `POST /api/webhook-endpoints`. Verify `X-Judged-Signature` over the raw body. See [Webhooks](/docs/guides/webhooks).


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.