Skip to content
Fluxer API

OAuth2

OAuth2 lets a user give an application access to their account, and the same consent step can install the application's bot into a guild or group DM. You create applications and client secrets with the Applications routes.

  1. Send the user's browser to Authorize application. When the user approves on the consent screen, Fluxer sends the browser to your redirect_uri with a code and your state.
  2. Exchange the code at Exchange OAuth2 token with your client credentials to get an access token and a refresh token.
  3. Send the access token as Authorization: Bearer <token>. Before the access token expires, exchange the refresh token for a new pair.
CredentialLifetime
Authorization code10 minutes, single use
Access token7 days
Refresh token30 days, single use. Each refresh returns a new one

PKCE supports the S256 and plain methods. A code_challenge with no code_challenge_method uses plain. When the code has a challenge, the token exchange needs a matching code_verifier.

The token, introspection and revocation routes take an application/x-www-form-urlencoded or multipart/form-data body. Authenticate your application with HTTP Basic or with the client_id and client_secret fields. Introspection and revocation return invalid_request when credentials are in both the Authorization header and the body.

Grant OAuth2 consent and the routes under /oauth2/@me/authorizations need the user's own token. A bot token or OAuth2 access token gets 403 ACCESS_DENIED.

String fields such as state, redirect_uri and code can be at most 256 characters.

ValueDescription
identifyRead the user's account through Get OAuth2 user information and Get current user
email1Adds email and verified to the user information
guildsUse List current user guilds, Get guild and List guild roles
connectionsUse List connections
bot2Install the application's bot into a guild or group DM

1 Only works together with identify

2 The access token gets no access from this scope

Separate scopes with spaces. Fluxer rejects an unknown scope with invalid_scope, and the order of scopes in a response isn't fixed.

The token, consent, introspection and revocation routes return this body with status 400 when the grant, client, scope, redirect URI or permission mask is rejected. Other failures use the ordinary error response.

FieldTypeDescription
errorstringThe OAuth2 error code
error_descriptionstringA description for people, which you shouldn't parse
{
"error": "invalid_grant",
"error_description": "The provided authorization grant is invalid, expired, or revoked"
}
ValueDescription
invalid_requestThe redirect URI, response type or permission mask is wrong, or credentials were sent in both places
invalid_clientThe application is unknown or the client secret is missing or wrong
invalid_grantThe code, refresh token, redirect URI or PKCE verifier doesn't match a valid grant
invalid_scopeA requested scope isn't in OAuth2 scopes

The token pair a successful exchange returns.

FieldTypeDescription
access_tokenstringThe bearer token
token_typestringAlways Bearer
expires_inintegerThe access token lifetime in seconds, 604800
refresh_tokenstringThe refresh token for the next exchange
scopestringThe granted scopes, separated by spaces
{
"access_token": "M2xQb1RkY0hqTmZLc1B2WndBcUx1RWc2WXRJbk9iUmE",
"token_type": "Bearer",
"expires_in": 604800,
"refresh_token": "VGhpc0lzQUZha2VSZWZyZXNoVG9rZW5Gb3JEb2NzMDE",
"scope": "identify email"
}

The user that Get OAuth2 user information returns.

FieldTypeDescription
subsnowflakeThe ID of the user, the same as id
idsnowflakeThe ID of the user
usernamestringThe username
discriminatorstringThe four-digit discriminator
global_name?stringThe display name
avatar?stringThe avatar hash
email??stringThe email address, null without the email scope
verified??booleanWhether the email address is verified, sent only with the email scope
flags?integerThe public user flags
avatar_color1?integerThe default avatar color
bot1booleanWhether the account is a bot
system1booleanWhether the account is a system user

1 Always sent, but the response schema does not declare it

Whether a token is active, and what it grants.

FieldTypeDescription
activebooleanWhether the token is valid and was issued to your application
scope?stringThe granted scopes, separated by spaces
client_id?snowflakeThe ID of the application
username?stringNever sent
token_type?stringThe token type, Bearer for an access token or refresh_token for a refresh token
exp?integerWhen the access token expires, in Unix seconds
iat?integerWhen the token was issued, in Unix seconds
sub?snowflakeThe ID of the user

An inactive token returns only active: false. An active token has every other field except username, and a refresh token has no exp.

The application, scopes and expiry of the access token you sent.

