Scopes
A scope is a named permission carried by an access token. Each protected endpoint requires a specific scope; a request without it returns 403 insufficient_scope. A token can carry only scopes granted to its client.
OIDC scopes vs. Remilia API scopes
- OIDC scopes — standard OpenID Connect scopes. Request
openidin a login flow to receive an ID token.openiddoes not grant access to any/api/v1endpoint. - Remilia API scopes — everything under the
remilia:prefix. These are the permissions the public API enforces.
Scope reference
These scopes require a user-delegated token from the Authorization Code + PKCE flow of a login client. They act on behalf of a signed-in user, so an API client (Client Credentials) cannot use them.
| Scope | Grants | Endpoint | Compatible client / grant |
|---|---|---|---|
remilia:profile.private | Read the authenticated user's own profile data — handle, display name, per-platform stats, aggregate scores | GET /me/profile | Login client (Authorization Code + PKCE) |
remilia:interact.poke | Poke another user, attributed to the authenticated user | POST /pokes | Login client (Authorization Code + PKCE) |
GET /users/{username} returns a public profile and requires no scope and no token.
Requesting scopes
Your login client is approved for a set of scopes. Request only the scopes your app needs from that set.
With oidc-spa, add them to the bootstrap configuration:
scopes: ["remilia:profile.private", "remilia:interact.poke"],oidc-spa adds openid automatically. For a manual authorization request, pass the same scope names in the space-delimited scope parameter.
Checking issued scopes
The token response's scope field is a space-delimited string. Check it before calling an endpoint that requires a scope:
{
"scope": "openid remilia:profile.private"
}Errors
A valid token without the required scope returns:
{
"error": {
"code": "insufficient_scope",
"message": "scope remilia:interact.poke required"
}
}A user-authorized endpoint returns 403 forbidden when:
- the token has the required scope but is not user-delegated; use a login client instead
- the user's account is disabled