Authentication

A major distinguishing feature of user accounts is that you retrieve authentication tokens by logging in through a classic email/password combination. However, the full login & registration flow is quite complex, and involves several steps.

Fingerprints

Discord uses fingerprints to persist experiments throughout the authentication flow. For more information about fingerprints, see the relevant experiment documentation.

If the client is unauthenticated, a fingerprint should be generated using Get Experiment Assignments and included in the X-Fingerprint header as well as any applicable fingerprint JSON parameters until authentication is complete.

Sessions

Discord uses sessions to track the user's authentication state. A session is created when the user logs in and is invalidated when the user logs out or the session expires. Sessions are unique to a single authentication token and keep track of the last location they were used from. Suspicious sessions may be flagged by Discord and lead to the account being locked, requiring the user to reset their password.

The authentication session ID corresponding to the current Gateway session is given in the auth_session_id_hash field in the Ready event. If the current Gateway session's authentication session ever changes (e.g. due to a password reset), the client will receive an Auth Session Change Gateway event.

Auth Session Object

Auth Session Structure
FieldTypeDescription
id_hashstringThe session ID hash
approx_last_used_timeISO8601 timestampWhen the session was last used
client_infoauth session client info objectThe client last associated with the session
Auth Session Client Info Structure
FieldTypeDescription
os?stringThe operating system of the client
platform?stringThe name of the client or browser platform
location?stringThe approximate location of the client
ip?stringThe IP address of the client, if the location could not be determined
Example Auth Session
{
"id_hash": "y3vq9yYww3Y1yAhc4ChuRtCOHADRu0gTPoIU5y3DcS4=",
"approx_last_used_time": "2024-03-30T21:30:58.100231+00:00",
"client_info": {
"os": "Windows",
"platform": "Discord Client",
"location": "San Francisco, California, United States"
}
}

Endpoints

Get Auth Sessions

GET/auth/sessions

Returns up to 50 of the user's active authentication sessions.

Response Body
FieldTypeDescription
user_sessionsarray[auth session object]Active authentication sessions for the user

Logout Auth Sessions

POST/auth/sessions/logout

Invalidates a list of authentication sessions. Returns a 204 empty response on success.

JSON Params
FieldTypeDescription
session_id_hashesarray[string]The session ID hashes to invalidate (1-64)

Login

The login process is the first step in authenticating a user.

To log in, a client must first use the Login Account endpoint with the user's email/phone number and password. If the user has multi-factor authentication enabled, the client must use the Verify MFA Login endpoint to complete the login process after a successful response.

If a known JSON error code is returned, the client must handle the error accordingly (e.g. prompt the user to undelete their account or verify their phone number). If a form body error is returned, the client should display the error message to the user.

Once the user is logged in, the client should store the authentication token to avoid having to log in again in the future.

WebAuthn Conditional UI (Passwordless) Login

An alternative to the traditional email/password login flow is the WebAuthn conditional UI flow. This allows users to log in using an WebAuthn device (e.g. a security key) instead of a password.

To use this flow, the client must first generate a challenge using the Start Passwordless Login endpoint. After the user completes the WebAuthn challenge, the client must use the Finish Passwordless Login endpoint to complete the login process. Using this flow, you must still take care to handle any errors as outlined above.

Endpoints

Login Account

POST/auth/login

Retrieves an authentication token for the given credentials.

JSON Params
FieldTypeDescription
loginstringThe user's email or E.164-formatted phone number
passwordstringThe user's password (8-72 characters)
undelete? 1booleanWhether to undelete a self-disabled or self-deleted account (default false)
login_source??stringThe source of the login request
gift_code_sku_id??stringThe SKU ID of the gift code that initiated the login request

1 If you get an account disabled (20013) or marked for deletion (20011) JSON error code, you can undelete the account by setting this parameter.

Login Source

Where a login is initiated from outside of the normal login flow.