FieldTypeDescription
applicationOAuth2 application summary objectThe application the token was issued to
scopesarray[string]The granted scopes
expiresISO8601 timestampWhen the access token expires
user?OAuth2 authorized user objectThe user, sent only when the token has identify

The application in a current OAuth2 authorization.

FieldTypeDescription
idsnowflakeThe ID of the application
namestringThe name of the application
icon?stringAlways null
description?stringAlways null
bot_publicbooleanWhether anyone can install the bot
bot_require_code_grantbooleanWhether installing the bot needs a full code grant
flagsintegerAlways 0

The user in a current OAuth2 authorization.

FieldTypeDescription
idsnowflakeThe ID of the user
usernamestringThe username
discriminatorstringThe four-digit discriminator
global_name?stringThe display name
avatar?stringThe avatar hash
avatar_color?integerThe default avatar color
bot?booleanWhether the account is a bot
system?booleanWhether the account is a system user
flagsintegerThe public user flags
email??stringThe email address, null without the email scope
verified??booleanWhether the email address is verified, sent only with the email scope
sub1snowflakeThe ID of the user, the same as id

1 Always sent, but the response schema does not declare it

One application the current user has authorized.

FieldTypeDescription
applicationauthorized application objectThe application
scopes1array[string]The scopes the user granted to it
authorized_atISO8601 timestampWhen the oldest current refresh token for the application was issued

1 Can include bot or values you don't recognize, which you should ignore

The application in an OAuth2 authorization.

FieldTypeDescription
idsnowflakeThe ID of the application
namestringThe name of the application
icon?stringThe avatar hash of the application's bot
description?stringAlways null
bot_publicbooleanWhether anyone can install the bot

The callback URL from Grant OAuth2 consent.

FieldTypeDescription
redirect_tostringThe redirect URI with code and your state added
GET/v1/oauth2/authorizeUnauthenticated

Starts the grant and redirects the browser to the Fluxer consent screen with the same parameters.

FieldTypeDescription
response_type?stringThe response type, code
client_idsnowflakeThe ID of the application
redirect_uri?stringA redirect URI registered on the application
scopestringThe requested scopes, separated by spaces
state?stringA value Fluxer returns unchanged on the redirect
prompt?stringThe prompt mode, consent or none
guild_id?snowflakeThe guild to preselect for the bot scope
channel_id?snowflakeThe group DM to preselect for the bot scope
permissions?stringThe permissions to give the bot, as an integer string
disable_guild_select?stringtrue to stop the user from picking another guild
code_challenge?stringThe PKCE challenge
code_challenge_method?stringThe PKCE method, S256 or plain
StatusBodyCondition
302emptyThe Location header has the consent screen or your callback

With prompt=none, Fluxer skips the consent screen when the signed-in user has already granted every requested scope, and redirects to your redirect_uri with a code. Otherwise it redirects with error=login_required when nobody is signed in, or error=consent_required. If redirect_uri isn't registered on the application, the error goes to the Fluxer web app.

The rate limit is 60 requests per minute, on the oauth:authorize bucket.

POST/v1/oauth2/authorize/consent

Records the user's consent and returns an OAuth2 consent response with the callback URL. With the bot scope it also installs the bot. In a guild you need MANAGE_GUILD or ADMINISTRATOR, and in a group DM you need to be a recipient.

FieldTypeDescription
response_type?stringThe response type, code. Ignored when the only scope is bot
client_idsnowflakeThe ID of the application
redirect_uri?1stringA redirect URI registered on the application
scopestringThe requested scopes, separated by spaces
state?stringA value Fluxer adds to the callback URL
permissions?2stringThe permissions to give the bot, as an integer string
guild_id?3snowflakeThe guild to install the bot into
channel_id?3snowflakeThe group DM to install the bot into
code_challenge?stringThe PKCE challenge
code_challenge_method?stringThe PKCE method, S256 or plain

1 Required unless the only scope is bot and the application doesn't set bot_require_code_grant

2 You can only request permissions you have. Thread permissions need the channel_threads client capability

3 Send one or the other

StatusBodyCondition
200OAuth2 consent response objectConsent was recorded
400OAuth2 error objectThe application, scope, redirect URI, response type or permission mask was rejected
400error responseNOT_A_BOT_APPLICATION, BOT_ALREADY_IN_GUILD or INVALID_CHANNEL_TYPE
400error responseMAX_GUILD_MEMBERS, MAX_GUILD_ROLES or MAX_GROUP_DM_RECIPIENTS
403error responseBOT_IS_PRIVATE when you don't own a private bot's application
403error responseMISSING_PERMISSIONS when you lack the guild permissions, or MISSING_ACCESS when you aren't in the group DM
404error responseUNKNOWN_CHANNEL when the group DM doesn't exist

