Sign in with Cube Community

Cube Community is an OpenID Connect provider: your tool, bot or site can sign people in with their Cube Community account, and know who they are (their Discord, their verified BeatLeader or verified ScoreSaber account) without asking them. Register your application, point any OpenID Connect library at the discovery URL below, and you are set.

Endpoints

Every endpoint (authorize, token, userinfo, keys, logout) is listed in the discovery document. Tokens are signed with RS256.

Issuer
https://cube.community/api/auth
Discovery URL
https://cube.community/api/auth/.well-known/openid-configuration

Use the authorization code flow. A server-side application keeps a client secret; a single-page or native app has none and uses PKCE, which every application should send anyway.

Scopes and claims

Pick the scopes your application needs when you register it; people see each one on the consent screen before they let it in. Each scope's claims come in two places, with the same values: the ID token (a signed JWT returned with the tokens) and the UserInfo response (GET /api/auth/oauth2/userinfo with the access token as a Bearer token). The ID token also carries OpenID Connect's own claims: iss, aud, exp, iat, auth_time, nonce, at_hash, sid.

openid

Required: makes the flow OpenID Connect, so you get an ID token.

substring

Their Cube Community user id. Stable: use it as the key to your own user records.

Example: "clgfoxlm50000s04mvxqq8ymg"

profile

Who they are on the site, as it shows them.

namestring

Their display name: the custom username they chose, or their Discord username.

Example: "JiveOff"

preferred_usernamestring

Their Discord display name: their global name, or their username when they have none.

Example: "JiveOff"

picturestring | null

Their avatar URL: their game avatar or their Discord one, whichever they chose.

Example: "https://cdn.discordapp.com/avatars/..."

discord

Their Discord identity, to match them on a server or with a bot.

discord_idstring

Their Discord user id (a snowflake, sent as a string: it does not fit in a JavaScript number).

Example: "186156892379283456"

accounts

Their verified linked accounts, such as BeatLeader or ScoreSaber.

linked_accountsarray of { provider, id, username? }

One entry per account they linked: provider is discord, beatleader, scoresaber or steam. Only the Discord entry has a username: their Discord display name, as in preferred_username.

Example: [{ "provider": "discord", "id": "1378...", "username": "JiveOff" }, { "provider": "beatleader", "id": "7656..." }]

game_account{ platform, id, name } | null

The account they play with: platform is steam or oculus. null if they have not linked one.

Example: { "platform": "steam", "id": "7656...", "name": "JiveOff" }

offline_access

Keeps your application signed in without asking them again.

No claim: the token endpoint also returns a refresh_token, which you exchange for new tokens (grant_type=refresh_token) once the access token expires, after an hour.

Example UserInfo response

For an application granted openid profile discord accounts:

{
  "sub": "clgfoxlm50000s04mvxqq8ymg",
  "name": "JiveOff",
  "preferred_username": "JiveOff",
  "picture": "https://cdn.discordapp.com/avatars/...",
  "discord_id": "186156892379283456",
  "linked_accounts": [
    { "provider": "discord", "id": "186156892379283456", "username": "JiveOff" },
    { "provider": "beatleader", "id": "76561198000000000" }
  ],
  "game_account": { "platform": "steam", "id": "76561198000000000", "name": "JiveOff" }
}

Reserved scopes

These are granted by an admin, not picked: ask [email protected], saying which application needs them and why.

email

Their email address. Which one depends on what was granted: the email of their Discord account, or their @cube.community address for staff tools.

emailstring

The email address of the Discord account they sign in with (Discord gives it to us at sign-in, and it follows a change there at their next sign-in), or their @cube.community address. Absent if their Discord account has none.

Example: "[email protected]"

email_verifiedboolean

For a Discord email: whether Discord itself has verified the address (its own verification, by email). Always true for a @cube.community address, which we issue. Treat false as unconfirmed.

Example: true

groups

The Cube Community groups they are in, to gate access or map roles in your application.

groupsstring[]

The names of their groups. Empty if they are in none.

Example: ["Staff Cubes", "Tournament Cubes"]

Cube Community © 2026