ValueDescription
giftLogin request initiated from a gift code
guild_templateLogin request initiated from a guild template
guild_inviteLogin request initiated from a guild invite
dm_inviteLogin request initiated from a group DM invite
friend_inviteLogin request initiated from a friend invite
role_subscriptionLogin request initiated from a role subscription redirect
role_subscription_settingLogin request initiated from a role subscription settings redirect
Response Body
FieldTypeDescription
user_idsnowflakeThe ID of the user that was logged in
token?stringThe authentication token, if the login was completed
user_settings?login settings objectThe user's partial settings, if the login was completed
required_actions?array[string]The required actions that must be completed before continuing to use Discord
ticket?stringA ticket to be used in the multi-factor authentication flow
mfa?booleanWhether multi-factor authentication is required to login (default false)
totp?booleanWhether the user has TOTP-based multi-factor authentication enabled
sms?booleanWhether the user has SMS-based multi-factor authentication enabled
backup?booleanWhether backup codes can be used for multi-factor authentication
webauthn??stringThe stringified JSON public key credential request options challenge for WebAuthn
Login Settings Structure

A partial settings object to bootstrap the client with.

FieldTypeDescription
localestringThe language option chosen by the user
themestringThe client theme selected by the user
Login Required Action Type

Actions the user must complete after a successful login.

ValueDescription
update_passwordThe user must change their password to meet Discord's new password requirements
Example Response (Completed)
{
"user_id": "852892297661906993",
"token": "ODUyODkyMjk3NjYxOTA2OTkz.GX5Xdp.22jsdSqEiHLUYEJSsjeq_vJKLpOofd5QMksqw32e",
"user_settings": {
"locale": "en-US",
"theme": "dark"
},
"required_actions": ["update_password"]
}
Example Response (MFA Required)
{
"user_id": "852892297661906993",
"mfa": true,
"sms": true,
"ticket": "ODUyODkyMjk3NjYxOTA2OTkz.H2Rpq0.WrhGhYEhM3lHUPN61xF6JcQKwVutk8fBvcoHjo",
"backup": true,
"totp": true,
"webauthn": "{\"publicKey\":{\"challenge\":\"a8a1cHP7_zYheggFG68zKUkl8DwnEqfKvPE-GOMvhss\",\"timeout\":60000,\"rpId\":\"discord.com\",\"allowCredentials\":[{\"type\":\"public-key\",\"id\":\"izrvF80ogrfg9dC3RmWWwW1VxBVBG0TzJVXKOJl__6FvMa555dH4Trt2Ub8AdHxNLkQsc0unAGcn4-hrJHDKSO\"}],\"userVerification\":\"preferred\"}}",
"required_actions": ["update_password"]
}

Verify MFA Login

POST/auth/mfa/{authenticator_type}

Verifies a multi-factor login and retrieves an authentication token using the specified authenticator type.

JSON Params
FieldTypeDescription
ticketstringThe MFA ticket received from the login request
code 1stringThe MFA code (TOTP, SMS, backup, or WebAuthn) to be verified
login_source??stringThe source of the login request
gift_code_sku_id??stringThe SKU ID of the gift code that initiated the login request

1 For WebAuthn authentication, the code parameter should be a stringified JSON object of the public key credential response.

Response Body
FieldTypeDescription
tokenstringThe authentication token
user_settingslogin settings objectThe user's partial settings
Example Response (Completed)
{
"token": "ODUyODkyMjk3NjYxOTA2OTkz.GX5Xdp.22jsdSqEiHLUYEJSsjeq_vJKLpOofd5QMksqw32e",
"user_settings": {
"locale": "en-US",
"theme": "dark"
}
}

Start Passwordless Login

POST/auth/conditional/start

Generates a challenge to start the conditional UI flow for WebAuthn login.

Response Body
FieldTypeDescription
ticketstringThe WebAuthn login ticket
challengestringThe stringified JSON public key credential request options challenge for WebAuthn
Example Response
{
"challenge": "{\"publicKey\":{\"challenge\":\"sLPruFUWBzowZjYy5d2caF2067pw44butrN0iHm_8k4\",\"timeout\":60000,\"rpId\":\"discord.com\",\"allowCredentials\":[],\"userVerification\":\"required\",\"extensions\":{\"uvm\":true}},\"mediation\":\"conditional\"}",
"ticket": "b9f98b82-c3a7-49b6-b881-f83418fa2dbe"
}

Finish Passwordless Login

POST/auth/conditional/finish

Retrieves an authentication token for the given WebAuthn credentials.

