Scopes and Permissions
When an app requests permission to access or modify some of the user's data, it needs to define what permissions it actually wants for that specific request. This is accomplished through scopes — special string values that represent permissions for actions that an app is authorized to perform on the user's behalf.
As an app developer, when creating your app or editing its settings, you define what scopes it is allowed to request.
Note
Since a scope represents a permission granted to the app by the user, the app can never get more access to the system than the user does.
Suppose that Alice, a moderator, grants the AutoModerationBot app the permission to a hypothetical rp:moderation scope so it can automatically delete stories that look like spam or violate the content policy. If Alice later resigns as a moderator, becoming a regular user, the app will lose its access to moderation functions as well.
List of requestable scopes
Identity API
idp:character:?.read- Requests access to character ownership information for one character of the user's choice via the Character API.
idp:character:<lodestoneId>.read-
Requests access to character ownership information for the character with the specified Lodestone ID (example:
idp:character:40869035.read) via the Character API. Cannot be granted if the user doesn't have a verified character with that Lodestone ID.This scope is enabled for your app if you enable
idp:character:?.readin app settings. idp:character:<World>/<Firstname_Lastname>.read-
Requests access to character ownership information for the character with the specified world and name, with spaces replaced by underscores (example:
idp:character:Omega/Sunset_Star.read) via the Character API. Cannot be granted if the user doesn't have a verified character with that name.This scope is enabled for your app if you enable
idp:character:?.readin app settings. idp:character:all.read- Requests access to character ownership information for all of the user's verified characters via the Character API. Note that the user can approve this request without actually granting access to all characters.
idp:user.read- Requests access to basic user information, including the user's unique ID, via the User API.
idp:user:email.read- Requests access to user email via the User API. An authorization request containing this scope must also request
user.read, otherwise the request will be immediately rejected.
Roleplay API
rp:character-profile:all.write- Requests permission to edit roleplay profiles of all of the user's characters via the character roleplay profiles API.
Both APIs
offline_access- If a request including this scope is granted, the app is issued a long-lived refresh token in addition to a short-lived access token. The user cannot deny this scope without denying the whole request.
The consent page
Once the authorization server accepts your app's authorization request, it presents the user with the consent page, where the user can review the permissions your app is requesting.

The user has three options:
- Approve all permissions the app is requesting.
- Approve only some of the permissions the app is requesting.
- Deny the request entirely.
Granted scopes
The app may receive fewer permissions than it bargained for, though never more. The scopes in the authorization request specify what permissions the app wants, but it is the user who decides what permissions, if any, the app actually gets.
This is unusual for OAuth 2.0 implementations, but is explicitly permitted by the spec. That said, there are some guarantees that ensure the app won't end up with a completely unusable access token:
- The user has to either approve at least one resource scope (that is, any scope other than
offline_access), or deny the request entirely. So if your app requests only one resource scope (plus optionallyoffline_access), it is guaranteed to be either granted that scope or have the request denied entirely. - The user cannot deny the
offline_accessscope without denying the entire request. Therefore, if your app's authorization request that includes theoffline_accessscope is approved, you can be certain that the token response will include a refresh token. - If the app requests
idp:character:all.read, the user has two options: to either grant the app access to all current and future characters (granting that specific scope), or to grant access to one or more current characters and no future ones (in which case the scopes for those specific characters will be granted). Therefore, if your app requestsidp:character:all.readand nothing else, and the request is approved, it can be certain that it was granted access to at least one verified character. The app should act as if the characters accessible via the returned access token are all characters available to it. - If
user:email.readis granted, thenuser.readis necessarily granted as well. - The wildcard scope
idp:character:?.readcan be requested, but will never be returned in the list of granted scopes. Instead, the authorization server will reply withidp:character:<lodestoneId>.readwith the Lodestone ID of the character the user selects. This ensures that issued single-character access tokens are always bound to specific characters. - Character name scopes of the form
idp:character:<World>/<Firstname_Lastname>.readcan be requested, but will never be returned in the list of granted scopes. Instead, if the user indeed owns a verified character with that name, the authorization server will reply withidp:character:<lodestoneId>.readwith the Lodestone ID of that character.
These rules are in place to ensure that apps won't ask for more permissions than strictly necessary. Most apps will only need one resource scope per authorization request (plus maybe offline_access), as they'll be interested in either the Character API, the User API, or the Roleplay API. If you ask for only one thing, you won't have to settle for less, because there's no "less" to settle for.
That said, apps that do request multiple resource scopes and get less than they requested still shouldn't break. For example, an app that requests idp:user.read and idp:user:email.read for user registration, but is granted only the former, should still proceed with user registration, but ask for the user's email address itself if it needs one, instead of obtaining it from Central Archives.
Scopes are request-specific
Scopes granted to apps are specific to individual requests and to the access tokens issued for these requests. For example, imagine this scenario:
- An app makes a request for the
idp:character:all.readscope. The user approves it, and the app is issued access token T1. - The same app makes a request for the
user.readscope from the same user. The user approves it, and the app is issued access token T2.
In this case, the app can use token T1 to access the Character API, and token T2 to access the User API, but not the other way round.