# Authentication for agents

Raconte is driven by an organization API key. One key belongs to one organization, and
every call made with it only ever sees that organization's interviews, invitations and
transcripts. This page is the prose walkthrough; the machine-readable version is the
RFC 9728 document at
[api.raconte.ai/.well-known/oauth-protected-resource](https://api.raconte.ai/.well-known/oauth-protected-resource).

## Discover

Any call to the REST API or the MCP server without a credential answers `401` with a
`WWW-Authenticate` header naming that document, so one failed request is enough to find
this page:

```
WWW-Authenticate: Bearer realm="Raconte API", resource_metadata="https://api.raconte.ai/.well-known/oauth-protected-resource"
```

The document carries an `agent_auth` block: `register_uri` is where a key is created,
`skill` points back at this file, `identity_types_supported` says which flows exist.

## Pick a method

There is one method: a bearer API key, created by a person and handed to you.

Raconte does not run an OAuth authorization server. There is no
`/.well-known/oauth-authorization-server`, no dynamic client registration, and no
`identity_assertion` flow, so nothing to exchange and no `id-jag` token to present. The
metadata document reflects that: `identity_types_supported` is `["anonymous"]` and the
only credential type is `api_key`.

## Register

Registration is human-driven, and self-serve:

1. Sign in at [raconte.ai/login](https://raconte.ai/login). Every organization gets free
   minutes each month, so no payment is needed to start.
2. Open [Settings → API](https://raconte.ai/settings/api), which is the `register_uri`.
3. Create a key. Its full value is shown once, at creation.

An agent cannot mint a key for itself. If you do not have one, ask the person you are
working for to create one at that URL and pass it to you through your own secret store.

## Claim

Nothing to claim: the value shown at creation is the credential. It does not expire and
is not refreshed. Store it as a secret, never in a repository or a prompt log.

## Use the credential

REST, base URL `https://api.raconte.ai`, every path prefixed with `/v1`:

```bash
curl https://api.raconte.ai/v1/interviews \
  -H "Authorization: Bearer $RACONTE_API_KEY"
```

An `x-api-key: $RACONTE_API_KEY` header is accepted as well.

MCP, Streamable HTTP at `https://api.raconte.ai/api/mcp`:

```json
{
  "mcpServers": {
    "raconte": {
      "url": "https://api.raconte.ai/api/mcp",
      "headers": { "Authorization": "Bearer ${RACONTE_API_KEY}" }
    }
  }
}
```

Clients that cannot send headers may pass `?api_key=<key>` instead. The handshake
(`initialize`, `tools/list`) is open, so a client can read the tool catalogue before it
holds a key; every tool call needs one.

CLI and SDK read the key from the `RACONTE_API_KEY` environment variable:

```bash
export RACONTE_API_KEY="your-key"
npx @raconte/cli interviews list
```

## Errors

| Status | Meaning | What to do |
| --- | --- | --- |
| `401` | No key, or an unknown or revoked one | Read `WWW-Authenticate`, then get a key from `register_uri`. Do not retry the same value. |
| `403` | The key is valid but the resource belongs to another organization | Use the key of the organization that owns the interview. |
| `404` | The resource does not exist, or is not visible to this organization | Check the id before assuming it was deleted. |
| `429` | Over the quota of 300 requests per minute per key | Wait for the `Retry-After` delay. `RateLimit-Remaining` and `RateLimit-Reset` are on every response. |

Errors are always JSON, never an HTML page. The shapes are typed in the
[OpenAPI specification](https://raconte.ai/openapi.json).

## Revocation

Delete the key from [Settings → API](https://raconte.ai/settings/api). Revocation takes
effect on the next request: the key stops authenticating and calls answer `401`. Keys are
independent, so revoking one leaves the others working. Rotate by creating the new key
first, switching the client over, then deleting the old one.

## More

- Developer portal: <https://raconte.ai/en/developers>
- MCP documentation: <https://raconte.ai/en/docs/mcp>
- Agent skill for the CLI: <https://raconte.ai/skill.md>