JSON Params
FieldTypeDescription
ticketstringThe WebAuthn login ticket received from the Start Passwordless Login endpoint
credentialstringThe stringified JSON public key credential response for WebAuthn
login_source??stringThe source of the login request
gift_code_sku_id??stringThe SKU ID of the gift code that initiated the login request
Response Body
FieldTypeDescription
user_idsnowflakeThe ID of the user that was logged in
tokenstringThe authentication token
user_settingslogin settings objectThe user's partial settings
required_actions?array[string]The required actions that must be completed before continuing to use Discord
Example Response
{
"user_id": "852892297661906993",
"token": "ODUyODkyMjk3NjYxOTA2OTkz.GX5Xdp.22jsdSqEiHLUYEJSsjeq_vJKLpOofd5QMksqw32e",
"user_settings": {
"locale": "en-US",
"theme": "dark"
},
"required_actions": ["update_password"]
}

Authorize IP Address

POST/auth/authorize-ip

Authorizes the client's IP address for login. Returns a 204 empty response on success.

JSON Params
FieldTypeDescription
tokenstringThe verification token received from the email or phone number verification process

Register

Potential users must register an account before they are able to use most of the platform.

The full registration process involves choosing a username & display name, providing an email address or phone number, setting a password, and providing a date of birth. However, the client can choose to skip some of these steps to provide a more streamlined registration experience, such as when viewing an invite or gift code.

To register, the client should first retrieve the user's location metadata to determine whether explicit consent is required. Then, they can use the Register Account endpoint to create a new account with the provided credentials. Throughout the process, they can use the Get Unique Username Suggestions to get username suggestions for the user's display name and Get Unique Username Eligibility endpoints to validate the username's availability.

Once the user is registered, the client should store the authentication token to avoid having to log in again in the future.

Phone Registration

Clients can alternatively register an account using a phone number. To do so, the client must first use the Register by Phone Number endpoint to send a verification code to the user's phone number. Then, the client must verify the phone number using the received code before completing the registration using the Register Account endpoint as usual.

Endpoints

Register Account

POST/auth/register

Creates a new account and retrieves an authentication token for the given credentials.

JSON Params
FieldTypeDescription
username? 1stringThe username to register (default random)
global_name? 1?stringThe display name to register
email?stringThe user's email address
phone_token?stringThe phone number verification token received from the phone registration flow
password?stringThe user's password (8-72 characters)
date_of_birth?ISO8601 dateThe user's date of birth
fingerprint? 2stringThe fingerprint to use for registration
invite? 3?stringThe invite code that initiated the registration
guild_template_code??stringThe guild template code that initiated the registration
gift_code_sku_id??stringThe SKU ID of the gift code that initiated the registration
consent? 4booleanWhether the user agrees to Discord's Terms of Service and Privacy Policy
promotional_email_opt_in? 4booleanWhether the user explicitly opts-in/out to receiving promotional emails from Discord

1 One of username or global_name must be provided. A valid username can be retrieved using the Get Unique Username Suggestions endpoint and validated using the Get Unique Username Eligibility endpoint. See the Usernames and Nicknames section for more information on username restrictions.

2 This value should be set to the same fingerprint used throughout the authentication flow. Upon valid registration, the new account will share the same ID as the fingerprint to ensure experiment continuity.

3 Upon valid registration, this invite code will automatically be accepted.

4 Clients can determine whether explicit consent is required by using the Get Location Metadata endpoint.

Response Body
FieldTypeDescription
tokenstringThe authentication token
show_verification_form?booleanWhether the user should be shown the joined guild's member verification form
Example Response
{
"token": "ODUyODkyMjk3NjYxOTA2OTkz.GX5Xdp.22jsdSqEiHLUYEJSsjeq_vJKLpOofd5QMksqw32e",
"show_verification_form": true
}

Register by Phone Number

POST/auth/register/phone

Sends a verification code to the user's phone number to register an account. Returns a 204 empty response on success. The verification code should be first used to verify the phone number before completing the registration.

JSON Params
FieldTypeDescription
phonestringThe user's E.164-formatted phone number

Get Location Metadata

GET/auth/location-metadata

Returns the location metadata for the user's IP address.

Response Body
FieldTypeDescription
country_codestringThe ISO 3166-1 alpha-2 country code of the user's IP address
consent_requiredbooleanWhether the user must explicitly agree to Discord's Terms of Service and Privacy Policy in order to register
promotional_email_opt_inpromotional email metadata objectPromotional email consent metadata
Promotional Email Metadata Structure
FieldTypeDescription
requiredbooleanWhether the user must explicitly agree to receive promotional emails from Discord
pre_checkedbooleanWhether the promotional email consent checkbox should be pre-checked, if explicit consent is required
Example Response
{
"consent_required": false,
"country_code": "CA",
"promotional_email_opt_in": {
"required": true,
"pre_checked": false
}
}