When a guild install has a non-zero permissions value, Fluxer creates a role with the application's name with those permissions and gives it to the bot. A guild install sends Guild Create and Guild Member Add, and a group DM install sends Channel Recipient Add. If the install fails, Fluxer deletes the code and returns the error.

The rate limit is 60 requests per minute, on the oauth:authorize bucket.

POST/v1/oauth2/token

Exchanges an authorization code or a refresh token for an OAuth2 token object.

FieldTypeDescription
grant_typestringThe grant type, authorization_code or refresh_token
codestringThe code from the callback, for authorization_code
redirect_uristringThe code's redirect URI, normalized, so https://example.com is sent as https://example.com/
code_verifier?stringThe PKCE verifier, when the code has a challenge
refresh_tokenstringThe refresh token, for refresh_token
client_id?snowflakeThe ID of the application, if you don't use HTTP Basic
client_secret?stringThe client secret, if you don't use HTTP Basic
StatusBodyCondition
200OAuth2 token objectA token pair was issued
400OAuth2 error objectClient authentication or the grant failed

The rate limit is 120 requests per minute, on the oauth:token bucket.

GET/v1/oauth2/userinfoidentify

Returns the OAuth2 user information for the access token's user.

StatusBodyCondition
200OAuth2 user information objectThe user was returned
403error responseMISSING_OAUTH_SCOPE when the token lacks identify, with the scope in required_scope

The rate limit is 120 requests per minute, on the oauth:introspect bucket.

POST/v1/oauth2/introspect

Returns an OAuth2 introspection object for an access or refresh token. A token is inactive when it was issued to another application or its user can't sign in.

FieldTypeDescription
tokenstringThe access or refresh token
client_id?snowflakeThe ID of the application, if you don't use HTTP Basic
client_secret?stringThe client secret, if you don't use HTTP Basic
StatusBodyCondition
200OAuth2 introspection objectThe token was checked, including an inactive one
400OAuth2 error objectClient authentication failed

The rate limit is 120 requests per minute, on the oauth:introspect bucket.

POST/v1/oauth2/token/revoke

Deletes every access and refresh token the token's user has for your application.

FieldTypeDescription
tokenstringThe access or refresh token
token_type_hint?1stringThe token type, access_token or refresh_token
client_id?snowflakeThe ID of the application, if you don't use HTTP Basic
client_secret?stringThe client secret, if you don't use HTTP Basic

1 Send refresh_token when the token is a refresh token, or Fluxer won't find it

StatusBodyCondition
200emptyThe tokens were deleted, or the token matched nothing
400OAuth2 error objectClient authentication failed

The rate limit is 120 requests per minute, on the oauth:revoke bucket.

GET/v1/oauth2/@me

Returns the current OAuth2 authorization for the OAuth2 access token you send. It needs no scope.

StatusBodyCondition
200current OAuth2 authorization objectThe authorization was returned
401error responseUNAUTHORIZED when the token isn't an OAuth2 access token

The rate limit is 120 requests per minute, on the oauth:introspect bucket.

GET/v1/oauth2/@me/authorizations

Returns an array of OAuth2 authorization objects for the applications the current user has authorized with a scope other than bot.

StatusBodyCondition
200array[OAuth2 authorization object]The authorizations were returned

The rate limit is 60 requests per minute, on the oauth_dev:clients:list bucket.

DELETE/v1/oauth2/@me/authorizations/{applicationId}

Deletes every token the current user has for one application. A bot the application installed stays where it is.

StatusBodyCondition
204emptyThe authorization was revoked
404error responseUNKNOWN_APPLICATION when the application doesn't exist

The rate limit is 120 requests per minute, on the oauth:introspect bucket.

POST/v1/oauth2/@me/authorizations/revoke

Deletes every token the current user has for several applications. If any application is unknown, the request returns 404 UNKNOWN_APPLICATION and revokes nothing.

FieldTypeDescription
application_idsarray[snowflake]The IDs of the applications (1-100)
StatusBodyCondition
204emptyThe authorizations were revoked

The rate limit is 120 requests per minute, on the oauth:introspect bucket.