Authentication
Send your token as either header - they are equivalent:
X-Auth-Token: rtfc_…
Authorization: Bearer rtfc_…Every endpoint requires one. There are no anonymous endpoints, and that is enforced by a gate in front of every route rather than per-handler, so it cannot be forgotten on a new endpoint.
Three kinds of credential
| What it is | Who uses it | |
|---|---|---|
Personal Access Token (rtfc_…) | Long-lived API key, created in the dashboard or minted for an end user | Your server |
| Session JWT | 24h token from POST /v1/auth/token | Interactive clients that log in with a password |
| Stream token | 5-minute, SSE-only, from POST /v1/stream/token | Browsers, which cannot send headers on EventSource |
A stream token is deliberately useless for anything else: it is rejected as a general bearer token, so leaking one into a URL or a log exposes a read of one stream for five minutes, not your account.
Scopes
A token can be restricted to what it actually needs:
| Scope | Grants |
|---|---|
read | GET anything you can see |
write | Create and modify debates, claims, votes, sessions, media |
stream | Open SSE connections |
provision | Create and delete end-user accounts |
admin | Administrative endpoints (implies all others) |
curl -sX POST $RTFC/tokens \
-H "X-Auth-Token: $TOKEN" -H 'Content-Type: application/json' \
-d '{"name": "read-only dashboard", "scopes": ["read"]}'The plaintext token is returned exactly once. Afterwards you only ever see a prefix.
A token created with no scopes has full access. That is the default, and it is what every token issued before scopes existed has - so nothing broke when scopes arrived. Restrict deliberately; you will not be restricted by accident.
Calling something outside your scopes returns 403:
{"error": {"code": "insufficient_scope",
"message": "This token lacks the 'write' scope",
"details": {"required_scope": "write", "token_scopes": ["read"]}}}Which to use
- Building a server-side integration? A PAT with
read+write. - Building a product with your own users? A
provision-scoped PAT for your
backend, and a separate per-user PAT for each of their accounts. See Multi-tenancy - this matters more than it sounds.
- Rendering results in a browser? Mint a stream token server-side and pass
that to the browser. Never ship a PAT to a client.
Rotating and revoking
GET /v1/tokens lists yours; DELETE /v1/tokens/{id} revokes one, effective immediately. Revoke rather than delete the user when a key leaks - the account and its debates survive.