Shared resources
The first step in implementing OAuth2 is registering a developer application and retrieving your client ID and client secret. After creating your application, make sure you have yourclient_id and client_secret handy. Refer to RFC 6749 for the full OAuth2 specification.
OAuth2 URLs
| URL | Description |
|---|---|
| https://discord.com/oauth2/authorize | Base authorization URL |
| https://discord.com/api/oauth2/token | Token URL |
| https://discord.com/api/oauth2/token/revoke | Token Revocation URL |
OAuth2 scopes
These are all the OAuth2 scopes that Discord supports. Some scopes require approval from Discord to use.| Scope | Description |
|---|---|
activities.read | Fetch data from a user’s “Now Playing/Recently Played” list — not currently available for apps |
activities.write | Update a user’s activity — not currently available for apps |
applications.builds.read | Read build data for a user’s applications |
applications.builds.upload | Upload/update builds for a user’s applications — requires Discord approval |
applications.commands | Add commands to a guild — included by default with the bot scope |
applications.commands.update | Update your app’s commands using a Bearer token — client credentials grant only |
applications.commands.permissions.update | Update permissions for your app’s commands in a guild |
applications.entitlements | Read entitlements for a user’s applications |
applications.store.update | Read and update store data (SKUs, store listings, achievements, etc.) for a user’s applications |
bot | For OAuth2 bots, puts the bot in the user’s selected guild by default |
connections | Allows /users/@me/connections to return linked third-party accounts |
dm_channels.read | See information about the user’s DMs and group DMs — requires Discord approval |
email | Enables /users/@me to return an email |
gdm.join | Join users to a group DM |
guilds | Allows /users/@me/guilds to return basic information about all of a user’s guilds |
guilds.join | Allows /guilds/{guild.id}/members/{user.id} to be used for joining users to a guild |
guilds.members.read | Allows /users/@me/guilds/{guild.id}/member to return a user’s member information in a guild |
identify | Allows /users/@me without email |
messages.read | Read messages from all client channels via local RPC server API access |
relationships.read | Access a user’s Discord Friends list, pending requests, and blocked users — Social SDK only |
role_connections.write | Update a user’s connection and metadata for the app |
rpc | Control a user’s local Discord client via local RPC server access — requires Discord approval |
rpc.activities.write | Update a user’s activity via local RPC server access — requires Discord approval |
rpc.notifications.read | Receive notifications pushed out to the user via local RPC server access — requires Discord approval |
rpc.voice.read | Read a user’s voice settings and listen for voice events via local RPC — requires Discord approval |
rpc.voice.write | Update a user’s voice settings via local RPC — requires Discord approval |
voice | Connect to voice on user’s behalf and see all voice members — requires Discord approval |
webhook.incoming | Generates a webhook returned in the OAuth token response for authorization code grants |
In order to add a user to a guild, your bot must already belong to that guild.
role_connections.write cannot be used with the Implicit grant type.State and security
Before implementing OAuth2 grants, it’s important to understand thestate parameter and how it prevents Cross-site request forgery (CSRF) and Clickjacking attacks.
state is sent in the authorization request and returned in the response. It should be a value that binds the user’s request to their authenticated state — for example, a hash of the user’s session cookie or a nonce linked to the user’s session.
When the user is redirected back, validate that the state returned matches the stored value. If they don’t match, deny the request.
Authorization code grant
The authorization code grant is the standard OAuth2 flow and involves retrieving an authorization code and exchanging it for a user’s access token. All calls to the OAuth2 endpoints require either HTTP Basic authentication orclient_id and client_secret in the form data body.
Redirect the user to the authorization URL
Construct the authorization URL and direct the user to it:Key parameters:
client_id— your application’s client IDscope— space-separated (URL-encoded as%20) list of OAuth2 scopesredirect_uri— your registered redirect URI, URL-encodedstate— unique string for CSRF protectionprompt— set toconsentto always show the authorization screen, ornoneto skip if already authorizedintegration_type—0for guild install,1for user install (only relevant whenscopecontainsapplications.commands)
Receive the authorization code
After the user authorizes your application, they are redirected to your Validate the
redirect_uri with a code query parameter:state parameter before proceeding.Exchange the code for an access token
Make a Required parameters:
POST request to the token URL to exchange the code for an access token:grant_type— must beauthorization_codecode— the code from the query stringredirect_uri— the redirect URI associated with this authorization
Refreshing tokens
To refresh an expired access token, make anotherPOST request to the token URL:
Revoking tokens
To disable an access or refresh token, make aPOST request to the token revocation URL:
token— the access token or refresh token to revoke
token_type_hint— eitheraccess_tokenorrefresh_token
Implicit grant
The implicit OAuth2 grant is a simplified flow optimized for in-browser clients. The client is directly issued an access token instead of an authorization code. Authorization URL exampleaccess_token, token_type, expires_in, scope, and state.
Redirect URL example
Client credentials grant
The client credentials flow lets bot developers get their own bearer tokens for testing purposes. Make aPOST request to the token URL using Basic authentication (client ID as username, client secret as password).
Team applications are limited to the
identify and applications.commands.update scopes, because teams are not bound to a specific user.Bot users
Discord’s API provides bot users — a separate type of user dedicated to automation. Bot users are automatically added to all apps and are authenticated using the bot token found in your app’s settings. Unlike the normal OAuth2 flow, bot users have full access to most API routes without using bearer tokens, and can connect to the Real Time Gateway.Bot vs user accounts
Bot users differ from standard Discord users in several ways:- Bots are added to guilds through the OAuth2 API and cannot accept normal invites.
- Bots cannot have friends or be added to or join Group DMs.
- Verified bots do not have a maximum number of guilds.
- Bots have an entirely separate set of rate limits.
Bot authorization flow
Bot authorization is a serverless and callback-less OAuth2 flow that makes it easy for users to add bots to guilds. Bot auth parameters| Parameter | Description |
|---|---|
client_id | Your app’s client ID |
scope | Needs to include bot for the bot flow |
permissions | The permissions you’re requesting |
guild_id | Pre-fills the dropdown picker with a guild for the user |
disable_guild_select | true or false — disallows the user from changing the guild dropdown |
permissions parameter is an integer corresponding to the permission calculations. response_type and redirect_uri are not required because there is no need to retrieve the user’s access token.
Advanced bot authorization
You can request additional scopes outside ofbot and applications.commands to prompt a complete authorization code grant flow and gain the ability to request the user’s access token.
When receiving the access code on redirect, there will be additional query string parameters: guild_id and permissions. When you retrieve the user’s access token, you’ll also receive information about the guild the bot was added to:
Two-factor authentication requirement
For bots with elevated permissions (marked with* in the permissions table), Discord enforces two-factor authentication on the owner’s account when added to guilds that have server-wide 2FA enabled.
Webhooks
Discord’s webhook flow is a specialized version of the authorization code implementation. Set thescope querystring parameter to webhook.incoming:
redirect_uri with a code parameter. Exchange the code for an access token to receive a modified token response:
webhook.token and webhook.id. A new webhook is created each time a user goes through the flow, so you’ll need to save each one. Be mindful of rate limits when sending to multiple webhooks.
API endpoints
GET /oauth2/applications/@me
Returns the bot’s application object.GET /oauth2/@me
Returns info about the current authorization. Requires authentication with a bearer token. Response structure| Field | Type | Description |
|---|---|---|
application | partial application object | The current application |
scopes | array of strings | The scopes the user has authorized the application for |
expires | ISO8601 timestamp | When the access token expires |
user? | user object | The user who has authorized, if the user has authorized with the identify scope |