Get Unique Username Suggestions

GET/unique-username/username-suggestions-unauthed

Returns a suggested unique username string for the user to register with.

Query String Params
FieldTypeDescription
global_name?stringThe global name to base the username suggestions on (default random)
Response Body
FieldTypeDescription
usernamestringThe suggested username
Example Response
{ "username": "gnarp.gnap" }

Get Unique Username Eligibility

POST/unique-username/username-attempt-unauthed

Checks whether a unique username is available for the user to register with.

JSON Params
FieldTypeDescription
usernamestringThe username to check
Response Body
FieldTypeDescription
takenbooleanWhether the username is taken
Example Response
{ "taken": true }

Logout

To log out, the client must use the Logout endpoint with the user's authentication token. This is used to invalidate the token and prevent further push notifications from being sent to the client. See the push notifications section for more information.

Endpoints

Logout

POST/auth/logout

Invalidates the given authentication session and unregisters the provided push notification token.

JSON Params
FieldTypeDescription
provider?stringThe push notification provider to revoke
token?stringThe push notification token to unregister
voip_provider? 1stringThe VOIP push notification provider to revoke the token from
voip_token? 1stringThe VOIP push notification token to unregister

1 VOIP-specific push notification tokens are only used with PushKit on iOS.

Account Recovery

If a user has forgotten their password, they can reset it using either their email address or phone number. To initiate a password reset, the client should use the Forgot Password endpoint.

To complete the password reset, the user must either retrieve the password reset token from their email or by verifying their phone number. Then, the client can use the Reset Password endpoint to set a new password.

Endpoints

Forgot Password

POST/auth/forgot

Initiates the password reset process for the given email or phone number. Returns a 204 empty response on success.

JSON Params
FieldTypeDescription
loginstringThe user's email or E.164-formatted phone number

Reset Password

POST/auth/reset

Resets the user's password and retrieves an authentication token.

JSON Params
FieldTypeDescription
tokenstringThe password reset token received from the email or phone number verification
passwordstringThe user's new password (8-72 characters)
source?stringThe source path the password reset was initiated from (e.g. /reset)
ticket?stringThe MFA ticket received from the previous request
code? 1stringThe MFA code (TOTP, SMS, backup, or WebAuthn) to be verified

1 For WebAuthn authentication, the code parameter should be a stringified JSON object of the public key credential response.

Response Body
FieldTypeDescription
token?stringThe authentication token, if the password reset was completed
user_id?snowflakeThe ID of the user whose password was reset, if MFA verification is required
ticket?stringA ticket to be used when retrying the request with multi-factor authentication
mfa?booleanWhether multi-factor authentication is required to reset the password (default false)
totp?booleanWhether the user has TOTP-based multi-factor authentication enabled
sms?booleanWhether the user has SMS-based multi-factor authentication enabled
backup?booleanWhether backup codes can be used for multi-factor authentication
webauthn??stringThe stringified JSON public key credential request options challenge for WebAuthn
Example Response (Completed)
{ "token": "ODUyODkyMjk3NjYxOTA2OTkz.GX5Xdp.22jsdSqEiHLUYEJSsjeq_vJKLpOofd5QMksqw32e" }
Example Response (MFA Required)
{
"user_id": "852892297661906993",
"mfa": true,
"sms": true,
"ticket": "ODUyODkyMjk3NjYxOTA2OTkz.H2Rpq0.WrhGhYEhM3lHUPN61xF6JcQKwVutk8fBvcoHjo",
"backup": true,
"totp": true,
"webauthn": "{\"publicKey\":{\"challenge\":\"a8a1cHP7_zYheggFG68zKUkl8DwnEqfKvPE-GOMvhss\",\"timeout\":60000,\"rpId\":\"discord.com\",\"allowCredentials\":[{\"type\":\"public-key\",\"id\":\"izrvF80ogrfg9dC3RmWWwW1VxBVBG0TzJVXKOJl__6FvMa555dH4Trt2Ub8AdHxNLkQsc0unAGcn4-hrJHDKSO\"}],\"userVerification\":\"preferred\"}}"
}

