Authentication
Personal access tokens, OAuth for MCP clients, Supabase access tokens for first-party apps, and what each one can call.
Every request carries one credential, in one header. Which one depends on who is calling:
| You are | Use | How |
|---|---|---|
| a script, a cron job, a CLI, an MCP client without a browser | a personal access token (rsk_…) | Settings → Integrations → API & assistants → Create a token |
| an MCP client with a browser (claude.ai, Claude Desktop, Claude Code) | OAuth, no token at all | add https://www.ressource.social/api/v1/mcp as a connector and sign in; see Connect a client |
| a first-party app (the iOS app) | the user's Supabase access token | sign in with Supabase Auth, send session.access_token |
Personal access tokens
A personal access token is created in Settings by a signed-in person. There is no API to mint one, on purpose: a token that could mint tokens would turn one leak into a permanent one.
- Pick a name, the access (read, or read and write), an expiry (30, 90 or 365 days, or never) and, under Advanced options, a rate limit (30, 60, 120 or 300 requests a minute; 120 by default). None of these can be changed later: mint another token instead.
- The token is shown once, with a copy button. Only a prefix (
rsk_J7WIJTX7…) is kept for display; a lost token cannot be recovered. Revoke it and create a new one. - Revoking is immediate (the next request is a
401) and final. - At most 20 live tokens per person.
- A token acts as its owner: it sees what they see, including their communities, and
what it saves belongs to them.
readcannot write;writeincludesread.
Store it like a password
A token goes in the Authorization header and nowhere else. Never put it in a URL, a
query string or client-side code shipped to browsers.
Send the header
curl -s -H "Authorization: Bearer $TOKEN" "$BASE/me"{
"id": "e8f087c4-…",
"username": "phase4mutqlift",
"full_name": "Phase Four",
"avatar_url": null,
"email": "you@example.com",
"is_private": false,
"auth": { "method": "pat", "scopes": ["read", "write"] }
}GET /me is the cheapest proof that a credential works. auth.method says which one
was accepted (pat, jwt or cookie); auth.scopes is what a token may do, and is
empty for a session (which holds everything its owner does).
That one header is all a request needs. A body is JSON whether or not you send
Content-Type: application/json (send it anyway); uploads are multipart/form-data.
Remember the base URL is the www host: a request to the bare domain is redirected,
and most clients drop the Authorization header on a redirect.
Scopes
Each route in the API reference needs either read or write. A read token
calling a write route gets 403 forbidden; check the scope rather than retrying.
What a credential cannot do
- An OAuth token works on the MCP server only. The token an MCP client receives
when a person signs in from it and approves is accepted by
/api/v1/mcpand by nothing else: every REST route answers it403 forbidden("An OAuth client's token is only accepted by /api/v1/mcp"). To call the REST API, use a personal access token. - AI assists refuse personal access tokens.
POST /ai/suggest-tagsandPOST /ai/rewrite-descriptionspend the account's AI allowance and are for a signed-in session only (the web app, the browser extension, a first-party app on a Supabase access token). A personal access token gets403; refusals carrydetails.assist. - Browsers on other sites. CORS is open to the web app's origin, to browser extensions, and — for a bearer token only — to these docs. A web page served from anywhere else should call the API from its server, which is also where the token belongs.
Trying endpoints from these docs
Most endpoint pages have Try in Playground. It sends a real request to your real
library with the token you paste, straight from your browser to the API; nothing
passes through this site. Paste a read token unless you mean to change something:
the playground keeps it in this browser's storage. Your signed-in session is never
used. Deleting endpoints and bulk writes have no playground — use their code samples.
Errors
A missing, revoked, expired or unknown credential is 401 unauthorized: get a new
token. Authenticated but not allowed is 403 forbidden. See
Responses and errors for the full list.