MFA Verification

In some cases, you may be required to verify your identify using multi-factor authentication before performing certain sensitive actions. When this occurs, you'll receive a 401 unauthorized error with a special error response body:

MFA Required Response Structure
FieldTypeDescription
messagestringA message saying that multi-factor authentication is required for the operation
codeintAn error code (will always be 60003)
mfaMFA verification request objectThe multi-factor authentication verification request
MFA Verification Request Structure
FieldTypeDescription
ticketstringThe MFA ticket
methodsarrayAn array of MFA methods that can be used to verify the user's identity
MFA Method Structure
FieldTypeDescription
typestringThe type of MFA method that can be used to verify the user's identity
challenge?stringThe stringified JSON public key credential request options challenge for WebAuthn
backup_codes_allowed?booleanWhether backup codes can be used in addition to TOTP codes
Authenticator Type
ValueDescription
totpVerification using a TOTP code or backup code
smsVerification using a code sent to the user's phone number via SMS
backupVerification using a backup code
webauthnVerification using a WebAuthn device
password 1Verification using the user's password

1 The user password is used to authenticate in certain cases if the user has not enabled any other MFA methods.

Example MFA Required Response
{
"message": "Two factor is required for this operation",
"code": 60003,
"mfa": {
"ticket": "ODUyODkyMjk3NjYxOTA2OTkz.H2Rpq0.WrhGhYEhM3lHUPN61xF6JcQKwVutk8fBvcoHjo",
"methods": [
{
"type": "webauthn",
"challenge": "{\"publicKey\":{\"challenge\":\"a8a1cHP7_zYheggFG68zKUkl8DwnEqfKvPE-GOMvhss\",\"timeout\":60000,\"rpId\":\"discord.com\",\"allowCredentials\":[{\"type\":\"public-key\",\"id\":\"izrvF80ogrfg9dC3RmWWwW1VxBVBG0TzJVXKOJl__6FvMa555dH4Trt2Ub8AdHxNLkQsc0unAGcn4-hrJHDKSO\"}],\"userVerification\":\"preferred\"}}"
},
{
"type": "totp",
"backup_codes_allowed": true
},
{
"type": "sms"
},
{
"type": "backup"
}
]
}
}

To verify, you must use the Verify MFA endpoint with the ticket retrieved from the error response. The retrieved verification JWT can then be inserted into the X-Discord-MFA-Authorization header and the original request can be retried.

Upon successful elevation, the verification JWT will be returned in a __Secure-recent_mfa cookie that temporary bypasses MFA for the next 5 minutes.

Endpoints

Verify MFA

POST/mfa/finish

Verifies a user's identity using multi-factor authentication. On success, returns a cookie that can be used to bypass MFA for the next 5 minutes.

JSON Params
FieldTypeDescription
ticketstringThe MFA ticket received from the MFA required response
mfa_typestringThe authenticator type used to verify the user's identity
data 1stringThe MFA data (TOTP, SMS, backup, WebAuthn, or password) to be verified

1 For WebAuthn authentication, the data parameter should be a stringified JSON object of the public key credential response.

Response Body
FieldTypeDescription
tokenstringThe MFA verification JWT (expires after 5 minutes)
Example Response
{
"token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzUxMiJ9.eyJpYXQiOjE3MTA4MDY4MDQsIm5iZiI6MTcxMDgwNjgwNCwiZXhwIjoxNzEwODA3MTA0LCJpc3MiOiJ1cm46ZGlzY29yZC1hcGkiLCJhdWQiOiJ1cm46ZGlzY29yZC1tZmEtcmVwcm9tcHQiLCJ1c2VyIjo4NTI4OTIyOTc2NjE5MDY5OTN9.vOCStK0Aj873VaF_cLmSlcnAfw7SO0jrwSeCpkSUvO3li-1jxzwewxY4Ak4fyZvb6VeJtSW-r8_Pfw8HTj8P6w"
}

Send MFA SMS

POST/auth/mfa/sms/send

Sends a multi-factor authentication code to the user's phone number for verification.

JSON Params
FieldTypeDescription
ticketstringThe MFA ticket received from the login request or MFA required response
Response Body
FieldTypeDescription
phonestringThe redacted phone number the SMS was sent to
Example Response
{ "phone": "+*******0085" }