# Discord Userdoccers
# Generated: 2026-08-14T05:17:09.585Z
# Base URL: https://docs.discord.food
# Docs
# Introduction
Link: https://docs.discord.food/
You’ve found the Unofficial Discord User API Documentation! These pages are dedicated to showing you all the ways that you can use Discord to make cool stuff. It is not an official source of information. Automating user accounts is against the platform Terms of Service, so just a heads up: doing so unsafely might get you banned.
While we try our best to not publish any information without basis, quite a lot of the documentation contents are based off of reverse engineering and educated guesses. This means inaccuracies may be present. All of our [documentation is on GitHub](https://github.com/discord-userdoccers/discord-userdoccers) and we <3 corrections and improvements!
The success of this project depends on the community’s contributions. If you have any knowledge of the Discord API, please consider contributing to this project. See [CONTRIBUTING.md](https://github.com/discord-userdoccers/discord-userdoccers/blob/master/CONTRIBUTING.md) for more information.
## Scope
This documentation is not affiliated with or endorsed by Discord in any way. It is a community effort to document the user side of the Discord API, which is not officially supported, as used by the [official client](https://discord.com/app) and [developer portal](https://discord.com/developers/applications).
This means this documentation is focused on the API as it is used by non-bot users, namely with user and bearer authentication tokens. **While bot endpoints may be documented, how bots interact with the API is not the focus of this documentation.**
If bots, interactions, and a semblance of a guarantee that your API endpoint won't break are what you’re looking for, head over to [Discord’s official documentation](https://discord.com/developers/docs/intro).
## Bugs
If you believe you’re experiencing a bug with **a bot-accessible part of the API**, open an issue in the [official documentation issue tracker](https://github.com/discord/discord-api-docs/issues).
## Go Make Cool Stuff!
Discord offers an open API to serve requests for users, bots, and OAuth2 integrations. So whether you’re making your own `!userinfo` command or looking to [rickroll someone](/topics/voice-connections), it has you covered.
So go do it! Go! Go [make an account](/authentication#register) and do something awesome.

This serves as a log of notable changes to the documentation. Does not include content changes.
## Changelog
We added a brand new AMOLED theme for those with OLED screens!
Userdoccers now exposes an MCP server through its Algolia integration.
This allows users to access the documentation through an MCP client, allowing AI assistants to read and understand the documentation more easily.
Access now at: `https://docs.discord.food/mcp`
We introduced an endpoint tester tool to help users experiment with API endpoints directly from the documentation!
Access it by hovering over any endpoint and clicking the "Test" button.
Note that this unfortunately only works with user and bearer tokens due to Discord API restrictions.
Algolia DocSearch has been upgraded to a newer version, bringing with it a slew of improvements, noticeably the addition of AI assistance to help you find what you're looking for faster.
The AI assistant, lovingly referred to as Doxy, is powered by Gemini 2.5 Flash and has access to documentation search results.
Keep in mind that it's still AI and may not always provide accurate information, so it's always a good idea to double-check the results it provides.
We added a new section documenting Discord's JSON error codes and their meanings, searchable and grouped by category.
Access it [here](/topics/errors#json-error-codes)!
As Discord has a very vast collection of error codes that is impossible for us to cover exhaustively,
the page also allows users to submit new error codes they encounter to help expand the documentation.
We introduced code generation for a variety of languages directly on tables. It currently supports the following tables:
- Structures, request bodies, and response bodies: generates an interface representing the structure.
- Enums and flags: generates an enum representing the values.
To use it, hover over any applicable table and click the copy button that appears in the top-right corner.
You can use the language selector to choose your desired programming language.
Note that this feature is currently in an alpha state and may output incorrect or incomplete code.
While it shows up on all tables in the documentation, using it on unsupported tables may lead to unexpected results.
---
# Authentication
Link: https://docs.discord.food/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.
Special care should be taken when handling user credentials and implementing Discord's login & registration flow. Discord does not take kindly to spam in their authentication endpoints, and an improper implementation or suspicious requests can lead to account termination.
## Fingerprints
Discord uses fingerprints to persist experiments throughout the authentication flow. For more information about fingerprints, see the [relevant experiment documentation](/topics/experiments#fingerprints).
If the client is unauthenticated, a fingerprint should be generated using [Get Experiment Assignments](/topics/experiments#get-experiment-assignments) and included in the `X-Fingerprint` header as well as any applicable `fingerprint` JSON parameters until authentication is complete.
## Suspended User Tokens
Suspended user tokens are special tokens issued to users who have been suspended from the platform. These tokens allow users to access [safety hub](/resources/safety-hub) features such as viewing their account standing and appealing their suspension, but cannot be used to access other parts of the platform.
These tokens are not passed in the `Authorization` header like regular authentication tokens, but instead in the body of the request as a `token` parameter.
The actions that can be performed are limited to:
- [Fetching the user's account standing](/resources/safety-hub#get-suspended-user-safety-hub)
- [Requesting a review for an action taken against the user's account](/resources/safety-hub#request-classification-review-for-suspended-user)
- [Completing age verification (for underage suspensions only)](/resources/safety-hub#request-age-verification-for-suspended-user)
## 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](/gateway/gateway-events#ready).
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/gateway-events#auth-session-change) Gateway event.
### Auth Session Object
###### Auth Session Structure
| Field | Type | Description |
| --------------------- | ---------------------------------------------------------------------- | ------------------------------------------- |
| id_hash | string | The session ID hash |
| approx_last_used_time | ISO8601 timestamp | When the session was last used |
| client_info | [auth session client info](#auth-session-client-info-structure) object | The client last associated with the session |
###### Auth Session Client Info Structure
| Field | Type | Description |
| -------- | ------- | ------------------------------------------ |
| os | ?string | The operating system of the client |
| platform | ?string | The name of the client or browser platform |
| location | ?string | The approximate location of the client |
###### Example Auth Session
```json
{
"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
Returns up to 50 of the user's active authentication sessions.
###### Response Body
| Field | Type | Description |
| ------------- | -------------------------------------------------- | ------------------------------------------- |
| user_sessions | array[[auth session](#auth-session-object) object] | Active authentication sessions for the user |
Logout Auth Sessions
Invalidates a list of authentication sessions. Returns a 204 empty response on success.
###### JSON Params
| Field | Type | Description |
| ----------------- | ------------- | ------------------------------------------ |
| session_id_hashes | array[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](#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](#verify-mfa-login) endpoint to complete the login process after a successful response.
If a known [JSON error code](/topics/errors#json-error-codes) 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.
### Passwordless Login
An alternative to the traditional email/password login flow is the WebAuthn Passwordless 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](#start-passwordless-login) endpoint. After the user completes the WebAuthn challenge, the client must use the [Finish Passwordless Login](#finish-passwordless-login) endpoint to complete the login process.
Using this flow, you must still take care to handle any errors as outlined above.
### Authentication Handoff
The handoff process is used to securely transfer the user's authentication state between two clients, commonly used to authenticate the Discord website from a native client and vice-versa.
To handoff authentication to another client, the source client must first use the [Create Handoff Token](#create-handoff-token) endpoint to generate a handoff token.
The token should then be passed to the target client, which can use the [Exchange Handoff Token](#exchange-handoff-token) endpoint to retrieve a new authentication token.
Note that handoff tokens are single-use and valid only for the IP address they were generated from.
### Endpoints
Login Account
Retrieves an authentication token for the given credentials.
If this endpoint is requested with a valid authentication token, a success response will be returned irrespective of the request body.
When first logging into an account (without MFA enabled) from a new location, Discord may reject the login request and require the user to verify the login attempt via email or phone.
If logging in via email, the user will receive a link that redirects to the official Discord client with a verification token present in the URL's fragment (e.g. `https://discord.com/authorize-ip#token=Wzg1Mjg5MjI5NzY2MTkwNjk5MywiMTI3LjAuMC4x8J+RvSJd.kdI8zppMIeTZsIBva3zZslaz_58`).
If logging in via phone number, the request will fail with a [`70007` JSON error code](/topics/errors#json-error-codes), and the user will receive a verification code via SMS.
A verification token should be retrieved by [verifying the phone number](/topics/phone-verification#verify-phone-number).
After [IP authorization](#authorize-ip-address) with this verification token, the login request should be retried. A new CAPTCHA challenge should not be required.
If the user's account is suspended by Discord, the login request will fail with a 403 forbidden and a special error response body, similar to a success response:
```json
{
"user_id": "852892297661906993",
"suspended_user_token": "ODUyODkyMjk3NjYxOTA2OTkz.Hcj0Nl.YEJSsjeq_vJKLpOofd5QMksqw32e"
}
```
Suspended authentication tokens cannot be used as a regular authentication token. They can only be used to view account standing and appeal the account's suspension. See the [Suspended User Tokens](#suspended-user-tokens) section for more information.
###### JSON Params
| Field | Type | Description |
| ----------------- | ------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------- |
| login | string | The user's email or E.164-formatted phone number |
| password | string | The user's password (8-72 characters) |
| undelete? ^1^ | boolean | Whether to undelete a [self-disabled](/resources/user#disable-user-account) or [self-deleted](/resources/user#delete-user-account) account (default false) |
| login_source? | ?string | The [source of the login request](#login-source) |
| gift_code_sku_id? | ?string | The 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](/topics/errors#json-error-codes), you can undelete the account by setting this parameter.
###### Login Source
Where a login is initiated from outside of the normal login flow.
| Value | Description |
| ------------------------- | ------------------------------------------------------------------ |
| gift | Login request initiated from a gift code |
| guild_template | Login request initiated from a guild template |
| guild_invite | Login request initiated from a guild invite |
| dm_invite | Login request initiated from a group DM invite |
| friend_invite | Login request initiated from a friend invite |
| role_subscription | Login request initiated from a role subscription redirect |
| role_subscription_setting | Login request initiated from a role subscription settings redirect |
###### Response Body
| Field | Type | Description |
| ------------------ | -------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| user_id | snowflake | The ID of the user that was logged in |
| token? | string | The authentication token, if the login was completed |
| user_settings? | [login settings](#login-settings-structure) object | The user's partial settings, if the login was completed |
| required_actions? | array[string] | The [required actions](#login-required-action-type) that must be completed before continuing to use Discord |
| ticket? | string | A ticket to be used in the [multi-factor authentication flow](#verify-mfa-login) |
| login_instance_id? | string | The instance ID to be used in the [multi-factor authentication flow](#verify-mfa-login) |
| mfa? | boolean | Whether [multi-factor authentication](#verify-mfa-login) is required to login (default false) |
| totp? | boolean | Whether the user has TOTP-based multi-factor authentication enabled |
| sms? | boolean | Whether the user has SMS-based multi-factor authentication enabled |
| backup? | boolean | Whether backup codes can be used for multi-factor authentication |
| webauthn? | ?string | The stringified JSON [public key credential request options](https://developer.mozilla.org/en-US/docs/Web/API/CredentialsContainer/get#web_authentication_api) challenge for WebAuthn |
###### Login Settings Structure
A partial settings object to bootstrap the client with.
| Field | Type | Description |
| ------ | ------ | ----------------------------------------------------------------------- |
| locale | string | The [language option](/reference#locales) chosen by the user |
| theme | string | The [client theme](/resources/user-settings#theme) selected by the user |
###### Login Required Action Type
Actions the user must complete after a successful login.
| Value | Description |
| --------------- | ------------------------------------------------------------------------------- |
| update_password | The user must change their password to meet Discord's new password requirements |
###### Example Response (Completed)
```json
{
"user_id": "852892297661906993",
"token": "ODUyODkyMjk3NjYxOTA2OTkz.GX5Xdp.22jsdSqEiHLUYEJSsjeq_vJKLpOofd5QMksqw32e",
"user_settings": {
"locale": "en-US",
"theme": "midnight"
},
"required_actions": ["update_password"]
}
```
###### Example Response (MFA Required)
```json
{
"user_id": "852892297661906993",
"mfa": true,
"sms": true,
"ticket": "ODUyODkyMjk3NjYxOTA2OTkz.H2Rpq0.WrhGhYEhM3lHUPN61xF6JcQKwVutk8fBvcoHjo",
"login_instance_id": "c438b7cd-4963-4379-b71a-5cd32b8225cb",
"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\"}}"
}
```
Verify MFA Login
Verifies a multi-factor login and retrieves an authentication token using the specified [authenticator type](#authenticator-type).
To verify using SMS MFA, you must first send a code to the user's phone number using the [Send MFA SMS](#send-mfa-sms) endpoint.
If the user's account is suspended by Discord, the login request will fail with a 403 forbidden and a special error response body, similar to a success response:
```json
{ "suspended_user_token": "ODUyODkyMjk3NjYxOTA2OTkz.Hcj0Nl.YEJSsjeq_vJKLpOofd5QMksqw32e" }
```
Suspended authentication tokens cannot be used as a regular authentication token. They can only be used to view account standing and appeal the account's suspension. See the [Suspended User Tokens](#suspended-user-tokens) section for more information.
###### JSON Params
| Field | Type | Description |
| ------------------ | ------- | ----------------------------------------------------------------------- |
| ticket | string | The MFA ticket received from the [login request](#login-account) |
| login_instance_id? | string | The login instance ID received from the [login request](#login-account) |
| code ^1^ | string | The MFA code (TOTP, SMS, backup, or WebAuthn) to be verified |
| login_source? | ?string | The [source of the login request](#login-source) |
| gift_code_sku_id? | ?string | The 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](https://developer.mozilla.org/en-US/docs/Web/API/PublicKeyCredential/toJSON).
###### Response Body
| Field | Type | Description |
| ------------- | -------------------------------------------------- | --------------------------- |
| token | string | The authentication token |
| user_settings | [login settings](#login-settings-structure) object | The user's partial settings |
###### Example Response (Completed)
```json
{
"token": "ODUyODkyMjk3NjYxOTA2OTkz.GX5Xdp.22jsdSqEiHLUYEJSsjeq_vJKLpOofd5QMksqw32e",
"user_settings": {
"locale": "en-US",
"theme": "dark"
}
}
```
Start Passwordless Login
Generates a challenge to start the passwordless flow for WebAuthn login.
If this endpoint is requested with a valid authentication token, an [authentication token](<#example-response-(completed)>) will be returned irrespective of the request body.
###### Response Body
| Field | Type | Description |
| --------- | ------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| ticket | string | The WebAuthn login ticket |
| challenge | string | The stringified JSON [public key credential request options](https://developer.mozilla.org/en-US/docs/Web/API/CredentialsContainer/get#web_authentication_api) challenge for WebAuthn |
###### Example Response
```json
{
"challenge": "{\"publicKey\":{\"challenge\":\"sLPruFUWBzowZjYy5d2caF2067pw44butrN0iHm_8k4\",\"timeout\":60000,\"rpId\":\"discord.com\",\"allowCredentials\":[],\"userVerification\":\"required\",\"extensions\":{\"uvm\":true}}}",
"ticket": "b9f98b82-c3a7-49b6-b881-f83418fa2dbe"
}
```
Start Conditional Login
Generates a challenge to start the conditional UI flow for WebAuthn login.
If this endpoint is requested with a valid authentication token, an [authentication token](<#example-response-(completed)>) will be returned irrespective of the request body.
Unlike [Start Passwordless Login](#start-passwordless-login), the `challenge` returned by this endpoint has
[`mediation`](https://developer.mozilla.org/en-US/docs/Web/API/CredentialsContainer/get#mediation) set to `conditional`.
This causes [conditional mediation](https://developer.mozilla.org/en-US/docs/Web/API/Web_Authentication_API#autofill_ui),
requiring user interaction before a passkey can be selected.
###### Response Body
| Field | Type | Description |
| --------- | ------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| ticket | string | The WebAuthn login ticket |
| challenge | string | The stringified JSON [public key credential request options](https://developer.mozilla.org/en-US/docs/Web/API/CredentialsContainer/get#web_authentication_api) challenge for WebAuthn |
###### Example Response
```json
{
"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
Retrieves an authentication token for the given WebAuthn credentials.
If this endpoint is requested with a valid authentication token, a success response will be returned irrespective of the request body.
If the user's account is suspended by Discord, the login request will fail with a 403 forbidden and a special error response body, similar to a success response:
```json
{ "suspended_user_token": "ODUyODkyMjk3NjYxOTA2OTkz.Hcj0Nl.YEJSsjeq_vJKLpOofd5QMksqw32e" }
```
Suspended authentication tokens cannot be used as a regular authentication token. They can only be used to view account standing and appeal the account's suspension. See the [Suspended User Tokens](#suspended-user-tokens) section for more information.
###### JSON Params
| Field | Type | Description |
| ----------------- | ------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| ticket | string | The WebAuthn login ticket received from the [Start Passwordless Login](#start-passwordless-login) or [Start Conditional Login](#start-conditional-login) endpoint |
| credential | string | The stringified JSON [public key credential response](https://developer.mozilla.org/en-US/docs/Web/API/PublicKeyCredential/toJSON) for WebAuthn |
| login_source? | ?string | The [source of the login request](#login-source) |
| gift_code_sku_id? | ?string | The SKU ID of the gift code that initiated the login request |
###### Response Body
| Field | Type | Description |
| ----------------- | -------------------------------------------------- | ----------------------------------------------------------------------------------------------------------- |
| user_id | snowflake | The ID of the user that was logged in |
| token | string | The authentication token |
| user_settings | [login settings](#login-settings-structure) object | The user's partial settings |
| required_actions? | array[string] | The [required actions](#login-required-action-type) that must be completed before continuing to use Discord |
###### Example Response
```json
{
"user_id": "852892297661906993",
"token": "ODUyODkyMjk3NjYxOTA2OTkz.GX5Xdp.22jsdSqEiHLUYEJSsjeq_vJKLpOofd5QMksqw32e",
"user_settings": {
"locale": "en-US",
"theme": "dark"
},
"required_actions": ["update_password"]
}
```
Authorize IP Address
Authorizes the client's IP address for login. Returns a 204 empty response on success.
###### JSON Params
| Field | Type | Description |
| ----- | ------ | ----------------------------------------------------------------------------------- |
| token | string | The verification token received from the email or phone number verification process |
Create Handoff Token
Creates a handoff token to transfer the user's authentication state to another client.
###### JSON Params
| Field | Type | Description |
| ----- | ------ | ----------------------------------------------------------------- |
| key | string | A unique key to identify the handoff request (e.g. a random UUID) |
###### Response Body
| Field | Type | Description |
| ------------- | ------ | ---------------------------------------------------------------------------- |
| handoff_token | string | The handoff token to pass to the target; this is not an authentication token |
Exchange Handoff Token
Exchanges a handoff token for an authentication token. Handoff tokens can only be exchanged once and are only valid from the same IP address they were created from.
###### JSON Params
| Field | Type | Description |
| ------------- | ------ | ------------------------------------------------------------------------------------------ |
| key | string | The unique key used to create the handoff token |
| handoff_token | string | The handoff token received from the [Create Handoff Token](#create-handoff-token) endpoint |
###### Response Body
| Field | Type | Description |
| ----- | -------------------------------------------------- | ------------------------------- |
| token | string | The authentication token |
| user | partial [user](/resources/user#user-object) object | The user that was authenticated |
## 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](#get-location-metadata) to determine whether explicit consent is required.
Then, they can use the [Register Account](#register-account) endpoint to create a new account with the provided credentials.
Throughout the process, they can use the [Get Unique Username Suggestions](#get-unique-username-suggestions) to get username suggestions for the user's display name and [Get Unique Username Eligibility](#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 Account with Phone Number](#register-account-with-phone-number) endpoint to send a verification code to the user's phone number.
Then, the client must [verify the phone number](/topics/phone-verification#verify-phone-number) using the received code before completing the registration using the [Register Account](#register-account) endpoint as usual.
### Endpoints
Register Account
Creates a new account and retrieves an authentication token for the given credentials.
If this endpoint is requested with a valid authentication token, a success response will be returned irrespective of the request body.
Accounts should only be registered for a user to immediately use. Upon registration, the client should immediately connect to the Gateway using the retrieved authentication token.
Suspicious account creations may be flagged by Discord and require [additional verification steps](/resources/user#required-action-type) or lead to immediate account termination.
###### JSON Params
| Field | Type | Description |
| ----------------------------- | ------------ | ------------------------------------------------------------------------------------------------------------------------------------ |
| username? ^1^ | string | The username to register (default random) |
| global_name? ^1^ | ?string | The display name to register |
| email? | string | The user's email address |
| phone_token? | string | The phone verification token received from the [phone registration flow](#phone-registration) |
| password? | string | The user's password (8-72 characters) |
| date_of_birth? | ISO8601 date | The user's date of birth |
| fingerprint? ^2^ | string | The fingerprint to use for registration |
| invite? ^3^ | ?string | The invite code that initiated the registration |
| guild_template_code? | ?string | The guild template code that initiated the registration |
| gift_code_sku_id? | ?string | The SKU ID of the gift code that initiated the registration |
| consent? ^4^ | boolean | Whether the user agrees to Discord's [Terms of Service](https://discord.com/terms) and [Privacy Policy](https://discord.com/privacy) |
| promotional_email_opt_in? ^4^ | boolean | Whether 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](#get-unique-username-suggestions) endpoint and validated using the [Get Unique Username Eligibility](#get-unique-username-eligibility) endpoint. See the [Usernames and Nicknames section](/resources/user#usernames-and-nicknames) for more information on username restrictions.
^2^ This value should be set [to the same fingerprint used throughout the authentication flow](#fingerprints). 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](#get-location-metadata) endpoint.
###### Response Body
| Field | Type | Description |
| ----------------------- | ------- | ---------------------------------------------------------------------------- |
| token | string | The authentication token |
| show_verification_form? | boolean | Whether the user should be shown the joined guild's member verification form |
###### Example Response
```json
{
"token": "ODUyODkyMjk3NjYxOTA2OTkz.GX5Xdp.22jsdSqEiHLUYEJSsjeq_vJKLpOofd5QMksqw32e",
"show_verification_form": true
}
```
Register Account with Phone Number
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](/topics/phone-verification#verify-phone-number) before [completing the registration](#register-account).
###### JSON Params
| Field | Type | Description |
| ----- | ------ | --------------------------------------- |
| phone | string | The user's E.164-formatted phone number |
Get Location Metadata
Returns the location metadata for the user's IP address.
###### Response Body
| Field | Type | Description |
| ------------------------ | -------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| country_code | string | The [ISO 3166-1 alpha-2](https://en.wikipedia.org/wiki/ISO_3166-1_alpha-2) country code of the user's IP address |
| consent_required | boolean | Whether the user must explicitly agree to Discord's [Terms of Service](https://discord.com/terms) and [Privacy Policy](https://discord.com/privacy) in order to register |
| promotional_email_opt_in | [promotional email metadata](#promotional-email-metadata-structure) object | Promotional email consent metadata |
###### Promotional Email Metadata Structure
| Field | Type | Description |
| ----------- | ------- | ----------------------------------------------------------------------------------------------------- |
| required | boolean | Whether the user must explicitly agree to receive promotional emails from Discord |
| pre_checked | boolean | Whether the promotional email consent checkbox should be pre-checked, if explicit consent is required |
###### Example Response
```json
{
"consent_required": false,
"country_code": "CA",
"promotional_email_opt_in": {
"required": true,
"pre_checked": false
}
}
```
Get Password Strength
Validates the strength of a password and returns a score based on its complexity. This is used to ensure that the user's password meets Discord's security requirements.
###### JSON Params
| Field | Type | Description |
| -------- | ------ | ------------------------------------------ |
| password | string | The password to validate (8-72 characters) |
###### Response Body
| Field | Type | Description |
| ----------------- | ------- | -------------------------------------------------------------------------- |
| valid | boolean | Whether the password is valid according to Discord's security requirements |
| password_strength | integer | The password strength score (0-4) |
Get Unique Username Suggestions
Returns a suggested unique username string for the user to register with.
###### Query String Params
| Field | Type | Description |
| ------------ | ------ | -------------------------------------------------------------------- |
| global_name? | string | The global name to base the username suggestions on (default random) |
###### Response Body
| Field | Type | Description |
| -------- | ------ | ---------------------- |
| username | string | The suggested username |
###### Example Response
```json
{ "username": "gnarp.gnap" }
```
Get Unique Username Eligibility
Checks whether a unique username is available for the user to register with.
See the [Usernames and Nicknames section](/resources/user#usernames-and-nicknames) for more information on username restrictions.
###### JSON Params
| Field | Type | Description |
| -------- | ------ | --------------------- |
| username | string | The username to check |
###### Response Body
| Field | Type | Description |
| ----- | -------- | ----------------------------- |
| taken | ?boolean | Whether the username is taken |
###### Example Response
```json
{ "taken": true }
```
## Logout
To log out, the client must use the [Logout](#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](/topics/push-notifications) for more information.
### Endpoints
Logout
Invalidates the given authentication session and unregisters the provided push notification token.
###### JSON Params
| Field | Type | Description |
| ------------------ | ------ | --------------------------------------------------------------------------------------------------------------------- |
| provider? | string | The [push notification provider](/topics/push-notifications#push-notification-provider) to revoke |
| token? | string | The push notification token to unregister |
| voip_provider? ^1^ | string | The VOIP [push notification provider](/topics/push-notifications#push-notification-provider) to revoke the token from |
| voip_token? ^1^ | string | The VOIP push notification token to unregister |
^1^ VOIP-specific push notification tokens are only used with PushKit on iOS.
## Password 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](#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](#reset-password) endpoint to set a new password.
If eligible, the user can optionally skip the password reset step and use the one-time login token sent to their email with the [One-Time Login](#one-time-login) endpoint.
### Endpoints
Forgot Password
Initiates the password reset process for the given email or phone number. For accounts without MFA, users will optionally be able to skip the reset flow using a one-time login ticket.
If providing an email, the user will receive a link that redirects to the official Discord client with a verification token present in the URL's fragment (e.g. `https://discord.com/reset#token=eyJpZCI6ODUyODkyMjk3NjYxOTA2OTkzLCJlbWFpbCI6Im5lbGx5QGRpc2NvcmRhcHAuY29tIn0.Z6pQDg.pKCZBaaiodflO6FZhdttm6B_z74`).
If providing a phone number, the request will fail with a [`70007` JSON error code](/topics/errors#json-error-codes), and the user will receive a verification code via SMS.
A verification token should be retrieved by [verifying the phone number](/topics/phone-verification#verify-phone-number).
If the user is ineligible to reset their password via phone number, the phone number verification request will fail with a [`70009` JSON error code](/topics/errors#json-error-codes) and the user will receive a link to reset their password via email.
###### JSON Params
| Field | Type | Description |
| ----- | ------ | ------------------------------------------------ |
| login | string | The user's email or E.164-formatted phone number |
###### Response Body
| Field | Type | Description |
| ------ | ------ | ---------------------------------------------------- |
| method | string | The [reset methodology](#password-reset-method) used |
###### Password Reset Method
| Value | Description |
| -------------- | --------------------------------------------------------------------------------------------------- |
| password_reset | Standard password reset flow |
| one_time_login | Email includes an additional link with a one-time login token present in the URL's query parameters |
Reset Password
Resets the user's password and retrieves an authentication token.
When attempting to reset the password of a user with multi-factor authentication enabled, the request will return a response similar to the [MFA Required response](#mfa-verification).
To complete the password reset, the client must retry the request with the `ticket` and `code` parameters specified.
###### JSON Params
| Field | Type | Description |
| ----------------------- | ------ | ---------------------------------------------------------------------------------------------------------- |
| token | string | The password reset token received from the email or phone number verification |
| password | string | The user's new password (8-72 characters) |
| source? | string | The source path the password reset was initiated from (e.g. `/reset`) |
| method? | string | The [authenticator type](#authenticator-type) to use for MFA verification |
| ticket? | string | The MFA ticket received from the previous request |
| code? ^1^ | string | The MFA code (TOTP, SMS, backup, or WebAuthn) to be verified |
| push_provider? ^2^ | string | The [push notification provider](/topics/push-notifications#push-notification-provider) of the device |
| push_token? ^2^ | string | The push notification token to register |
| push_voip_provider? ^2^ | string | The VOIP [push notification provider](/topics/push-notifications#push-notification-provider) of the device |
| push_voip_token? ^2^ | string | The VOIP push notification token to register |
^1^ For WebAuthn authentication, the `code` parameter should be a stringified JSON object of the [public key credential response](https://developer.mozilla.org/en-US/docs/Web/API/PublicKeyCredential/toJSON).
^2^ Mobile clients attach the device's push notification token to this request, since it returns a new authentication token. See [registering tokens](/topics/push-notifications#registering-tokens) for more information.
###### Response Body
| Field | Type | Description |
| --------- | --------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| token? | string | The authentication token, if the password reset was completed |
| user_id? | snowflake | The ID of the user whose password was reset, if MFA verification is required |
| ticket? | string | A ticket to be used when retrying the request with multi-factor authentication |
| mfa? | boolean | Whether multi-factor authentication is required to reset the password (default false) |
| totp? | boolean | Whether the user has TOTP-based multi-factor authentication enabled |
| sms? | boolean | Whether the user has SMS-based multi-factor authentication enabled |
| backup? | boolean | Whether backup codes can be used for multi-factor authentication |
| webauthn? | ?string | The stringified JSON [public key credential request options](https://developer.mozilla.org/en-US/docs/Web/API/CredentialsContainer/get#web_authentication_api) challenge for WebAuthn |
###### Example Response (Completed)
```json
{ "token": "ODUyODkyMjk3NjYxOTA2OTkz.GX5Xdp.22jsdSqEiHLUYEJSsjeq_vJKLpOofd5QMksqw32e" }
```
###### Example Response (MFA Required)
```json
{
"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\"}}"
}
```
One-Time Login
Consumes a one-time login token to retrieve an authentication token.
###### JSON Params
| Field | Type | Description |
| ------ | ------ | ------------------------------------------------ |
| ticket | string | The one-time login token received from the email |
###### Response Body
| Field | Type | Description |
| ----- | ------ | ------------------------ |
| token | string | The authentication token |
## Account Recovery
Account recovery is a feature intended for post-takeover recovery after an attacker has already changed the victim's email, password, phone number or MFA settings.
Upon an email change, Discord will email the victim about the change and give them the option to start the account recovery process.
The email will include a link that redirects to the official Discord client with a revert token present in the URL (e.g. `https://discord.com/wasntme/BIGJWTHERE`).
This token is valid for two days.
This token can be used with the [Revert Account](#revert-account) endpoint to revert the account back to the previous settings.
Upon completion, the current phone number is removed from the account and all phone numbers previously associated with the account are blacklisted. This prevents a follow-up takeover via [sim-jacking](https://en.wikipedia.org/wiki/SIM_swap_scam).
### Endpoints
Revert Account
Recovers an account after account takeover. This endpoint will:
- Invalidate the revert token used
- Invalidate all authorization tokens and active Gateway sessions associated with the account
- Set the account's email back to the original
- Set the account's password to the one provided
- Remove MFA from the account
- Remove and blacklist all phone numbers previously associated with the account
This process will fail if the account was deleted beforehand (e.g. by anti-spam or a Discord employee) or the original email was assigned to a different account.
###### JSON Params
| Field | Type | Description |
| -------- | ------ | ---------------------------------------- |
| token | string | The revert token from the recovery email |
| password | string | The new password for the account |
###### Response Body
| Field | Type | Description |
| ----- | ------ | ---------------------------- |
| email | string | The account's restored email |
###### Example Response
```json
{ "email": "alien@shiroko.me" }
```
## 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
| Field | Type | Description |
| ------- | ---------------------------------------------------------------------- | ------------------------------------------------------------------------------- |
| message | string | A message saying that multi-factor authentication is required for the operation |
| code | integer | An [error code](/topics/errors#json) (will always be `60003`) |
| mfa | [MFA verification request](#mfa-verification-request-structure) object | The multi-factor authentication verification request |
###### MFA Verification Request Structure
| Field | Type | Description |
| ------- | ------ | ----------------------------------------------------------------------------------------------- |
| ticket | string | The MFA ticket |
| methods | array | An array of [MFA methods](#mfa-method-structure) that can be used to verify the user's identity |
###### MFA Method Structure
| Field | Type | Description |
| --------------------- | ------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| type | string | The [type of MFA method](#authenticator-type) that can be used to verify the user's identity |
| challenge? | string | The stringified JSON [public key credential request options](https://developer.mozilla.org/en-US/docs/Web/API/CredentialsContainer/get#web_authentication_api) challenge for WebAuthn |
| backup_codes_allowed? | boolean | Whether backup codes can be used in addition to TOTP codes |
###### Authenticator Type
| Value | Description |
| ------------ | --------------------------------------------------------------------------------------------------------------- |
| totp | Verification using a [TOTP](https://en.wikipedia.org/wiki/Time-based_One-Time_Password) code or backup code |
| sms | Verification using a code sent to the user's phone number via SMS |
| backup | Verification using a backup code |
| webauthn | Verification using a [WebAuthn](https://developer.mozilla.org/en-US/docs/Web/API/Web_Authentication_API) device |
| password ^1^ | Verification 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
```json
{
"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](#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
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
| Field | Type | Description |
| -------- | ------ | ------------------------------------------------------------------------------------------ |
| ticket | string | The MFA ticket received from the [MFA required response](#mfa-required-response-structure) |
| mfa_type | string | The [authenticator type](#authenticator-type) used to verify the user's identity |
| data ^1^ | string | The 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](https://developer.mozilla.org/en-US/docs/Web/API/PublicKeyCredential/toJSON).
###### Response Body
| Field | Type | Description |
| ----- | ------ | -------------------------------------------------- |
| token | string | The MFA verification JWT (expires after 5 minutes) |
###### Example Response
```json
{
"token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzUxMiJ9.eyJpYXQiOjE3MTA4MDY4MDQsIm5iZiI6MTcxMDgwNjgwNCwiZXhwIjoxNzEwODA3MTA0LCJpc3MiOiJ1cm46ZGlzY29yZC1hcGkiLCJhdWQiOiJ1cm46ZGlzY29yZC1tZmEtcmVwcm9tcHQiLCJ1c2VyIjo4NTI4OTIyOTc2NjE5MDY5OTN9.vOCStK0Aj873VaF_cLmSlcnAfw7SO0jrwSeCpkSUvO3li-1jxzwewxY4Ak4fyZvb6VeJtSW-r8_Pfw8HTj8P6w"
}
```
Send MFA SMS
Sends a multi-factor authentication code to the user's phone number for verification.
###### JSON Params
| Field | Type | Description |
| ------ | ------ | ----------------------------------------------------------------------------------------------------------------------------- |
| ticket | string | The MFA ticket received from the [login request](#login-account) or [MFA required response](#mfa-required-response-structure) |
###### Response Body
| Field | Type | Description |
| ----- | ------ | --------------------------------------------- |
| phone | string | The redacted phone number the SMS was sent to |
###### Example Response
```json
{ "phone": "+*******0085" }
```
---
# API Reference
Link: https://docs.discord.food/reference
Discord's API is based around two core layers, a HTTPS/REST API for general operations, and persistent secure WebSocket based connection for sending and subscribing to real-time events. The most common use case of the Discord API will be providing a service, or access to a platform through the [OAuth2](https://oauth.net/2/) API.
###### Base URL
Discord offers a canary API for testing changes before they are pushed to the regular API. The canary API is not guaranteed to be stable, and can be used at the dedicated URL or [with debug options](#debugging).
```
Stable: https://discord.com/api
Canary: https://canary.discord.com/api
```
## API Versioning
Some API and Gateway versions are now non-functioning, and are labeled as discontinued in the table below for posterity. Trying to use these versions will fail and return a 400 bad request.
Discord exposes different versions of the API[.](https://c.tenor.com/BuZl66EegkgAAAAC/westworld-dolores.gif) You should specify which version to use by including it in the request path like `https://discord.com/api/v{version_number}`. Omitting the version number from the route will route requests to the current default version (marked below).
###### API Versions
| Version | Status | Default |
| ------- | ------------ | -------- |
| 10 | Available | |
| 9 | Available | ✓ Client |
| 8 | Deprecated | |
| 7 | Deprecated | |
| 6 | Deprecated | ✓ API |
| 5 | Discontinued | |
| 4 | Discontinued | |
| 3 | Discontinued | |
## Error Messages
Starting in API v7, form error responses have improved error formatting. The response will tell you which JSON key contains the error, the error code, and a human readable error message. Discord is frequently adding new error messages, so a complete list of errors is not feasible and would be almost instantly out of date. Here are some examples instead:
###### Array Error
```json
{
"code": 50035,
"errors": {
"activities": {
"0": {
"platform": {
"_errors": [
{
"code": "BASE_TYPE_CHOICES",
"message": "Value must be one of ('desktop', 'android', 'ios')."
}
]
},
"type": {
"_errors": [
{
"code": "BASE_TYPE_CHOICES",
"message": "Value must be one of (0, 1, 2, 3, 4, 5)."
}
]
}
}
}
},
"message": "Invalid Form Body"
}
```
###### Object Error
```json
{
"code": 50035,
"errors": {
"access_token": {
"_errors": [
{
"code": "BASE_TYPE_REQUIRED",
"message": "This field is required"
}
]
}
},
"message": "Invalid Form Body"
}
```
###### Request Error
```json
{
"code": 50035,
"message": "Invalid Form Body",
"errors": {
"_errors": [
{
"code": "APPLICATION_COMMAND_TOO_LARGE",
"message": "Command exceeds maximum size (4000)"
}
]
}
}
```
## Authentication
Authenticating with the Discord API can be done in one of two ways:
1. Using a user or bot token gained by [logging into an account](/authentication) or [registering a bot](https://discord.com/developers/applications?new_application=true). For more information on users and bots, see [bots vs user accounts](/topics/oauth2#bot-vs-user-accounts).
2. Using an OAuth2 bearer token gained through the [OAuth2 API](/topics/oauth2#oauth2).
For all authentication types, authentication is performed with the `Authorization` HTTP header in the format `Authorization: TOKEN_TYPE? TOKEN`.
###### Example User Token Authorization Header
```
Authorization: MTk4NjIyNDgzNDcxOTI1MjQ4.Cl2FMQ.ZnCjm1XVW7vRze4b7Cq4se7kKWs
```
###### Example Bot Token Authorization Header
```
Authorization: Bot MTk4NjIyNDgzNDcxOTI1MjQ4.Cl2FMQ.ZnCjm1XVW7vRze4b7Cq4se7kKWs
```
###### Example Bearer Token Authorization Header
```
Authorization: Bearer ODkxNDM2MjMzOTAzOTY0MTYx.pXvaXIpme43oSHZLXDCK7IiKA8iAjr
```
## Encryption
All HTTP-layer services and protocols (e.g. HTTP, WebSocket) within the Discord API are using TLS 1.2.
## Snowflake Format
Discord utilizes Twitter's [snowflake](https://github.com/twitter/snowflake/tree/snowflake-2010) format for uniquely identifiable descriptors (IDs). These IDs are guaranteed to be unique across all of Discord, except in some specific scenarios in which child objects share their parent's ID. Because Snowflake IDs are up to 64 bits in size (e.g. a uint64), they are always returned as strings in the HTTP API to prevent integer overflows in some languages. See [the Gateway documentation](/gateway/using-gateway#encoding-and-compression) for more information regarding Gateway encoding.
###### Snowflake ID Broken Down in Binary
```
111111111111111111111111111111111111111111 11111 11111 111111111111
64 22 17 12 0
```
###### Snowflake ID Format Structure (Left to Right)
| Field | Bits | Number of bits | Description | Retrieval |
| ------------------- | -------- | -------------- | ---------------------------------------------------------------------------- | ----------------------------------- |
| Timestamp | 63 to 22 | 42 bits | Milliseconds since Discord Epoch, the first second of 2015 or 1420070400000. | `(snowflake >> 22) + 1420070400000` |
| Internal worker ID | 21 to 17 | 5 bits | | `(snowflake & 0x3E0000) >> 17` |
| Internal process ID | 16 to 12 | 5 bits | | `(snowflake & 0x1F000) >> 12` |
| Increment | 11 to 0 | 12 bits | For every ID that is generated on that process, this number is incremented | `snowflake & 0xFFF` |
#### Convert Snowflake to DateTime
#### Snowflake IDs in Pagination
Discord typically uses snowflake IDs in many API routes for pagination. The standardized pagination paradigm utilized is one in which you can specify IDs `before` and `after` in combination with `limit` to retrieve a desired page of results. You will want to refer to the specific endpoint documentation for details.
It is useful to note that snowflake IDs are just numbers with a timestamp, so when dealing with pagination where you want results from the beginning of time (in Discord Epoch, but `0` works here too) or before/after a specific time you can generate a snowflake ID for that time.
If the endpoint supports multiple pagination arguments, any `before`, `after`, and `around` keys are mutually exclusive (only one may be used at a time). If multiple are provided, only `around` or `before` is respected.
###### Generating a Snowflake ID from a Timestamp Example
```
(timestamp_ms - DISCORD_EPOCH) << 22
```
## ID Serialization
There are some cases in which the API and Gateway may return IDs in an unexpected format. Internally, Discord stores IDs as integer snowflakes. When IDs are serialized to JSON, `bigints` are transformed into strings. Given that all Discord IDs are snowflakes, you should always expect a string.
However, there are cases in which passing something to the API will instead return IDs serialized as an integer; this is the case when you send the API or Gateway a value in an `id` field that is not `bigint` size. For example, when requesting `GUILD_MEMBERS_CHUNK` from the gateway:
```js
// Send
{
op: 8,
d: {
guild_id: [ '308994132968210433' ],
user_ids: [ '123123' ]
}
}
// Receive
{
t: 'GUILD_MEMBERS_CHUNK',
s: 3,
op: 0,
d: {
not_found: [ 123123 ],
members: [],
guild_id: '308994132968210433'
}
}
```
You can see in this case that the sent `user_id` is not a `bigint`; therefore, when it is serialized back to JSON by Discord, it is not transformed into a string.
## Magic Snowflakes
Certain snowflake IDs are constants that have special meaning throughout the API. While this is not an exhaustive list, the following are important to note:
| Resource | ID | Description |
| -------------------------------------------------------- | --------------------- | --------------------------------- |
| [User](/resources/user#user-object) | `456226577798135808` | Deleted user sentinel account |
| [User](/resources/user#user-object) | `643945264868098049` | Official Discord system account |
| [User](/resources/user#user-object) | `669627189624307712` | Community Updates system account |
| [User](/resources/user#user-object) | `1008776202191634432` | AutoMod system account |
| [User](/resources/user#user-object) | `1081004946872352958` | Clyde AI bot |
| [User](/resources/user#user-object) | `1232523165893132288` | Discord Updates system account |
| [Application](/resources/application#application-object) | `521842831262875670` | Premium subscriptions application |
| [Application](/resources/application#application-object) | `545364944258990091` | Discord Developers application |
| [Application](/resources/application#application-object) | `710982414301790216` | Stickers application |
| [Application](/resources/application#application-object) | `834488117758001152` | Ticketed Events application |
| [Application](/resources/application#application-object) | `1096190356233670716` | Collectibles application |
| [Application](/resources/application#application-object) | `1225629272358518784` | Quest Reward Codes application |
| [Application](/resources/application#application-object) | `1340102344645283891` | Guild Powerups application |
| [Application](/resources/application#application-object) | `622174530214821906` | Xbox integration |
| [Application](/resources/application#application-object) | `1008890872156405890` | PlayStation integration |
| [Application](/resources/application#application-object) | `984193235868065795` | PlayStation integration (staging) |
| [Guild](/resources/guild#guild-object) | `667560445975986187` | Community Updates guild |
## ISO8601 Datetime
Discord utilizes the [ISO8601 format](https://www.loc.gov/standards/datetime/iso-tc154-wg5_n0038_iso_wd_8601-1_2016-02-16.pdf) for most datetimes returned in the API. This format is referred to as type `ISO8601` within tables in this documentation.
## Consistency
Discord operates at a scale where true consistency is impossible. Because of this, lots of operations in the API and in-between API services are [eventually consistent](https://en.wikipedia.org/wiki/Eventual_consistency). Due to this, client actions can never be serialized and may be executed in _any_ order (if executed at all). Along with these constraints, events in Discord may:
- Never be sent to a client
- Be sent _exactly_ one time to the client
- Be sent up to _N_ times per client
Clients should operate on events and results from the API in as much of an idempotent behavior as possible.
## HTTP API
#### User Agent
Clients using the HTTP API should provide a valid [User Agent](https://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.43) which specifies information about the client.
For bots, it must contain the string `DiscordBot`. For user accounts, see the [Client Properties](#client-properties) section.
###### Bot User Agent Example
```
User-Agent: DiscordBot ($url, $versionNumber)
```
Clients may append more information and metadata to this string as they wish.
#### Rate Limiting
The HTTP API implements a process for limiting and preventing excessive requests in accordance with [RFC 6585](https://tools.ietf.org/html/rfc6585#section-4). API users that regularly hit and ignore rate limits will have their API keys revoked, and be blocked from the platform. For more information on rate limiting of requests, please see the [Rate Limits](/topics/rate-limits#rate-limits) section.
#### Boolean Query Strings
Certain endpoints in the API are documented to accept booleans for their query string parameters. While there is no standard system for boolean representation in query string parameters, Discord represents such cases using `True`, `true`, or `1` for true and `False`, `false` or `0` for false.
#### Debugging
The HTTP API accepts an optional `X-Debug-Options` header with a comma-delimited list of debug options. The options in this list can be arbitrary, but the below options have effects:
| Value | Description |
| ------ | ------------------------------------------------------ |
| canary | Forcefully routes the request to the canary API |
| trace | Forcefully [traces the request with APM](#apm-tracing) |
All API responses include a `X-Discord-Features` header which contains the name of the API feature that the request was routed to.
###### APM Tracing
Discord offers an APM (Application Performance Monitoring) service that allows Discord employees to view traces of requests made to the API. This is useful for debugging issues with the API, and can be enabled by setting `trace` in the `X-Debug-Options` header as described above.
When tracing requests, you must provide an additional `X-Client-Trace-ID` header with a unique identifier for the request. This identifier can be generated with the following pseudocode:
```py
import base64
import random
import struct
import time
class IDGenerator:
def __init__(self):
self.prefix = random.randint(0, 0xFFFFFFFF) & 0xFFFFFFFF
self.creation_time = int(time.time() * 1000)
self.sequence = 0
def generate(self, user_id: int = 0):
uuid = bytearray(24)
# Lowest signed 32 bits
struct.pack_into("> 32)
struct.pack_into("> 32)
struct.pack_into("
The ability to view APM traces is only available to Discord employees.
## Gateway API
Discord's Gateway API is used for maintaining persistent, stateful WebSocket connections between your client and Discord servers. These connections are used for sending and receiving real-time events your client can use to track and update local state. The Gateway API uses secure WebSocket connections as specified in [RFC 6455](https://tools.ietf.org/html/rfc6455). For information on opening Gateway connections, please see the [Gateway API](/gateway/using-gateway#connections) section.
## Client Properties
Client properties, or "super properties", contain tracking information about the current client, used for analytics and A/B testing purposes. These properties are sent when [identifying](/gateway/using-gateway#identifying) with the Gateway and are included with every outgoing HTTP request using the `X-Super-Properties` header as a base64-encoded JSON object.
When these properties are not provided, Discord will attempt to parse some of them from the `User-Agent` header of requests.
While including this header is not required, it is highly recommended due to its significance in anti-abuse systems. Additionally, many experimental features require a recent client build number to be specified in this header to function.
###### Client Properties Structure
Due to the nature of client properties, the structure of this object is not well-defined, and no field is truly required.
Additionally, types of fields are not verified, and all documented enums are merely conventions. Fields are marked as required if it's observed that they are sent in all official client properties.
| Field | Type | Description |
| ----------------------------------------------- | -------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| os ^1^ | string | The [operating system of the client](#operating-system-type) |
| os_version? | string | The operating system version (kernel version for Linux, SDK version for Android) |
| os_sdk_version? | string | The operating system SDK version |
| os_arch? | string | The architecture of the operating system |
| app_arch? | string | The architecture of the desktop application |
| browser | string | The [browser the client is using](#browser-type) |
| browser_user_agent ^2^ | string | The user-agent of the client's browser, may be blank on mobile clients |
| browser_version | string | The version of the client's browser, may be blank on mobile clients |
| client_build_number ^1^ | integer | The build number of the client |
| native_build_number? | ?integer | The [native metadata version](/topics/client-distribution#get-latest-distributed-application-manifest) of the desktop client, if using the new update system |
| client_version? ^1^ | string | The mobile client version |
| client_event_source? | ?string | The [alternate event source](#client-event-source) this request originated from |
| client_app_state? | string | The [focus state](#client-app-state) of the client |
| client_launch_id? | string | A client-generated UUID used to identify the client launch |
| client_heartbeat_session_id? | ?string | A client-generated UUID representing the current persisted analytics heartbeat, regenerated every 30 minutes |
| client_performance_cpu? **(deprecated)** | integer | The total CPU utilization of the mobile device (in percent) |
| client_performance_memory? **(deprecated)** | integer | The total memory utilization of the mobile device (in kilobytes) |
| cpu_core_count? **(deprecated)** | integer | The number of CPU cores available to the mobile device |
| release_channel ^1^ | string | The [release channel of the client](#release-channel) |
| system_locale | string | The primary system locale |
| device? | string | The model of the mobile device the client is running on |
| device_vendor_id? | string | A unique identifier for the mobile device (UUID on Android, [IdentifierForVendor](https://developer.apple.com/documentation/uikit/uidevice/1620059-identifierforvendor) on iOS) |
| device_advertiser_id? **(deprecated)** | string | The advertiser ID of the mobile device |
| design_id? | integer | The [design ID of the client](#design-id) |
| accessibility_support_enabled? **(deprecated)** | boolean | Whether accessibility support is enabled |
| accessibility_features? **(deprecated)** | integer | The [accessibility features enabled on the client](#accessibility-feature-flags) |
| window_manager? | string | The Linux window manager (`env.XDG_CURRENT_DESKTOP ?? "unknown" + "," + env.GDMSESSION ?? "unknown"`) |
| distro? | string | The Linux distribution (output of `lsb_release -ds`) |
| runtime_environment? | string | The Linux [runtime environment](#runtime-environment) |
| display_server? | string | The Linux display server (`env.XDG_SESSION_TYPE ?? "unknown"`) |
| referrer? | string | The URL that originally referred the user to Discord |
| referrer_current? | string | Same as `referrer` but for the current session |
| referring_domain? | string | The domain of the URL that originally referred the user to Discord |
| referring_domain_current? | string | Same as `referring_domain` but for the current session |
| search_engine? | string | The [search engine that originally referred the user to Discord](#search-engine), parsed from the referrer URL |
| search_engine_current? | string | Same as `search_engine` but for the current session |
| mp_keyword? | string | The search engine query that originally referred the user to Discord, parsed from the `q` or `p` parameter of the referrer URL |
| mp_keyword_current? | string | Same as `mp_keyword` but for the current session |
| utm_campaign? | string | The UTM campaign that originally referred the user to Discord, parsed from the `utm_campaign` parameter of the referrer URL |
| utm_campaign_current? | string | Same as `utm_campaign` but for the current session |
| utm_content? | string | The UTM content that originally referred the user to Discord, parsed from the `utm_content` parameter of the referrer URL |
| utm_content_current? | string | Same as `utm_content` but for the current session |
| utm_medium? | string | The UTM medium that originally referred the user to Discord, parsed from the `utm_medium` parameter of the referrer URL |
| utm_medium_current? | string | Same as `utm_medium` but for the current session |
| utm_source? | string | The UTM source that originally referred the user to Discord, parsed from the `utm_source` parameter of the referrer URL |
| utm_source_current? | string | Same as `utm_source` but for the current session |
| utm_term? | string | The UTM term that originally referred the user to Discord, parsed from the `utm_term` parameter of the referrer URL |
| utm_term_current? | string | Same as `utm_term` but for the current session |
| has_client_mods? | boolean | Whether the connecting client has modifications (e.g. BetterDiscord) |
| launch_signature? | string | The [launch signature](#launch-signature) of the client |
| installation_id? ^3^ | string | The client's existing installation ID (see the [experiments documentation](/topics/experiments#installations) for more information) |
| is_fast_connect? ^3^ | boolean | Whether the Gateway session sent the [identified](/gateway/using-gateway#identifying) using fast connect (a preload script ran before the client was loaded) |
| version? ^3^ | string | The version of the client properties protocol |
^1^ These properties are used to gate experimental features and may be required for certain endpoints. `client_version` may be used instead of `client_build_number` for mobile experiments. See the [experiments documentation](/topics/experiments) for more information.
^2^ If specified, this value should match the `User-Agent` header sent by the client.
^3^ These properties are only sent when [identifying](/gateway/using-gateway#identifying) with the Gateway and are not included in the `X-Super-Properties` header.
###### Operating System Type
| Value | Description |
| -------------- | --------------------------------------------- |
| Android | The client is running on Android |
| BlackBerry | The client is running on BlackBerry OS |
| Mac OS X | The client is running on macOS |
| iOS | The client is running on iOS |
| Linux | The client is running on a Linux distribution |
| Windows Mobile | The client is running on Windows Mobile |
| Windows | The client is running on Windows |
| Playstation | The client is running on PlayStation |
| Xbox | The client is running on Xbox |
| Unknown | The client is running on an unknown OS |
###### Browser Type
| Value | Description | Client Status Type |
| ----------------- | --------------------------------- | ------------------------------------------------------ |
| Discord Client | Desktop client | [`desktop`](/resources/presence#client-status-object) |
| Discord Android | Android client | [`mobile`](/resources/presence#client-status-object) |
| Discord iOS | iOS client | [`mobile`](/resources/presence#client-status-object) |
| Discord Embedded | Embedded (e.g. Xbox) client | [`embedded`](/resources/presence#client-status-object) |
| Discord VR | VR (e.g. Meta Quest) client | [`vr`](/resources/presence#client-status-object) |
| Android Chrome | Google Chrome Android | [`web`](/resources/presence#client-status-object) |
| Android Mobile | Generic Android browser | [`web`](/resources/presence#client-status-object) |
| BlackBerry | BlackBerry browser | [`web`](/resources/presence#client-status-object) |
| Chrome | Google Chrome desktop | [`web`](/resources/presence#client-status-object) |
| Chrome iOS | Google Chrome iOS | [`web`](/resources/presence#client-status-object) |
| ~~Edge~~ | ~~Legacy Microsoft Edge desktop~~ | ~~[`web`](/resources/presence#client-status-object)~~ |
| Facebook Mobile | Facebook mobile browser | [`web`](/resources/presence#client-status-object) |
| Firefox | Mozilla Firefox | [`web`](/resources/presence#client-status-object) |
| Internet Explorer | Microsoft Internet Explorer | [`web`](/resources/presence#client-status-object) |
| Konqueror | KDE Konqueror | [`web`](/resources/presence#client-status-object) |
| Mobile Safari | Safari iOS | [`web`](/resources/presence#client-status-object) |
| Mozilla | Generic Mozilla-like browser | [`web`](/resources/presence#client-status-object) |
| Opera | Opera | [`web`](/resources/presence#client-status-object) |
| Opera Mini | Opera Mini | [`web`](/resources/presence#client-status-object) |
| Safari | Safari desktop | [`web`](/resources/presence#client-status-object) |
###### Client Event Source
| Value | Description |
| ------- | ----------------------------------------------- |
| OVERLAY | The request originated from the Discord Overlay |
###### Client App State
| Value | Description |
| ---------- | ------------------------------------------- |
| focused | The client is focused (in the foreground) |
| unfocused | The client is unfocused (in the background) |
| active | The app is active |
| inactive | The app is inactive |
| background | The app has been backgrounded |
###### Release Channel
| Value | Description |
| ------------------ | --------------------------------------------------------------------------------------------------------------------- |
| stable | Stable |
| ptb | PTB |
| canary | Canary |
| staging | Staging |
| internal | Internal |
| googleRelease | Google Play Store stable |
| ~~samsungRelease~~ | ~~Samsung Galaxy Store stable~~ |
| billingRelease | Android billing (unknown) |
| betaRelease | Android beta |
| canaryRelease | Android alpha |
| internalRelease | Internal employee-only release |
| developerRelease | Internal developer release |
| adhocRelease | [iOS ad-hoc release](https://developer.apple.com/help/account/manage-profiles/create-an-ad-hoc-provisioning-profile/) |
| N/A | Not applicable release (unknown) |
| unknown | Unknown release |
###### Design ID
| Value | Name | Description |
| ----- | -------------- | ------------------------------------ |
| 0 | CLASSIC_IA | The classic design (default) |
| 1 | DESIGN_IA | The full mobile redesign |
| 2 | DESIGN_TABS_IA | The mobile redesign with tabs |
| 3 | YOU_BAR_IA | The mobile redesign with the you bar |
###### Accessibility Feature Flags
| Value | Name | Description |
| --------- | ---------------------------------- | -------------------------------------------------------------------------- |
| 1 \<\< 0 | SCREENREADER | User has a screen reader enabled |
| 1 \<\< 1 | REDUCED_MOTION | User has reduced motion enabled |
| 1 \<\< 2 | REDUCED_TRANSPARENCY | User has reduced transparency enabled |
| 1 \<\< 3 | HIGH_CONTRAST | User has high contrast enabled |
| 1 \<\< 4 | BOLD_TEXT | User has bold text enabled |
| 1 \<\< 5 | GRAYSCALE | User has grayscale colors enabled |
| 1 \<\< 6 | INVERT_COLORS | User has inverted colors enabled |
| 1 \<\< 7 | PREFERS_COLOR_SCHEME_LIGHT | User prefers a light color scheme |
| 1 \<\< 8 | PREFERS_COLOR_SCHEME_DARK | User prefers a dark color scheme |
| 1 \<\< 9 | CHAT_FONT_SCALE_INCREASED | User has increased the chat font scale |
| 1 \<\< 10 | CHAT_FONT_SCALE_DECREASED | User has decreased the chat font scale |
| 1 \<\< 11 | ZOOM_LEVEL_INCREASED | User has increased the zoom level |
| 1 \<\< 12 | ZOOM_LEVEL_DECREASED | User has decreased the zoom level |
| 1 \<\< 13 | MESSAGE_GROUP_SPACING_INCREASED | User has increased the message group spacing |
| 1 \<\< 14 | MESSAGE_GROUP_SPACING_DECREASED | User has decreased the message group spacing |
| 1 \<\< 15 | DARK_SIDEBAR | User has a dark sidebar enabled |
| 1 \<\< 16 | REDUCED_MOTION_FROM_USER_SETTINGS | User has reduced motion explicitly enabled from user settings |
| 1 \<\< 17 | SATURATION_LEVEL_DECREASED | User has decreased the saturation level |
| 1 \<\< 18 | FORCED_COLORS | User has system high-contrast forced colors enabled |
| 1 \<\< 19 | FORCED_COLORS_FROM_USER_SETTINGS | User has high-contrast forced colors explicitly enabled from user settings |
| 1 \<\< 20 | ROLE_STYLE_ADJUSTED | User has adjusted role styles |
| 1 \<\< 21 | SYNC_PROFILE_THEME_WITH_USER_THEME | User has enabled syncing the user profile theme with the client theme |
| 1 \<\< 22 | REDUCED_MOTION_PREFERS_CROSSFADES | User has reduced motion enabled and prefers crossfades |
| 1 \<\< 23 | CONTRAST_LEVEL_INCREASED | User has increased the contrast level |
| 1 \<\< 24 | CONTRAST_LEVEL_DECREASED | User has decreased the contrast level |
###### Runtime Environment
| Value | Description |
| -------- | ----------------------------- |
| native | Client is running natively |
| flatpak | Client is running in Flatpak |
| snap | Client is running in Snap |
| appimage | Client is running in AppImage |
###### Search Engine
| Value | Description |
| ---------- | --------------------------------------------------- |
| google | [Google search engine](https://www.google.com/) |
| bing | [Bing search engine](https://www.bing.com/) |
| yahoo | [Yahoo search engine](https://www.yahoo.com/) |
| duckduckgo | [DuckDuckGo search engine](https://duckduckgo.com/) |
###### Launch Signature
While the launch signature may appear to be a random UUID, certain bits are used to encode information about the client, specifically whether certain client mods are detected.
| Value | Name | Detection Keys |
| ---------- | ------------- | ------------------------------------------------------------ |
| 1 \<\< 119 | JQUERY | `jQuery`, `$`, `fn`, `jquery` |
| 1 \<\< 108 | BETTERDISCORD | `BetterDiscord`, `BetterDiscordPreload`, `BdApi` |
| 1 \<\< 100 | RAMBOX | `rambox` |
| 1 \<\< 91 | VENDETTA | `revenge`, `vendetta`, `bunny`, `kettu` |
| 1 \<\< 84 | VENCORD | `Vencord`, `VencordNative`, `VesktopNative`, `VencordMobile` |
| 1 \<\< 75 | REPLUGGED | `replugged`, `RepluggedNative` |
| 1 \<\< 61 | LEGCORD | `legcord`, `LegcordRPC` |
| 1 \<\< 55 | DORION | `Dorion`, `__DORION_CONFIG__`, `__DORION_INIT__` |
| 1 \<\< 48 | GOOFCORD | `GCDP` |
| 1 \<\< 38 | OPENASAR | `openasar` |
| 1 \<\< 24 | SHELTER | `shelter` |
| 1 \<\< 11 | MOONLIGHT | `moonlight`, `moonlightNode` |
Client mods are detected by passing `globalThis` to libdiscore (Wasm). For each client mod, it loops over each built-in obfuscated detection key, deobfuscates it (hex decode and XOR 0x73) and checks if it exists in the passed object.
A default launch signature can be generated with the following pseudocode:
```py
import uuid
def generate_launch_signature() -> str:
bits = 0b00000000100000000001000000010000000010000001000000001000000000000010000010000001000000000100000000000001000000000000100000000000
# Force all bits to 0
random_uuid = uuid.uuid4().int & (~bits & ((1 << 128) - 1))
result = uuid.UUID(int=random_uuid)
return str(result)
```
Note that the launch signature for mobile clients is currently just the current Unix timestamp in nanoseconds, represented as a string. It may be updated to encode similar information to the desktop launch signature in the future.
###### Example Client Properties (Web)
```json
{
"os": "Windows",
"browser": "Chrome",
"device": "",
"system_locale": "en-US",
"browser_user_agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/136.0.0.0 Safari/537.36",
"browser_version": "136.0.0.0",
"os_version": "10",
"referrer": "https://www.reddit.com/",
"referring_domain": "www.reddit.com",
"referrer_current": "https://www.google.com/",
"referring_domain_current": "www.google.com",
"search_engine_current": "google",
"mp_keyword_current": "discord",
"release_channel": "stable",
"client_build_number": 396858,
"client_event_source": null,
"has_client_mods": false,
"client_launch_id": "9a65c85b-401d-4cf0-9c17-9676a68a482c",
"launch_signature": "477bea01-90cb-422d-9a38-aaa66ed3e25e",
"client_heartbeat_session_id": "2fc3cabd-3ca0-4716-b399-496780c302d1"
}
```
###### Example Client Properties (Windows)
```json
{
"os": "Windows",
"browser": "Discord Client",
"release_channel": "canary",
"client_version": "1.0.328",
"os_version": "10.0.26100",
"os_arch": "x64",
"app_arch": "x64",
"system_locale": "en-US",
"has_client_mods": false,
"client_launch_id": "466a709c-1d91-442d-a35f-34e8c834736e",
"launch_signature": "477bea01-90cb-422d-9a38-aaa66ed3e25e",
"browser_user_agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) discord/1.0.328 Chrome/134.0.6998.179 Electron/35.1.5 Safari/537.36",
"browser_version": "35.1.5",
"os_sdk_version": "26100",
"client_build_number": 397417,
"native_build_number": 63309,
"client_event_source": null,
"client_heartbeat_session_id": "b789aacc-2579-489a-9dc8-2aa440519ae6"
}
```
###### Example Client Properties (macOS)
```json
{
"os": "Mac OS X",
"browser": "Discord Client",
"release_channel": "ptb",
"client_version": "0.0.171",
"os_version": "24.2.0",
"os_arch": "arm64",
"app_arch": "arm64",
"system_locale": "en-US",
"has_client_mods": false,
"client_launch_id": "c1f90baa-5390-43bd-a5eb-36a77d0c17c1",
"launch_signature": "477bea01-90cb-422d-9a38-aaa66ed3e25e",
"browser_user_agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) discord/0.0.171 Chrome/134.0.6998.179 Electron/35.1.5 Safari/537.36",
"browser_version": "35.1.5",
"os_sdk_version": "24",
"client_build_number": 397030,
"native_build_number": null,
"client_event_source": null,
"client_heartbeat_session_id": "63efcf64-bfd4-48b3-bdb6-57e643c7f1e0"
}
```
###### Example Client Properties (Linux)
```json
{
"os": "Linux",
"browser": "Discord Client",
"release_channel": "canary",
"client_version": "0.0.670",
"os_version": "5.15.153.1-microsoft-standard-WSL2",
"os_arch": "x64",
"app_arch": "x64",
"system_locale": "en-US",
"has_client_mods": false,
"client_launch_id": "ee3d1bb9-761a-426e-a9e4-4962295ca5df",
"launch_signature": "477bea01-90cb-422d-9a38-aaa66ed3e25e",
"browser_user_agent": "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) discord/0.0.670 Chrome/134.0.6998.179 Electron/35.1.5 Safari/537.36",
"browser_version": "35.1.5",
"window_manager": "Hyprland,unknown",
"distro": "Ubuntu 24.04.4 LTS",
"client_build_number": 397417,
"native_build_number": null,
"client_event_source": null,
"client_heartbeat_session_id": "9345ac0b-2bbb-43f8-89c1-5cf190fbb61d"
}
```
###### Example Client Properties (Android)
Given a client version of 280.2 and a release channel of alpha, the user agent version is derived like so:
`280` for major version + `0/1/2` for stable/beta/alpha + `02` for minor version -> `280202`.
```json
{
"os": "Android",
"browser": "Discord Android",
"device": "a20e", // Samsung Galaxy A20e
"system_locale": "en-US",
"has_client_mods": false,
"client_version": "280.2 - rn",
"release_channel": "alpha",
"device_vendor_id": "17503929-a4b8-4490-87bf-0222adfdadc8",
"design_id": 2,
"browser_user_agent": "", // While it is not provided here, the User-Agent header is Discord-Android/280202;RNA
"browser_version": "",
"os_version": "34", // Android 14
"client_build_number": 4025,
"client_event_source": null,
"client_launch_id": "9a65c85b-401d-4cf0-9c17-9676a68a482c",
"launch_signature": "1772849654003989335",
"client_heartbeat_session_id": "2fc3cabd-3ca0-4716-b399-496780c302d1"
}
```
###### Example Client Properties (iOS)
```json
{
"os": "iOS",
"browser": "Discord iOS",
"device": "iPhone14,5", // iPhone 13
"system_locale": "en-US",
"has_client_mods": false,
"client_version": "227.0",
"release_channel": "stable",
"device_vendor_id": "AFF0710F-CEC0-4671-B2CF-0A03D72B5FD0",
"design_id": 2,
"browser_user_agent": "", // While it is not provided here, the User-Agent header is Discord/58755 CFNetwork/1494.0.7 Darwin/23.4.0
"browser_version": "",
"os_version": "17.4.1",
"client_build_number": 58755,
"client_event_source": null,
"client_launch_id": "9a65c85b-401d-4cf0-9c17-9676a68a482c",
"launch_signature": "1772849654003989335",
"client_heartbeat_session_id": "2fc3cabd-3ca0-4716-b399-496780c302d1"
}
```
###### Example Client Properties (Embedded)
```json
{
"browser": "Discord Embedded",
"browser_user_agent": "Discord Embedded/0.0.8",
"browser_version": "0.0.8",
"client_build_number": 4440,
"design_id": 0,
"os": "Windows",
"release_channel": "unknown"
}
```
## Message Formatting
Discord utilizes a subset of markdown for rendering message content on its clients, while also adding some custom functionality to enable things like mentioning users and channels. This functionality uses the following formats:
###### Formats
| Type | Structure | Example |
| ----------------------- | ------------------------------ | ------------------------------- |
| User | `<@USER_ID>` | `<@80351110224678912>` |
| User ^1^ | `<@!USER_ID>` | `<@!80351110224678912>` |
| Channel | `<#CHANNEL_ID>` | `<#103735883630395392>` |
| Role | `<@&ROLE_ID>` | `<@&165511591545143296>` |
| Slash Command ^2^ | `` | `` |
| Standard Emoji | Unicode Characters or `:NAME:` | 💯 or `:100:` |
| Custom Emoji | `<:NAME:ID>` | `<:mmLol:216154654256398347>` |
| Custom Emoji (Animated) | `` | `` |
| Unix Timestamp | `` | `` |
| Unix Timestamp (Styled) | `` | `` |
| Guild Navigation | `` | `` |
| Email ^3^ | `` | `` |
| Phone Number ^4^ | `<+PHONE_NUMBER>` | `<+1 (555) 123 4567>` |
Using the markdown for either users, roles, or channels will usually mention the target(s) accordingly, but this can be suppressed using the `allowed_mentions` parameter when creating a message. Standard emoji are currently rendered using [Twemoji](https://twemoji.twitter.com/) for Desktop/Android and Apple's native emoji on iOS.
Timestamps are expressed in seconds and display the given timestamp in the user's timezone and locale.
^1^ User mentions with an exclamation mark are deprecated and should be handled like any other user mention.
^2^ Subcommands and subcommand groups can also be mentioned by using respectively `` and ``.
^3^ Can be optionally prefixed with `mailto:`, following the same format as the [`mailto:`](https://en.wikipedia.org/wiki/Mailto) URI scheme. Does not support multiple comma-separated addresses. Supports headers (e.g. ``).
^4^ Can be optionally prefixed with `tel:`/`sms:`. Whitespace is ignored and the dialling prefix `+` is not required when a scheme is provided.
###### Timestamp Styles
| Style | Example Output | Description |
| ----- | -------------------------------- | ---------------------- |
| t | 16:20 | Short Time |
| T | 16:20:30 | Medium Time |
| d | 20/04/2021 | Short Date |
| D | April 20, 2021 | Long Date |
| f ^1^ | April 20, 2021 at 16:20 | Long Date/Short Time |
| F | Tuesday, April 20, 2021 at 16:20 | Full Date/Short Time |
| s | 20/04/2021, 16:20 | Short Date/Short Time |
| S | 20/04/2021, 16:20:30 | Short Date/Medium Time |
| R | 2 months ago | Relative Time |
^1^ This is the default.
###### Guild Navigation Types
Guild navigation types link to the corresponding resource in the current guild.
| Type | Description |
| --------------------- | ------------------------------------------------------------------------------------------ |
| customize | _Customize_ tab with the server's [onboarding prompts](/resources/guild#onboarding-object) |
| browse | _Browse Channels_ tab |
| guide | [Server Guide](https://support.discord.com/hc/en-us/articles/13497665141655) |
| home **(deprecated)** | Same as `guide` |
| linked-roles | [Linked Roles](https://support.discord.com/hc/en-us/articles/10388356626711) |
| linked-roles:ROLE_ID | _Linked Role_ connection |
## CDN Formatting
###### CDN Base URL
```
https://cdn.discordapp.com/
```
Discord uses IDs and hashes to render images and other CDN content in the client. These hashes can be retrieved through various API requests, like [Get User](/resources/user#get-user). Below are the formats, size limitations, and CDN endpoints for content in Discord.
The returned format can be changed by changing the [extension name](#file-formats) at the end of the URL. For images, the returned size can be changed by appending a [query string](#cdn-parameters) of `?size=desired_size` to the URL.
Image size can be any power of two between 16 and 4096, with some additional accepted values [outlined below](#cdn-parameters). The [media proxy](#media-proxy) uses the same paths as the CDN and supports additional transformation parameters.
In the case of endpoints that support animated images, the hash will begin with `a_` if it is available in animated WebP, APNG, or GIF format (e.g. `a_1269e74af4df7417b13759eae50c83dc`).
CDN response headers will _typically_ contain standard Google Cloud Storage response headers, such as `X-Goog-Hash`. Use these to your benefit.
###### File Formats
| Name | Extension |
| ------ | ----------- |
| JPEG | .jpg, .jpeg |
| PNG | .png |
| SVG | .svg |
| WebP | .webp |
| WebM | .webm |
| GIF | .gif |
| Lottie | .json |
| MP3 | .mp3 |
| MP4 | .mp4 |
| OGG | .ogg |
###### CDN Endpoints
| Type | Path | Supports |
| -------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------- |
| Achievement Icon | /app-assets/[\{application_id\}](/resources/application#application-object)/achievements/\{achievement_id\}/icons/icon_hash.png | PNG, JPEG, WebP |
| Activity Link Asset ^4^ | /attachments-quick-links/[\{asset_path\}](/resources/application#activity-link-object) | Uploaded format |
| Application Asset | /app-assets/[\{application_id\}](/resources/application#application-object)/[\{asset_id\}](/resources/application#application-asset-object).png | PNG, JPEG, WebP |
| Application Cover | /app-icons/[\{application_id\}](/resources/application#application-object)/[\{application_cover_image\}](/resources/application#application-object).png | PNG, JPEG, WebP |
| Application Directory Collection | /application-directory/collection-items/[\{collection_item_id\}](/resources/application-directory#application-directory-collection-item-structure)/[\{image_hash\}](/resources/application-directory#application-directory-collection-item-structure).png | PNG, WEBP |
| Application Game Screenshot | /app-assets/[\{application_id\}](/resources/application#application-object)/game/screenshots/[\{screenshot_hash\}](/resources/game#game-object).png | PNG, JPEG, WebP |
| Application Icon | /app-icons/[\{application_id\}](/resources/application#application-object)/[\{application_icon\}](/resources/application#application-object).png | PNG, JPEG, WebP |
| Application Splash | /app-icons/[\{application_id\}](/resources/application#application-object)/[\{application_splash\}](/resources/application#application-object).png | PNG, JPEG, WebP |
| Attachment ^2^ ^4^ | /attachments/[\{channel_id\}](/resources/channel#channel-object)/\{message_id\}/[\{attachment_id\}](/resources/message#attachment-object)/[\{attachment_filename\}](/resources/message#attachment-object) | Uploaded format |
| Avatar Decoration Preset | /avatar-decoration-presets/[\{avatar_decoration_data_asset\}](/resources/user#avatar-decoration-data-structure).png | PNG, JPEG, WebP |
| Channel Icon | /channels/[\{channel_id\}](/resources/channel#channel-object)/icons/[\{channel_icon\}](/resources/channel#channel-object).png | PNG, JPEG, WebP |
| Clan Badge ^7^ | /clan-badges/[\{guild_id\}](/resources/guild#guild-object)/[\{badge_hash\}](/resources/discovery#guild-profile-object).png | PNG |
| Clan Banner | /clan-banners/[\{guild_id\}](/resources/guild#guild-object)/[\{banner_hash\}](/resources/discovery#guild-profile-object).png | PNG |
| Custom Emoji ^8^ | /emojis/[\{emoji_id\}](/resources/emoji#emoji-object).png | PNG, JPEG, WebP, GIF |
| Default User Avatar ^1^ ^2^ | /embed/avatars/[\{user_index\}](/resources/user#user-object).png | PNG |
| Ephemeral Attachment ^2^ ^4^ | /ephemeral-attachments/[\{application_id\}](/resources/application#application-object)/[\{attachment_id\}](/resources/message#attachment-object)/[\{attachment_filename\}](/resources/message#attachment-object) | Uploaded format |
| Guild Banner | /banners/[\{guild_id\}](/resources/guild#guild-object)/[\{guild_banner\}](/resources/guild#guild-object).png | PNG, JPEG, WebP, GIF |
| Guild Discovery Splash | /discovery-splashes/[\{guild_id\}](/resources/guild#guild-object)/[\{guild_discovery_splash\}](/resources/guild#guild-object).png | PNG, JPEG, WebP |
| Guild Home Header | /home-headers/[\{guild_id\}](/resources/guild#guild-object)/[\{guild_home_header\}](/resources/guild#guild-object).png | PNG, JPEG, WebP |
| Guild Icon | /icons/[\{guild_id\}](/resources/guild#guild-object)/[\{guild_icon\}](/resources/guild#guild-object).png | PNG, JPEG, WebP, GIF |
| Guild Member Avatar | /guilds/[\{guild_id\}](/resources/guild#guild-object)/users/[\{user_id\}](/resources/user#user-object)/avatars/[\{user_avatar\}](/resources/user#user-object).png | PNG, JPEG, WebP, GIF |
| Guild Member Banner | /guilds/[\{guild_id\}](/resources/guild#guild-object)/users/[\{user_id\}](/resources/user#user-object)/banners/[\{user_banner\}](/resources/user#user-object).png | PNG, JPEG, WebP, GIF |
| Guild New Member Action Icon | /new-member-actions/[\{channel_id\}](/resources/guild#new-member-action-structure)/[\{action_icon\}](/resources/guild#new-member-action-structure).png | PNG, JPEG, WebP |
| Guild Product Attachment ^2^ ^4^ | /server-products/[\{application_id\}](/resources/application#application-object)/[\{attachment_id\}](/resources/message#attachment-object)/[\{attachment_filename\}](/resources/message#attachment-object) | Uploaded format |
| Guild Resource Channel Icon | /resource-channels/[\{channel_id\}](/resources/guild#resource-channel-structure)/[\{channel_icon\}](/resources/guild#resource-channel-structure).png | PNG, JPEG, WebP |
| Guild Scheduled Event Cover | /guild-events/[\{scheduled_event_id\}](/resources/guild-scheduled-event#guild-scheduled-event-object)/[\{scheduled_event_cover_image\}](/resources/guild-scheduled-event#guild-scheduled-event-object).png | PNG, JPEG, WebP |
| Guild Splash | /splashes/[\{guild_id\}](/resources/guild#guild-object)/[\{guild_splash\}](/resources/guild#guild-object).png | PNG, JPEG, WebP |
| Guild Tag Badge ^7^ | /guild-tag-badges/[\{guild_id\}](/resources/guild#guild-object)/[\{badge_hash\}](/resources/discovery#guild-profile-object).png | PNG |
| Nameplate ^2^ ^6^ | /assets/collectibles/[\{asset_path\}](/resources/user#nameplate-data-structure)\{asset_name\} | PNG, WebM |
| Profile Badge | /badge-icons/[\{badge_icon\}](/resources/user#profile-badge-structure).png | PNG |
| Quest Asset ^2^ ^4^ ^5^ | /assets/quests/[\{quest_id\}](/resources/quests#quest-object)/[\{asset_name\}](/resources/quests#quest-assets-structure) | Uploaded format |
| Quest Asset (Themed) ^2^ ^4^ ^5^ | /assets/quests/[\{quest_id\}](/resources/quests#quest-object)/[\{theme\}](/resources/user-settings#theme)/[\{asset_name\}](/resources/quests#quest-assets-structure) | Uploaded format |
| Role Icon | /roles/[\{role_id\}](/resources/guild#role-object)/icons/[\{role_icon\}](/resources/guild#role-object).png | PNG, JPEG, WebP |
| Soundboard Sound | /soundboard-sounds/[\{sound_id\}](/resources/soundboard#soundboard-sound-object) | MP3, OGG |
| Sticker ^2^ ^3^ | /stickers/[\{sticker_id\}](/resources/sticker#sticker-object).png | PNG, Lottie, GIF |
| Sticker Pack Banner | /app-assets/710982414301790216/store/[\{asset_id\}](/resources/sticker#sticker-pack-object).png | PNG, JPEG, WebP |
| Store Asset | /app-assets/[\{application_id\}](/resources/application#application-object)/store/[\{asset_id\}](/resources/store#store-asset-object).png | PNG, JPEG, MP4, WebP |
| Stream Preview | /streams/[\{stream_key\}](/gateway/gateway-events#stream-key)/\{thumbnail_hash\}.png | PNG, JPEG, WebP |
| Team Icon | /team-icons/[\{team_id\}](/resources/team#team-object)/[\{team_icon\}](/resources/team#team-object).png | PNG, JPEG, WebP |
| User Archived Avatar | /avatars/[\{user_id\}](/resources/user#user-object)/archived/[\{avatar_id\}](/resources/user#avatar-structure)/[\{avatar_storage_hash\}](/resources/user#avatar-structure).png | PNG, JPEG, WebP, GIF |
| User Avatar | /avatars/[\{user_id\}](/resources/user#user-object)/[\{user_avatar\}](/resources/user#user-object).png | PNG, JPEG, WebP, GIF |
| User Banner | /banners/[\{user_id\}](/resources/user#user-object)/[\{user_banner\}](/resources/user#user-object).png | PNG, JPEG, WebP, GIF |
| Video Filter | /users/[\{user_id\}](/resources/user#user-object)/video-filter-assets/[\{video_filter_id\}](/resources/user-settings-proto#video-filter-asset-structure)/[\{video_filter_asset\}](/resources/user-settings-proto#video-filter-asset-structure).png | PNG, JPEG, GIF, MP4, WEBP |
^1^ The value for `user_index` in the path for migrated users should be the user's ID shifted 22 bits to the left modulo 6 (i.e. `user_id >> 22 % 6`). The value for non-migrated users the user's discriminator modulo 5 (Test#1337 would be `1337 % 5`, which evaluates to 2). The value for teams should be the team's ID modulo 5 (i.e. `team_id % 5`). See the [section on Discord's new username system](/resources/user#unique-usernames) for more information.
^2^ The size of images returned is constant with the `size` query string parameter being ignored. This also applies to any received CDN URL that is under the `/assets/` path.
^3^ The sticker will be available as PNG if its [`format_type`](/resources/sticker#sticker-object) is `PNG` or `APNG`, GIF if its [`format_type`](/resources/sticker#sticker-object) is `GIF`, and as JSON if its [`format_type`](/resources/sticker#sticker-object) is `LOTTIE`. GIF stickers are not available through the CDN, and must be accessed at `https://media.discordapp.net/stickers/{sticker_id}.gif`.
^4^ The attachment will only be available in its uploaded format, which can be any format.
^5^ The [theme](/resources/user-settings#theme) path is only used for fetching the [`game_tile` and `logotype` assets](/resources/quests#quest-assets-structure). Only `dark` and `light` are supported.
^6^ Valid asset names are limited to: `img.png`, `static.png`, `asset.webm`.
^7^ The clan badge route is an alias of the guild tag badge route, existing for backward compatibility.
^8^ Discord recommends requesting emoji as WebP for maximum performance and compatibility. Emoji can be uploaded as JPEG, PNG, GIF, WebP, and AVIF formats. WebP and AVIF formats must be requested as WebP since they don’t convert well to other formats. See the [emoji resource](/resources/emoji#emoji-formats) for more information.
##### CDN Parameters
The CDN supports various query string parameters. These parameters are optional and can be used to modify the returned resource. Parameters are only applicable to image resources.
| Field | Type | Description |
| ------------------ | ----------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| size? | integer | The size of the image to return (if omitted, a default size is used); the size can be any power of two between 16 and 4096, and additionally 20, 22, 24, 28, 40, 44, 48, 56, 60, 80, 96, 100, 160, 240, 300, 320, 480, 600, 640, 1280, 1536, 3072 |
| quality? | string | The [quality](#image-quality) of the image to return; not supported with all endpoints and image types |
| keep_aspect_ratio? | boolean ^1^ | Whether the image will be resized to the endpoint's enforced aspect ratio (default false) |
| passthrough? | boolean ^1^ | Whether the image will be returned in the original, Discord-defined quality and format (usually APNG) if possible (default true); only supported with specific endpoints |
| animated? | boolean ^1^ | Whether the image will be returned in its animated format (if applicable) (default false); only supported with the WebP format |
^1^ The CDN only accepts boolean parameters as `true` or `false` (not `1` or `0`).
##### Image Quality
The quality of the image to return. Only supported with WebP and JPG formats (the rest are always lossless). The quality can be any of the following values:
| Value | Description |
| -------- | ----------------------------------------------------------------------- |
| lossless | The image will be returned in its original format, with no quality loss |
| high | The image will be returned in a high quality format (the default) |
| low | The image will be returned in a low quality format |
#### Signed Attachment URLs
Attachments uploaded to Discord's CDN (like user-uploaded images) have signed URLs with a preset expiry time. This includes ephemeral attachments and guild product attachments. Discord automatically refreshes attachment CDN URLs that appear within the client,
so when you receive a payload with a signed URL (like when you [fetch a message](/resources/message#get-message)), it will be valid. Note that this does not apply to URLs present in user-generated content, such as message content or embed descriptions.
When passing CDN URLs into API fields, like [`url` in an embed image object](/resources/message#embed-media-structure) and [`avatar_url` for webhooks](/resources/webhook#execute-webhook), or when simply sending a message,
you can pass the CDN URL without any parameters as the value and Discord will automatically render and refresh the URL.
If you need to refresh an attachment URL manually, you can use the [Refresh Attachment URLs](/topics/cloud-uploads#refresh-attachment-urls) endpoint with any URL.
[Other CDN endpoints](#cdn-endpoints) listed above are not signed, so they will not expire.
###### Attachment URL Query Parameters
| Parameter | Description |
| --------- | --------------------------------------------------------------- |
| ex | Hex timestamp indicating when an attachment CDN URL will expire |
| is | Hex timestamp indicating when the URL was issued |
| hm | Unique signature that remains valid until the URL's expiration |
###### Example Attachment URL
```
https://cdn.discordapp.com/attachments/1012345678900020080/1234567891233211234/my_image.png?ex=65d903de&is=65c68ede&hm=2481f30dd67f503f54d020ae3b5533b9987fae4e55f2b4e3926e08a3fa3ee24f&
```
### Media Proxy
The media proxy uses the CDN's resource paths with the `media.discordapp.net` host. For example, a proxied attachment will use `/attachments/{channel_id}/{message_id}/{attachment_id}/{attachment_filename}` on `https://media.discordapp.net/`,
matching the corresponding CDN attachment path. Note that signed URLs are still required for attachments in the media proxy.
The media proxy is primarily used for returned media URLs such as [`proxy_url`](/resources/message#attachment-object) on attachments and embed media. It can resize and transcode supported images and generate still previews for supported animated media.
If the underlying attachment is not a supported media type, such as an attachment without image or video dimensions, the proxy returns a 415 unsupported media type error.
Media proxy URLs use the same [CDN parameters](#cdn-parameters) where applicable, and also support the parameters below. When converting a media proxy URL back to the original CDN URL,
clients should remove `width`, `height`, `quality`, `size`, and `format` because those parameters describe the proxy transformation rather than the original object.
Media proxy response headers will contain `X-Discord-Transform-Duration`, which specifies the time spent transcoding in milliseconds.
###### Media Proxy Base URL
```
https://media.discordapp.net/
```
Note that you may encounter media proxy URLs exposed on other hosts, such as `https://images-ext-2.discordapp.net`.
###### Media Proxy Parameters
| Field | Type | Description |
| ------- | ------- | --------------------------------------------------------------------------------------------- |
| width? | integer | The maximum width of the returned media |
| height? | integer | The maximum height of the returned media |
| format? | string | The format to transcode to; commonly used to request still previews, such as `jpg` for videos |
## CDN Data
CDN data is a [Data URI scheme](https://en.wikipedia.org/wiki/Data_URI_scheme) that supports formats such as JPG, GIF, and PNG. An example Data URI format is:
```csh
data: image/jpeg; base64, BASE64_ENCODED_JPEG_IMAGE_DATA
```
Ensure you use the proper content type (e.g. `image/jpeg`, `image/png`, `image/gif`) that matches the image data being provided.
## Uploading Files
Most endpoints in the Discord API only accept JSON-encoded request bodies with the `application/json` content type. However, certain endpoints, specifically those that support file attachments, also accept `multipart/form-data` request bodies.
If an endpoint supports both `application/json` and `multipart/form-data`, it will also accept `application/x-www-form-urlencoded` request bodies, but only when no files are being uploaded.
If you wish to upload files while maintaining a JSON body, you may include a `payload_json` field in your `multipart/form-data` request. This field should contain a JSON-encoded string representing the body of your request, excluding any file data.
Note that arrays and nested objects require you to use `payload_json`, as form fields do not support these data types.
All message create endpoints accept file attachments, indicated by the `files[n]` parameter. To add file(s), the standard `application/json` body must be replaced by a `multipart/form-data` body. The JSON message body can optionally be provided using the `payload_json` parameter as outlined above.
The file upload size limit applies to each file in a request, but the total attachment size may not exceed **500 MiB**. The default limit is **10 MiB** for all users, but may be higher depending on their
[premium type](https://support.discord.com/hc/en-us/articles/115000435108) or the target guild's [premium tier](https://support.discord.com/hc/en-us/articles/360028038352), whichever is higher. The table below summarizes the raised limits:
Note that Cloudflare enforces a maximum request size of less than **500 MiB**. Exceeding this limit will fail with a 413 payload too large.
To upload a set of files larger than this, you must utilize [Google Cloud uploads](/topics/cloud-uploads).
| Resource | Tier | Limit |
| --------------------------------------------------- | -------- | ----------- |
| [User premium type](/resources/user#premium-type) | `TIER_1` | **50 MiB** |
| [User premium type](/resources/user#premium-type) | `TIER_2` | **500 MiB** |
| [User premium type](/resources/user#premium-type) | `TIER_3` | **50 MiB** |
| [Guild premium tier](/resources/guild#premium-tier) | `TIER_2` | **50 MiB** |
| [Guild premium tier](/resources/guild#premium-tier) | `TIER_3` | **100 MiB** |
All `files[n]` parameters must include a valid `Content-Disposition` subpart header with a `filename` and unique `name` parameter. Each file parameter must be uniquely named in the format `files[n]` (e.g. `files[0]`, `files[1]`, or `files[42]`).
The suffixed index `n` is the _snowflake placeholder_ that can be used in the `attachments` field.
Images can also be referenced in embeds using the `attachment://filename` URL. An example payload is provided below.
#### Editing Message Attachments
The `attachments` JSON parameter includes all files that will be appended to the message, including new files and their respective snowflake placeholders (referenced above). When making a `PATCH` request, only files listed in the `attachments` parameter will be appended to the message. Any previously-added files that aren't included will be removed.
###### Example Request Bodies (multipart/form-data)
Note that these examples are small sections of an HTTP request to demonstrate behaviour of this endpoint—client libraries will set their own form boundaries (`boundary` is just an example). For more information, refer to the [multipart/form-data spec](https://tools.ietf.org/html/rfc7578#section-4).
This example demonstrates usage of the endpoint _without_ `payload_json`.
```json
--boundary
Content-Disposition: form-data; name="content"
Hello, World!
--boundary
Content-Disposition: form-data; name="tts"
true
--boundary--
```
This example demonstrates usage of the endpoint _with_ `payload_json` and all content fields (`content`, `embeds`, `files[n]`) set.
```json
--boundary
Content-Disposition: form-data; name="payload_json"
Content-Type: application/json
{
"content": "Hello, World!",
"embeds": [{
"title": "Hello, Embed!",
"description": "This is an embedded message.",
"thumbnail": {
"url": "attachment://myfile.png"
},
"image": {
"url": "attachment://mygif.gif"
}
}],
"message_reference": {
"type": 0,
"channel_id": "233648473390448640",
"message_id": "233648473390448641"
},
"attachments": [{
"id": 0,
"description": "Image of a cute little cat",
"filename": "myfile.png"
}, {
"id": 1,
"description": "Rickroll gif",
"filename": "mygif.gif"
}]
}
--boundary
Content-Disposition: form-data; name="files[0]"; filename="myfile.png"
Content-Type: image/png
[image bytes]
--boundary
Content-Disposition: form-data; name="files[1]"; filename="mygif.gif"
Content-Type: image/gif
[image bytes]
--boundary--
```
###### Using Attachments within Embeds
You can upload attachments when creating a message and use those attachments within your embed. To do this, you will want to upload files as part of your `multipart/form-data` body.
Make sure that you're uploading files which contain a filename, as you will need to reference it in your payload.
Only `.jpg`, `.jpeg`, `.png`, `.webp`, and `.gif` may be used at this time. Other file types are not supported.
Within an embed object, you can then set an image to use an attachment as its URL with the attachment scheme syntax: `attachment://filename.png`
For example:
```json
{
"embeds": [
{
"image": {
"url": "attachment://screenshot.png"
}
}
]
}
```
## Locales
User locale is determined by looking at the `X-Discord-Locale` header, then the `Accept-Language` header if not present, then lastly the user settings locale.
| Locale | Language Name | Native Name |
| ------ | ------------------ | ------------------------- |
| ar | Arabic | العربية |
| bg | Bulgarian | български |
| cs | Czech | Čeština |
| da | Danish | Dansk |
| de | German | Deutsch |
| el | Greek | Ελληνικά |
| en-GB | English, UK | English, UK |
| en-US | English, US | English, US |
| es-ES | Spanish, Spain | Español |
| es-419 | Spanish, LATAM | Español de América Latina |
| fi | Finnish | Suomi |
| fr | French | Français |
| hi | Hindi | हिन्दी |
| hr | Croatian | Hrvatski |
| hu | Hungarian | Magyar |
| id | Indonesian | Bahasa Indonesia |
| it | Italian | Italiano |
| ja | Japanese | 日本語 |
| ko | Korean | 한국어 |
| lt | Lithuanian | Lietuviškai |
| nl | Dutch | Nederlands |
| no | Norwegian | Norsk |
| pl | Polish | Polski |
| pt-BR | Portuguese, Brazil | Português do Brasil |
| ro | Romanian | Română |
| ru | Russian | Pусский |
| sv-SE | Swedish | Svenska |
| th | Thai | ไทย |
| tr | Turkish | Türkçe |
| uk | Ukrainian | Українська |
| vi | Vietnamese | Tiếng Việt |
| zh-CN | Chinese, China | 中文 |
| zh-TW | Chinese, Taiwan | 繁體中文 |
#### Localized String
In API v8 and above, most API resources have switched away from this format, instead opting for `` and `_localizations` fields.
However, this format is still used in [store APIs](/resources/store) today.
Certain localized strings in the API have a special structure. These strings are represented as an object with the following fields:
| Field | Type | Description |
| -------------- | ------------------- | ---------------------------------------------------------------------------- |
| default | string | The fallback string if no localization is available for the requested locale |
| localizations? | map[string, string] | The string for each [locale](#locales) supported |
Note that for localized versions of resources, the value is simply the localized string, not the above object.
When creating or updating resources, you can provide either the above object or a single string value, which will set the `default` field and remove any existing localizations.
## File Types
A file type is either one of the file group keywords below, or any dot-prefixed file extension. Values must match the regex `^(image|video|audio|\.[\w\-\.]+)$`.
| Value | Description |
| ------------------- | --------------------------------------------------------------------------- |
| image | Any image file (`.png`, `.gif`, `.jpg`, `.jpeg`, `.jfif`, `.webp`, `.avif`) |
| video | Any video file (`.mp4`, `.mov`, `.qt`, `.webm`) |
| audio | Any audio file (`.mp3`, `.m4a`, `.wav`, `.ogg`, `.opus`, `.flac`) |
| `.{file_extension}` | A specific dot-prefixed file extension, such as `.pdf` |
The keyword expansions above are subject to change, so it's recommended to use the file group keywords rather than individual extensions. If you do specify individual extensions, you must include `.jpg` for image uploads and both `.mp4` and `.mov` for video uploads, as mobile clients may otherwise reject valid files.
Note that this only validates the uploaded file's name (i.e. its extension), not its actual contents, so a file could be renamed to bypass the restriction.
## Documentation Reference
This documentation uses various conventions to describe the API. Here are some common conventions you may see:
#### Nullable and Optional Resource Fields
Resource fields that may contain a `null` value have types that are prefixed with a question mark.
Resource fields that are optional have names that are suffixed with a question mark.
Resource fields that are `null`/missing only in extraneous cases will not be marked as above.
Instead, they will be marked with a footnote, and the situation will be explained below.
###### Example Nullable and Optional Fields
| Field | Type |
| ---------------------------- | ------- |
| optional_field? ^1^ | string |
| nullable_field | ?string |
| optional_and_nullable_field? | ?string |
^1^ May be unexpectedly `null` at 3:00 AM on Tuesdays for accounts created on June 23rd, 2017.
#### Field Limits
A best effort is made to document the limits of fields where possible (e.g. maximum length of a string, maximum number of array elements). These limits are not exhaustive and may not cover all edge cases.
A fallback limit of 1521 array elements and 152133 characters is used when no well-defined limit exists.
#### Deprecated/Removed Fields
Fields that are deprecated will be marked with a **(deprecated)** notice next to them. Fields that are removed (and are kept for completion's sake, such as in enums) will be ~~marked with strikethrough~~.
#### Event Fields
Certain fields are only present in structures received over the Gateway. These fields will usually be documented in the Gateway section instead of the main structure.
#### Badges
Certain endpoints may have badges that describe additional behavior in short form. Here are some examples you may find:
###### MFA Required
This endpoint may require that users with multi-factor authentication enabled authenticate themselves for certain actions. See the [MFA verification documentation](/authentication#mfa-verification) for implementation.
This is not applicable to OAuth2 and bot requests.
###### Audit Log Reason
The endpoint may be used with a `X-Audit-Log-Reason` header. This header is used to provide a reason for the action being performed. This reason will be shown in the audit log entry for this action. See the [audit log documentation](/resources/audit-log#audit-reason) for more information.
###### Unauthenticated Request
These requests do not require the `Authorization` header to be present.
###### OAuth2 Request
The endpoint may be used with a bearer token in the `Authorization` header. The specific scope required (if any) will be provided if you hover over the badge.
###### Deprecated Endpoint
This endpoint remains active and functionally the same, but it should be avoided if possible as it may be removed in a future API version.
---
# Soundboard
Link: https://docs.discord.food/resources/soundboard
Soundboard sounds are short audio clips that can be played in voice channels.
There is a set of [default sounds](#list-default-soundboard-sounds) available to all users. Soundboard sounds can also be [created in a guild](#create-guild-soundboard-sound); users will be able to use them in the guild, and premium (Nitro) subscribers can use them in all guilds.
Custom soundboard sounds in a can be retrieved over the Gateway using [Request Soundboard Sounds](/gateway/gateway-events#request-soundboard-sounds).
### Soundboard Sound Object
###### Soundboard Sound Structure
| Field | Type | Description |
| ------------ | -------------------------------------------------- | ------------------------------------------------------------------------------------------------ |
| sound_id | snowflake | The ID of the soundboard sound |
| name | string | The name of the soundboard sound (2-32 characters) |
| volume | float | The volume of the soundboard sound (represented as a float from 0 to 1) |
| emoji_id | ?snowflake | The ID of the sound's custom emoji |
| emoji_name | ?string | The unicode character of the sound's emoji |
| guild_id? | snowflake | The ID of the source guild |
| available | boolean | Whether this guild sound can be used; may be false due to loss of premium subscriptions (boosts) |
| user? ^1^ | partial [user](/resources/user#user-object) object | The user who created this sound |
| user_id? ^2^ | snowflake | The ID of the user who created this sound |
^1^ Only included for sounds in contexts where the sound is created or updated, as well as when fetched through the [List Guild Soundboard Sounds](#list-guild-soundboard-sounds) or [Get Guild Soundboard Sound](#get-guild-soundboard-sound) endpoints by a user with the `MANAGE_EXPRESSIONS` permission.
^2^ Only included in Gateway events related to the soundboard.
## Endpoints
List Default Soundboard Sounds
Returns a list of [soundboard sound](#soundboard-sound-object) objects that can be used by all users.
List Guild Soundboard Sounds
Returns an object containing a list of [soundboard sound](#soundboard-sound-object) objects for the given guild. Includes the `user` field if the user has the `CREATE_EXPRESSIONS` or `MANAGE_EXPRESSIONS` permission.
###### Response Body
| Field | Type | Description |
| ----- | ---------------------------------------------------------- | ---------------------------------- |
| items | array[[soundboard sound](#soundboard-sound-object) object] | The soundboard sounds in the guild |
Get Guild Soundboard Sound
Returns a [soundboard sound](#soundboard-sound-object) object for the given guild and sound ID. Includes the `user` field if the user has the `CREATE_EXPRESSIONS` or `MANAGE_EXPRESSIONS` permission.
Create Guild Soundboard Sound
Creates a new soundboard sound for the guild. Requires the `CREATE_EXPRESSIONS` permission. Returns the new [soundboard sound](#soundboard-sound-object) object on success. Fires a [Guild Soundboard Sound Create](/gateway/gateway-events#guild-soundboard-sound-create) Gateway event.
Soundboard sounds have a maximum file size of **512 KiB** and a maximum duration of 5.2 seconds. Attempting to upload a sound larger than this limit will fail with a 400 bad request.
Soundboard sound limits are applied to the total amount of sounds in the guild, making them a lot simpler than emoji limits. The default sound limit is 8.
The real limit depends on the guild's [premium tier](https://support.discord.com/hc/en-us/articles/360028038352) and [features](/resources/guild#guild-features).
These limits are summarized in the following table by [premium tier](/resources/guild#premium-tier). Note that if the guild has the [`MORE_SOUNDBOARD` feature](/resources/guild#guild-features), the applied limit is instead 96.
| Premium Tier | Sound Limit |
| ------------ | ----------- |
| `NONE` | 8 |
| `TIER_1` | 24 |
| `TIER_2` | 36 |
| `TIER_3` | 48 |
###### JSON Params
| Field | Type | Description |
| ----------- | --------------------------------- | ---------------------------------------------------------------------------------- |
| name | string | The name of the soundboard sound (2-32 characters) |
| sound | [sound data](/reference#cdn-data) | The sound file to upload |
| volume? | ?float | The volume of the soundboard sound (represented as a float from 0 to 1, default 1) |
| emoji_id? | ?snowflake | The ID of the sound's custom emoji |
| emoji_name? | ?string | The unicode character of the sound's emoji |
Modify Guild Soundboard Sound
Modifies the given soundboard sound. For sounds created by the current user, requires either the `CREATE_EXPRESSIONS` or MANAGE_EXPRESSIONS permission. For other sounds, requires the `MANAGE_EXPRESSIONS` permission. Returns the updated [soundboard sound](#soundboard-sound-object) object on success. Fires a [Guild Soundboard Sound Update](/gateway/gateway-events#guild-soundboard-sound-update) Gateway event.
###### JSON Params
| Field | Type | Description |
| ----------- | ---------- | ---------------------------------------------------------------------------------- |
| name? | string | The name of the soundboard sound (2-32 characters) |
| volume? | ?float | The volume of the soundboard sound (represented as a float from 0 to 1, default 1) |
| emoji_id? | ?snowflake | The ID of the sound's custom emoji |
| emoji_name? | ?string | The unicode character of the sound's emoji |
Delete Guild Soundboard Sound
For sounds created by the current user, requires either the `CREATE_EXPRESSIONS` or `MANAGE_EXPRESSIONS` permission. For other sounds, requires the `MANAGE_EXPRESSIONS` permission. Returns a 204 empty response on success. Fires a [Guild Soundboard Sound Delete](/gateway/gateway-events#guild-soundboard-sound-delete) Gateway event.
Get Soundboard Sound Guild
Returns a [discoverable guild](/resources/discovery#discoverable-guild-object) object for the guild that owns the given sound. This endpoint requires the guild to be discoverable, not be [auto-removed](/resources/discovery#discoverable-guild-object), and have [guild expression discoverability](/resources/discovery#discovery-metadata-object) enabled.
Send Soundboard Sound
Sends a soundboard sound to a voice channel. Returns a 204 empty response on success. Fires a [Voice Channel Effect Send](/gateway/gateway-events#voice-channel-effect-send) Gateway event.
Sending a soundboard sound requires the current user to be connected to the voice channel. The user cannot be server muted, deafened, or suppressed.
###### JSON Params
| Field | Type | Description |
| ---------------- | ---------- | ---------------------------------------------------------------- |
| sound_id | snowflake | The ID of the soundboard sound to send |
| source_guild_id? | ?snowflake | The ID of the sound's source guild, if applicable (not required) |
---
# Family Center
Link: https://docs.discord.food/resources/family-center
[Family Center](https://support.discord.com/hc/en-us/articles/14155043715735-Family-Center-for-Parents-and-Guardians) acts as Discord's parental controls solution to allow parents to monitor the activities of their teens on Discord. They do not allow parents to view message content, but Discord does share:
- Users messaged (DMs and Group DMs)
- Users called (DMs and Group DMs) in the last week
- Friends added in the last week
- Guilds joined in the last week
- Guilds the teen has sent messages to in the last week
A maximum of 8 accounts can be connected to a single parent.
Discord automatically removes all connected parents the month the teen turns 18 (as indicated by the age they entered after being prompted for their birthday). After this, viewing the Family Center from the teen's account will no longer show the option to display a QR code for connection, and attempts to generate a new code via the API will fail.
## Definitions
In line with the API, instead of referring to Family Center users as "parents" or "teens" and links as "family", "connected teens", or "my family", the API terminology will be used instead.
- **Requestor:** This is the user that _sends_ a link request to a different user and acts as the user the linked user is connected to. Can be viewed as the "parent."
- **Linked user:** This is the user that _receives_ or _accepts_ a link request sent by the requestor and acts as the user the "parent" can view the activity of. Can be viewed as the "teen."
- **Link:** Represents the connection between requestor and linked user.
### Family Center Object
###### Family Center Structure
| Field | Type | Description |
| -------------- | --------------------------------------------------------- | -------------------------------------------------- |
| linked_users | array[[linked user](#linked-user-object) object] | List of linked users |
| teen_audit_log | [teen audit log](#teen-audit-log-object) object | Audit log of the linked users activity |
| users | array[partial [user](/resources/user#user-object) object] | List of requestors the linked user is connected to |
### Linked User Object
Partial user data of an underage user linked to the requestor via [Family Center](https://support.discord.com/hc/en-us/articles/14155043715735-Family-Center-for-Parents-and-Guardians).
###### Linked User Structure
| Field | Type | Description |
| ---------------- | ----------------- | ----------------------------------------------------- |
| created_at | ISO8601 timestamp | When the link request was sent |
| updated_at | ISO8601 timestamp | When the link status was last updated |
| link_status | integer | The [link status](#link-status) of the linked user |
| link_type | integer | The [link type](#link-type) |
| requestor_id ^1^ | snowflake | The ID of the account the linked user is connected to |
| user_id ^1^ | snowflake | The ID of the linked user |
^1^ If the link type is `1`, the `user_id` and `requestor_id` will be the same. See [Link Type](#link-type) for more information.
###### Link Status
Represents the current state of the link.
| Value | Description |
| ----- | -------------------------------------------------------------- |
| 1 | The Family Center link request has been sent, but not accepted |
| 2 | The linked user is currently connected to the requestor |
| 3 | The link has been disconnected |
| 4 | The link request was rejected |
| 5 | The link request has expired |
###### Link Type
Represents what part each user played in the connection.
| Value | Description |
| ----- | ------------------------------------------------------------------------ |
| 1 | The current user accepted the request and is the linked user of the link |
| 2 | The current user sent the request and is the requestor of the link |
###### Example Linked User
```json
{
"created_at": "2024-07-30T19:49:09.800072+00:00",
"updated_at": "2024-07-30T19:55:43.834081+00:00",
"link_type": 2,
"link_status": 3,
"requestor_id": "246877849162743818",
"user_id": "801318363472330772"
}
```
### Linked Users Object
Lists all linked users and requestors. Not to be confused with the [Linked User](#linked-user-object) object.
###### Linked Users structure
| Field | Type | Description |
| ------------ | --------------------------------------------------------- | -------------------------------------------------- |
| linked_users | array[[linked user](#linked-user-object) object] | List of linked users |
| users | array[partial [user](/resources/user#user-object) object] | List of requestors the linked user is connected to |
### Teen Audit Log Object
Audit log of events of the linked user. Visible to both requestors and linked users.
###### Teen Audit Log Structure
| Field | Type | Description |
| -------------- | --------------------------------------------------------- | ------------------------------------------------------------------------ |
| teen_user_id | ?snowflake | The ID of the linked user |
| range_start_id | ?snowflake | A snowflake representing the start time of the current 7-day track range |
| actions | array[[action](#action-structure) object] | [Actions](#action-structure) the linked user has done |
| users | array[partial [user](/resources/user#user-object) object] | Users referenced in the audit log |
| guilds | array[[guild](/resources/guild#guild-object) object] | Guilds referenced in the audit log |
| totals | map[integer, integer] | Object keyed by [action types](#teen-action-type) with their totals |
###### Action Structure
| Field | Type | Description |
| ------------ | --------- | ----------------------------------------------------------------------------------------------------------------------------- |
| event_id | snowflake | The ID of the event action |
| user_id | snowflake | The ID of the linked user |
| entity_id | snowflake | The ID of the entity the action relates to (user, guild, or group DM) based off the [display type](#teen-action-display-type) |
| display_type | integer | The [display type](#teen-action-display-type) of the action, detailing what this action involved |
###### Teen Action Type
Represents a specific teen action.
| Value | Name | Description |
| ----- | ------------------------- | -------------------------------- |
| 1 | DM_MESSAGE_SEND | A DM message was sent |
| 2 | GDM_MESSAGE_SEND | A group DM message was sent |
| 3 | MESSAGE_REACT | A message reaction was added |
| 4 | ADD_FRIEND | A friend was added |
| 5 | SEND_CALL | A call was sent |
| 6 | CALL_JOIN | A call was joined |
| 7 | GUILD_JOIN | A guild was joined |
| 8 | GUILD_MESSAGE_SEND | A guild message was sent |
| 9 | GUILD_VC_JOIN | A guild voice channel was joined |
| 10 | GUILD_VOICE_CHANNEL_LEAVE | A guild voice channel was left |
| 11 | CALL_LEAVE | A call was left |
| 12 | CALL_START | A call was started |
| 13 | INVOICE_COMPLETE | An invoice was completed |
###### Teen Action Display Type
Represents the grouped display type of an action.
| Value | Name | Description |
| ----- | ------------------- | --------------------------------------------- |
| 1 | USER_ADD | Users added within the last 7 days |
| 2 | GUILD_ADD | Guilds joined within the last 7 days |
| 3 | USER_INTERACTION | Users interacted with in the last 7 days |
| 4 | GUILD_INTERACTION | Guilds interacted with in the last 7 days |
| 5 | USER_CALLED | Users called within the last 7 days |
| 6 | TOTAL_VOICE_MINUTES | Total voice minutes within the last 7 days |
| 7 | PURCHASES | Purchases within the last 7 days |
| 8 | GIFTS | Gifts sent or received within the last 7 days |
###### Example Teen Audit Log
```json
{
"teen_user_id": "801318363472330772",
"range_start_id": "1328607677722394624",
"actions": [
{
"event_id": "1331144363278860318",
"user_id": "801318363472330772",
"entity_id": "246877849162743818",
"display_type": 3
}
],
"users": [
{
"id": "246877849162743818",
"username": "jay_taelien",
"global_name": "Jay",
"avatar": "91b7bc37e924f78625f7ea582fdbac5d",
"avatar_decoration_data": {
"asset": "a_aa2e1c2b3cf05b24f6ec7b8b4141f5fc",
"sku_id": "1144056631374647458",
"expires_at": null
},
"discriminator": "0",
"public_flags": 16512,
"primary_guild": null
}
],
"guilds": [],
"totals": {
"1": 0,
"2": 0,
"3": 1,
"4": 0
}
}
```
## Endpoints
Get Family Center Overview
Returns a [Family Center](#family-center-object) object.
Get Link Code
Generates the link code for usage in the generated QR code that a linked user receives to give to a requestor.
The URL the QR Code represents follows this structure:
`https://discord.com/feature/family-center/my-family/:linked_user_id/:link_code`
Opening this link on the mobile app prompts the "send connection request" screen. Does nothing when visited on the Desktop client.
###### Response Body
| Field | Type | Description |
| ---------- | ------- | --------------------------------------------------------------------------------------------------------- |
| link_code | string | The code used to connect a requestor to a linked user, appended to the end of the URL the QR code encodes |
| expires_at | integer | Unix timestamp (in milliseconds) of when the link code expires |
Get Linked Users
Returns a [linked users](#linked-users-object) object.
Create Linked User Request
Creates a request that appears in the linked user's Family Center. Returns a [linked users](#linked-users-object) object on success. Fires a [User Update](/gateway/gateway-events#user-update) Gateway event.
###### JSON Params
| Field | Type | Description |
| ------------ | --------- | ---------------------------------------------------- |
| recipient_id | snowflake | The ID of the user the requestor wants to connect to |
| code | string | The link code from the linked user's device |
Modify Linked User
Modifies the linked user status of a linked user. Can be invoked by either the linked user or the requestor if used for removing the link. Returns an array of [linked user](#linked-user-object) objects on success. Fires a [User Update](/gateway/gateway-events#user-update) Gateway event.
###### JSON Params
| Field | Type | Description |
| ------------------ | --------- | ------------------------------------------------------------ |
| link_status | integer | The new [link status](#link-status) of the linked user |
| linked_user_id ^1^ | snowflake | The ID of the user the linked user or requestor is modifying |
^1^ If this request is sent to remove a link (setting [`link_status`](#link-status) to `3`), the `linked_user_id` changes depending on if the requestor or linked user is invoking it. If the linked user invokes the request, `linked_user_id` is the ID of the requestor, otherwise it's the ID of the linked user.
Remove Linked User
Removes a linked user. Returns a list of [linked user](#linked-user-object) objects on success. Fires a [User Update](/gateway/gateway-events#user-update) Gateway event.
###### JSON Params
| Field | Type | Description |
| -------------- | --------- | ----------------------------------- |
| linked_user_id | snowflake | The ID of the linked user to remove |
---
# Connected Accounts
Link: https://docs.discord.food/resources/connected-accounts
Connections are links between third party accounts to Discord accounts.
### Connection Object
The connection object that the user has attached.
###### Connection Structure
| Field | Type | Description |
| -------------------- | ------------------------------------------------------------------------- | ----------------------------------------------------------------------- |
| id | string | ID of the connection account |
| type | string | The [type](#connection-type) of the connection |
| name | string | The username of the connection account |
| verified | boolean | Whether the connection is verified |
| metadata? | object | Service-specific metadata about the connection |
| metadata_visibility | integer | [Visibility](#visibility-type) of the connection's metadata |
| revoked | boolean | whether the connection is revoked |
| integrations ^1^ ^2^ | array[[connection integration](#connection-integration-structure) object] | The guild integrations attached to the connection |
| friend_sync | boolean | Whether friend sync is enabled for this connection |
| show_activity | boolean | Whether activities related to this connection will be shown in presence |
| two_way_link | boolean | Whether this connection has a corresponding third party OAuth2 token |
| visibility | integer | [Visibility](#visibility-type) of the connection |
| access_token? ^1^ | string | The access token for the connection account |
^1^ Not included when [fetching a user's connections](#list-user-connections) via OAuth2.
^2^ These integrations can be used to [join your own sub-enabled guild or the guild of a creator you are supporting](/resources/integration#join-integration-guild).
###### Partial Connection Structure
| Field | Type | Description |
| --------- | ------- | ---------------------------------------------- |
| id | string | ID of the connection account |
| type | string | The [type](#connection-type) of the connection |
| name | string | The username of the connection account |
| verified | boolean | Whether the connection is verified |
| metadata? | object | Service-specific metadata about the connection |
###### Example Connection
```json
{
"type": "reddit",
"id": "run&hide",
"name": "alien",
"visibility": 1,
"friend_sync": false,
"show_activity": true,
"verified": true,
"two_way_link": false,
"metadata_visibility": 1,
"metadata": {
"gold": "0",
"mod": "1",
"total_karma": "20223",
"created_at": "2019-05-02T20:28:37"
},
"revoked": false,
"integrations": []
}
```
###### Example Partial Connection
```json
{
"type": "reddit",
"id": "run&hide",
"name": "alien",
"verified": true,
"metadata": {
"gold": "0",
"mod": "1",
"total_karma": "20223",
"created_at": "2019-05-02T20:28:37"
}
}
```
###### Connection Integration Structure
| Field | Type | Description |
| ------- | --------------------------------------------------------------------------- | ------------------------------------------------------------------ |
| id ^1^ | snowflake | The ID of the integration |
| type | string | The [type of integration](/resources/integration#integration-type) |
| account | [account](/resources/integration#integration-account-structure) object | The integration's account information |
| guild | [integration guild](/resources/integration#integration-guild-object) object | The guild that the integration is attached to |
^1^ This field may also be the literal string "twitch-partners" to represent the Twitch Partners integration.
###### Example Connection Integration
```json
{
"id": "twitch-partners",
"type": "twitch",
"account": {
"id": "92473777",
"name": "discordapp"
},
"guild": {
"id": "107939014299901952",
"name": "Twitch Partners",
"icon": "62450d21b75478191962d9c4b81831ae"
}
}
```
###### Connection Type
| Value | Name |
| --------------- | ----------------------------- |
| amazon-music | Amazon Music |
| battlenet | Battle.net |
| bluesky | Bluesky |
| bungie | Bungie.net |
| contacts ^2^ | Contact Sync |
| crunchyroll | Crunchyroll |
| domain | Domain |
| ebay | eBay |
| epicgames | Epic Games |
| facebook | Facebook |
| github | GitHub |
| instagram ^1^ | Instagram |
| leagueoflegends | League of Legends |
| mastodon | Mastodon |
| paypal | PayPal |
| playstation | PlayStation Network |
| playstation-stg | PlayStation Network (Staging) |
| reddit | Reddit |
| roblox | Roblox |
| riotgames | Riot Games |
| samsung ^1^ | Samsung Galaxy |
| soundcloud | SoundCloud |
| spotify | Spotify |
| skype ^1^ | Skype |
| steam | Steam |
| tiktok | TikTok |
| twitch | Twitch |
| twitter | Twitter |
| xbox | Xbox |
| youtube | YouTube |
^1^ Service can no longer be added by users.
^2^ Service is not returned in [Get User Profile](/resources/user#get-user-profile) or when [fetching a user's connections](#list-user-connections) via OAuth2.
###### Visibility Type
| Value | Name | Description |
| ----- | -------- | ------------------------------------------------ |
| 0 | NONE | Invisible to everyone except the user themselves |
| 1 | EVERYONE | Visible to everyone |
[Partial connections](#partial-connection-structure) always have a visibility of 1.
### Console Device Object
###### Console Device Structure
| Field | Type | Description |
| -------- | --------- | ----------------------------------------------------------------------------------------------- |
| id | snowflake | The ID of the device |
| name | string | The name of the device |
| platform | string | The [console platform](#connection-type) (only `playstation` and `playstation-stg` are allowed) |
###### Example Console Device
```json
{
"id": "1371598138300956672",
"name": "My Gifted PlayStation 5",
"platform": "playstation"
}
```
## Endpoints
Authorize User Connection
Returns an authorization link that can be used for authorizing a new connection.
###### Query String Params
| Field | Type | Description |
| ------------------ | ------- | ---------------------------------------------------------- |
| two_way_link_type? | ?string | The [type of two-way link](#two-way-link-type) to create |
| two_way_user_code? | ?string | The device code to use for the two-way link |
| continuation? | boolean | Whether this is a continuation of a previous authorization |
###### Two Way Link Type
| Value | Description |
| ------- | ------------------------------------ |
| web | The connection is linked via web |
| mobile | The connection is linked via mobile |
| desktop | The connection is linked via desktop |
###### Response Body
| Field | Type | Description |
| ----- | ------ | ----------------------------------- |
| url | string | The authorization link for the user |
Create User Connection Callback
Creates a new connection for the current user. Returns a [connection](#connection-object) object on success. Fires a [User Connections Update](/gateway/gateway-events#user-connections-update) Gateway event.
###### JSON Params
| Field | Type | Description |
| ------------------ | ------- | -------------------------------------------------- |
| code | string | The authorization code for the connection |
| state | string | The state used to authorize the connection |
| two_way_link_code? | string | The code to use for two-way linking |
| insecure? | boolean | Whether the connection is insecure (default false) |
| friend_sync? | boolean | Whether to sync friends over the connection |
| openid_params? | object | Additional parameters for OpenID Connect |
Create Contact Sync Connection
Creates a new contact sync connection for the current user. Returns a [connection](#connection-object) object on success. Fires a [User Connections Update](/gateway/gateway-events#user-connections-update) Gateway event.
This endpoint is only usable to create contact sync connections (nominally with an ID of @me). For most other connections, use [Authorize User Connection](#authorize-user-connection) and [Create User Connection Callback](#create-user-connection-callback).
###### JSON Params
| Field | Type | Description |
| ------------ | ------- | ------------------------------------------- |
| name | string | The username of the connection account |
| friend_sync? | boolean | Whether to sync friends over the connection |
Update External Friend List Entries
Syncs the user's device contacts to the connection. May fire multiple [Friend Suggestion Create](/gateway/gateway-events#friend-suggestion-create) Gateway events.
###### JSON Params
| Field | Type | Description |
| ------------------------------- | --------------------------------------------------------------- | ------------------------------------------------------------------------------------ |
| friend_list_entries | array[[friend list entry](#friend-list-entry-structure) object] | The phone numbers to sync (max 10000) |
| background | boolean | Whether the request is a background sync (will not return suggestions) |
| allowed_in_suggestions | integer | The [contact sync suggestions setting](#contact-sync-suggestions-setting) |
| include_mutual_friends_count | boolean | Whether to show the mutual friend count of contacts |
| add_reverse_friend_suggestions? | boolean | Whether to add users that have contact synced the current user as friend suggestions |
###### Friend List Entry Structure
| Field | Type | Description |
| --------- | ------ | ------------------------------------------- |
| friend_id | string | E.164-formatted phone number of the contact |
###### Contact Sync Suggestions Setting
| Value | Name | Description |
| ----- | ------------------------ | --------------------------------------------------------------------- |
| 1 | MUTUAL_CONTACT_INFO_ONLY | Users who have contact synced that have the current user as a contact |
| 2 | ANYONE_WITH_CONTACT_INFO | Users who have contact synced |
###### Response Body
| Field | Type | Description |
| ------------------ | ------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------- |
| bulk_add_token | ?string | Token to be used for [bulk adding relationships](/resources/relationships#bulk-add-relationships) |
| friend_suggestions | array[[friend suggestion](/resources/relationships#friend-suggestion-object) object] | Suggested users |
Contact Sync Settings
###### Response Body
| Field | Type | Description |
| ---------------------- | ------- | ------------------------------------------------------------------------- |
| allowed_in_suggestions | integer | The [contact sync suggestions setting](#contact-sync-suggestions-setting) |
Create Domain Connection
Creates a new domain connection for the current user. Returns a [connection](#connection-object) object on success. Fires a [User Connections Update](/gateway/gateway-events#user-connections-update) Gateway event.
This endpoint is only usable to create domain connections. For most other connections, use [Authorize User Connection](#authorize-user-connection) and [Create User Connection Callback](#create-user-connection-callback).
When attempting to create a domain connection, Discord will verify that the domain is owned by the user. If this verification fails, the endpoint will return an error response:
```json
{ "message": "Unable to validate domain.", "code": 50187, "proof": "dh=dceaca792e3c40fcf356a9297949940af5cfe538" }
```
The `proof` provided must be added to the domain's DNS records as a TXT record with the name `_discord.`. Alternatively, the proof can be served at `https:///.well-known/discord`.
After adding the proof, the request should be retried.
List User Connections
Returns a list of [connection](#connection-object) objects.
Get User Connection Access Token
Returns a new access token for the given connection. Only available for Twitch, YouTube, and Spotify connections. Fires a [User Connections Update](/gateway/gateway-events#user-connections-update) Gateway event.
###### Response Body
| Field | Type | Description |
| ------------ | ------ | ----------------------------- |
| access_token | string | The connection's access token |
List User Connection Subreddits
Returns a list of [subreddits](#subreddit-structure) the connected account moderates. Only available for Reddit connections.
###### Subreddit Structure
| Field | Type | Description |
| ----------- | ------- | --------------------------------- |
| id | string | The subreddit's ID |
| subscribers | integer | The number of joined Reddit users |
| url | string | The subreddit's relative URL |
###### Example Response
```json
[
{
"id": "t5_388p4",
"subscribers": 1044184,
"url": "/r/discordapp/"
}
]
```
Refresh User Connection
Refreshes a connection. Returns a 204 empty response on success. Fires a [User Connections Update](/gateway/gateway-events#user-connections-update) Gateway event.
Modify User Connection
Modifies a connection. Returns a [connection](#connection-object) object on success. Fires a [User Connections Update](/gateway/gateway-events#user-connections-update) Gateway event.
Not all connection types support all parameters.
###### JSON Params
| Field | Type | Description |
| ------------------- | ------- | ----------------------------------------------------------------------- |
| name | string | The connection's username |
| show_activity | boolean | Whether activities related to this connection will be shown in presence |
| friend_sync | boolean | Whether friend sync is enabled for this connection |
| metadata_visibility | integer | [Visibility](#visibility-type) of the connection's metadata |
| visibility | integer | [Visibility](#visibility-type) of the connection |
Delete User Connection
Deletes a connection. Returns a 204 empty response on success. Fires a [User Connections Update](/gateway/gateway-events#user-connections-update) and optionally a [Guild Delete](/gateway/gateway-events#guild-delete) Gateway event.
Deleting a connection will remove you from any guilds you joined via the connection's [integrations](#connection-integration-structure).
List User Linked Connections
This endpoint is only usable with an OAuth2 access token with the `connections` scope.
Returns a list of [connection](#connection-object) objects that have a two-way link with the application making the request.
Create Console Connection
Returns a nonce for connecting to voice on PlayStation consoles.
###### JSON Params
| Field | Type | Description |
| --------------------- | -------------------------------------------------------------------------- | --------------------------------- |
| analytics_properties? | [connect request properties](#connect-request-properties-structure) object | The properties used for analytics |
###### Connect Request Properties Structure
| Field | Type | Description |
| ------------ | ------ | ------------------------------------------------- |
| handoff_type | string | The [console handoff type](#console-handoff-type) |
###### Console Handoff Type
| Value | Description |
| ---------------------- | --------------------------------------------- |
| CREATE_NEW_CALL | Create a new call on a console device |
| TRANSFER_EXISTING_CALL | Transfer an existing call to a console device |
###### Response Body
| Field | Type | Description |
| ----- | ------ | ----------- |
| nonce | string | The nonce |
###### Example Response
```json
{ "nonce": "fgnmC0tT" }
```
Cancel Console Connection Request
Cancels a console connection request. Returns a 204 empty response on success.
List Console Devices
Returns the consoles associated with the given connection type. Only supports `playstation` and `playstation-stg` connection types.
###### Response Body
| Field | Type | Description |
| ------- | ------------------------------------------------------ | ------------------------ |
| devices | array[[console device](#console-device-object) object] | The user console devices |
Send Console Command
Sends a command to connect to a voice call on a console device.
###### JSON Params
| Field | Type | Description |
| ---------- | --------- | ---------------------------------------------------------------------------------------- |
| command | string | The [command type](#console-command-type) |
| channel_id | snowflake | The ID of the channel to connect to |
| guild_id? | snowflake | The ID of the guild the channel is in |
| nonce? | string | The nonce obtained from [Create Console Connection](#create-console-connection) endpoint |
###### Console Command Type
| Value | Description |
| ------------- | ----------------------- |
| connect_voice | Connect to a voice call |
###### Response Body
| Field | Type | Description |
| ----- | --------- | -------------------------- |
| id | snowflake | The ID of the sent command |
Cancel Console Command
Cancels a console command. Returns a 204 empty response on success.
---
# Teams
Link: https://docs.discord.food/resources/team
Teams are groups of developers on Discord who want to collaborate on apps. On other platforms, these may be referred to as "organizations", "companies", or "teams". Discord went with the name Teams because it best encompassed all the awesome conglomerates of devs that work together to make awesome things on Discord. Also, none of you ever got picked for kickball in gym class, so now you get to be on a team.
Teams allow you and other Discord users to share access to apps. No more sharing login credentials in order to reset the token on a bot that your friend owns but you work on, or other such cases.
For game developers, this means that you can get your engineers access to your app for credentials they may need, your marketing folks access to store page management, and your finance people access to sales and performance metrics.
### Team Object
###### Team Structure
| Field | Type | Description |
| ------------------------------ | ------------------------------------------------------------------- | ------------------------------------------------------------------------------ |
| id | snowflake | The ID of the team |
| name | string | The name of the team |
| icon ^1^ | ?string | The team's [icon hash](/reference#cdn-formatting) |
| owner_user_id | snowflake | The ID of the team's owner |
| members? ^2^ | array[[team member](#team-member-object) object] | The members in the team |
| payout_account_status? ^3^ | ?integer | The [status of the team's primary payout account](#team-payout-account-status) |
| payout_account_statuses? ^3^ | array[[team payout account](#team-payout-account-structure) object] | The statuses of the team's payout accounts |
| stripe_connect_account_id? ^4^ | string | The ID of the team's Stripe Connect account |
^1^ The default team icon uses the same images as [default avatars](/reference#cdn-formatting) and can be calculated using `team_id % 5`.
^2^ Only provided in the [application](/resources/application#application-object) object.
^3^ Only included when fetched from [Get Team](#get-team) or [List Teams](#list-teams) with `include_payout_account_status` set to `true`.
^4^ Only included when fetched from [Get Team](#get-team).
###### Team Payout Account Structure
| Field | Type | Description |
| ------- | ------- | --------------------------------------------------------------- |
| gateway | integer | The [payout gateway](#team-payout-gateway) used |
| status | integer | The [status of the payout account](#team-payout-account-status) |
###### Team Payout Gateway
| Value | Name | Description |
| ----- | -------------- | ------------- |
| 1 | STRIPE_TOPUP | Stripe Top-Up |
| 2 | TIPALTI | Tipalti |
| 3 | STRIPE_PRIMARY | Stripe |
###### Team Payout Account Status
| Value | Name | Description |
| ----- | --------------- | ------------------------------------------------------------- |
| 1 | UNSUBMITTED | Team has not submitted a payout account application |
| 2 | PENDING | Team's payout account application is pending approval |
| 3 | ACTION_REQUIRED | Team's payout account requires action to receive payouts |
| 4 | ACTIVE | Team's payout account is active and can receive payouts |
| 5 | BLOCKED | Team's payout account is blocked and cannot receive payouts |
| 6 | SUSPENDED | Team's payout account is suspended and cannot receive payouts |
###### Example Team
```json
{
"id": "1110738998453837384",
"icon": null,
"name": "Power",
"owner_user_id": "852892297661906993",
"payout_account_status": 1,
"payout_account_statuses": [{ "gateway": 1, "status": 1 }]
}
```
### Team Member Object
###### Team Member Structure
| Field | Type | Description |
| ---------------- | -------------------------------------------------- | ---------------------------------------------------------- |
| user | partial [user](/resources/user#user-object) object | The user this team member represents |
| team_id | snowflake | The ID of the team the user is a member of |
| membership_state | integer | The user's [team membership state](#team-membership-state) |
| role | string | The user's [role](#team-member-roles) on the team |
###### Team Membership State
| Value | Name | Description |
| ----- | -------- | -------------------------------- |
| 1 | INVITED | The user is invited |
| 2 | ACCEPTED | The user has accepted the invite |
## Team Member Roles
Team members can be one of four roles (owner, admin, developer, and read-only), and each role inherits the access of those below it. Roles for team members can be configured under **Team Members** in a team's settings.
###### Team Member Role Types
| Value | Description |
| --------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| admin | Admins have similar access to owners, except they cannot take destructive actions on the team or team-owned apps. |
| developer | Developers can access information about team-owned apps, like the client secret or public key. They can also take limited actions on team-owned apps, like configuring interaction endpoints or resetting the bot token. Members with the Developer role _cannot_ manage the team or its members, or take destructive actions on team-owned apps. |
| read_only | Read-only members can access information about a team and any team-owned apps. Some examples include getting the IDs of applications and exporting payout records. |
##### Example Team Member
```json
{
"user": {
"id": "852892297661906993",
"username": "alien",
"global_name": "Alien",
"avatar": "05145cc5646fbcba277b6d5ea2030610",
"discriminator": "0",
"public_flags": 64,
"avatar_decoration_data": null,
"primary_guild": null
},
"team_id": "1110738998453870732",
"membership_state": 2,
"role": "admin"
}
```
### Team Payout Object
###### Team Payout Structure
| Field | Type | Description |
| ----------------------------------- | ------------------ | ----------------------------------------------- |
| id | snowflake | The ID of the payout |
| user_id | snowflake | The ID of the user who receives the payout |
| amount | integer | The amount of the payout |
| status | integer | The [status of the payout](#team-payout-status) |
| period_start | ISO8601 timestamp | When the payout period started |
| period_end | ?ISO8601 timestamp | When the payout period ended |
| payout_date | ?ISO8601 timestamp | When the payout was made |
| latest_tipalti_submission_response? | object | The latest response from Tipalti |
###### Team Payout Status
| Value | Name | Description |
| ----- | ----------------- | -------------------------------------------- |
| 1 | OPEN | The payout is open |
| 2 | PAID | The payout has been paid out |
| 3 | PENDING | The payout is pending completion |
| 4 | MANUAL | The payout has been manually made |
| 5 | CANCELLED | The payout has been cancelled |
| 6 | DEFERRED | The payout has been deferred |
| 7 | DEFERRED_INTERNAL | The payout has been deferred internally |
| 8 | PROCESSING | The payout is processing |
| 9 | ERROR | The payout has errored |
| 10 | REJECTED | The payout has been rejected |
| 11 | RISK_REVIEW | The payout is under risk review |
| 12 | SUBMITTED | The payout has been submitted for completion |
| 13 | PENDING_FUNDS | The payout is pending sufficient funds |
###### Example Team Payout
```json
{
"id": "1110738998453870732",
"user_id": "852892297661906993",
"amount": 1000000,
"status": 1,
"period_start": "2021-01-01",
"period_end": null,
"payout_date": null
}
```
### Company Object
A development/publishing company working on a game on Discord.
###### Company Structure
| Field | Type | Description |
| ----- | --------- | ----------------------- |
| id | snowflake | The ID of the company |
| name | string | The name of the company |
###### Example Company
```json
{
"id": "1058932127820939295",
"name": "AlienTec"
}
```
## Endpoints
List Teams
Returns a list of [team](#team-object) objects that the current user is a member of.
###### Query String Params
| Field | Type | Description |
| ------------------------------ | ------- | ------------------------------------------------------------------------------------------------------------ |
| include_payout_account_status? | boolean | Whether to include team [payout account status](#team-payout-account-status) in the response (default false) |
Create Team
Creates a new team. Returns a [team](#team-object) object on success. Users can join a maximum of 30 teams.
This action requires the user to have MFA enabled.
###### JSON Params
| Field | Type | Description |
| ----- | ------ | -------------------- |
| name | string | The name of the team |
Get Team
Returns a [team](#team-object) object for the given team ID.
Modify Team
Modifies a team. User must be an admin of the team. Returns the updated [team](#team-object) object on success.
###### JSON Params
| Field | Type | Description |
| -------------- | ---------------------------------- | ------------------------------------------------------ |
| name? | string | The name of the team |
| icon? | ?[image data](/reference#cdn-data) | The team's icon |
| owner_user_id? | snowflake | The ID of the team's owner (must be the current owner) |
Delete Team
Deletes a team permanently. User must be the owner of the team. Returns a 204 empty response on success.
Accept Team Invite
Accepts an invite to join a team. Returns a [team](#team-object) object on success. Users can join a maximum of 30 teams.
This action requires the user to have MFA enabled.
###### JSON Params
| Field | Type | Description |
| --------- | ------ | --------------------- |
| token ^1^ | string | The team invite token |
^1^ This token can be retrieved by visiting the emailed `https://click.discord.com/` link and extracting the `#token` URI fragment from the redirect URL.
List Team Members
Returns a list of [team member](#team-member-object) objects for the given team ID.
Add Team Member
Invites a user to the team. User must be an admin of the team. Returns a [team member](#team-member-object) object on success.
You must be friends with the user you are inviting.
###### JSON Params
| Field | Type | Description |
| ------------------ | ------- | ------------------------------------------------- |
| username | string | The username of the user to invite |
| discriminator? ^1^ | ?string | The discriminator of the user to invite |
| role | string | The user's [role](#team-member-roles) on the team |
^1^ `null` for migrated users. See the [section on Discord's new username system](/resources/user#unique-usernames) for more information.
Modify Team Member
Modifies a team member. User must be an admin of the team. Returns the updated [team member](#team-member-object) object on success.
The team owner cannot be modified.
###### JSON Params
| Field | Type | Description |
| ----- | ------ | ------------------------------------------------- |
| role? | string | The user's [role](#team-member-roles) on the team |
Remove Team Member
Removes a team member. User must be an admin of the team unless removing themselves. Returns a 204 empty response on success.
List Team Applications
Returns a list of [application](/resources/application#application-object) objects for the given team ID.
Get Team Stripe Connect URL
Returns a link that can be used to access the team's Stripe Connect payout account dashboard.
Stripe Connect can only be used for payouts to US bank accounts.
###### JSON Params
| Field | Type | Description |
| ------------- | ------ | ---------------------------------------------------------------------------------------------- |
| country_code? | string | The [ISO 3166-1 alpha-2](https://en.wikipedia.org/wiki/ISO_3166-1_alpha-2) country code to use |
###### Response Body
| Field | Type | Description |
| --------------------------- | ------ | ------------------------------- |
| stripe_connect_redirect_url | string | The Stripe Connect redirect URL |
###### Example Response
```json
{
"stripe_connect_redirect_url": "https://connect.stripe.com/setup/e/acct_123456/789abcd"
}
```
Get Team Payout Onboarding
Returns a link that can be embedded in an IFrame to allow the user to access the team's Tipalti payout account dashboard. User must be the owner of the team.
Tipalti can be used for payouts to international bank accounts.
###### Response Body
| Field | Type | Description |
| ----- | ------ | ----------------------- |
| url | string | The payee dashboard URL |
###### Example Response
```json
{
"url": "https://ui2.tipalti.com/payeedashboard/home?ts=12345&idap=10418817887227111107389984538707326773&payer=Discord&hashkey=123456abcd"
}
```
List Team Payouts
Returns a list of [team payout](#team-payout-object) objects for the given team ID.
###### Query String Params
| Field | Type | Description |
| ------ | --------- | -------------------------------------------------- |
| limit? | number | Max number of payouts to return (1-96, default 96) |
| after? | snowflake | Return payouts after this ID |
Get Team Payout Report
Returns a CSV file containing the payout report for the given payout ID.
###### Query String Params
| Field | Type | Description |
| ----- | ------ | ---------------------------------------------------------- |
| type | string | The [type of report](#team-payout-report-type) to generate |
###### Team Payout Report Type
| Value | Description |
| ----------- | --------------------- |
| sku | Report by SKU |
| transaction | Report by transaction |
Search Companies
Returns a list of [company](#company-object) objects that match the given query. If no query is provided, returns a 204 empty response.
###### Query String Params
| Field | Type | Description |
| ----- | ------ | ------------------------------------ |
| name? | string | Query to match company names against |
Get Company
Returns a [company](#company-object) object for the given company ID.
Create Company
Creates a new company under this team. Returns a [company](#company-object) object on success.
###### JSON Params
| Field | Type | Description |
| ----- | ------ | ----------------------- |
| name | string | The name of the company |
Create Team Identity Verification
Creates a new verification attempt for the team. Returns a [user identity verification](/resources/user#user-identity-verification-object) object on success.
Initiating an identity verification permanently locks the team out of manually transferring team ownership, Discord support must be contacted instead.
User must be the owner of the team.
###### JSON Params
| Field | Type | Description |
| ---------- | ------ | --------------------------------------------------------- |
| return_url | string | The URL to redirect to after Stripe verification succeeds |
Get Team Identity Verification
Returns a [user identity verification](/resources/user#user-identity-verification-object) object representing the most recent verification attempt.
---
# Webhooks
Link: https://docs.discord.food/resources/webhook
Webhooks are a low-effort way to post messages to channels in Discord. They do not require a bot user or authentication to use.
### Webhook Object
Used to represent a webhook.
###### Webhook Structure
| Field | Type | Description |
| ------------------- | --------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------- |
| id | snowflake | The ID of the webhook |
| type | integer | The [type of webhook](#webhook-types) |
| guild_id? | ?snowflake | The guild ID this webhook is for, if any |
| channel_id | ?snowflake | The channel ID this webhook is for, if any |
| user? ^3^ | ?partial [user](/resources/user#user-object) object | The user this webhook was created by |
| name | ?string | The default name of the webhook (1-80 characters) |
| avatar | ?string | The default [avatar hash](/reference#cdn-formatting) of the webhook |
| token? ^1^ | string | The secure token of the webhook (returned for `INCOMING` webhooks) |
| application_id | ?snowflake | The application that created this webhook |
| source_guild? ^2^ | [integration guild](/resources/integration#integration-guild-object) object | The guild of the channel that this webhook is following (returned for `CHANNEL_FOLLOWER` webhooks) |
| source_channel? ^2^ | [webhook channel](#webhook-channel-structure) object | The channel that this webhook is following (returned for `CHANNEL_FOLLOWER` webhooks) |
| url? ^1^ | string | The URL used for executing the webhook (returned for `INCOMING` webhooks) |
^1^ For application-owned webhooks, this field is only returned to the application that created the webhook.
^2^ These fields will not be included if the webhook creator has since lost access to the followed channel's guild.
^3^ This field is not included when the webhook is retrieved with its token.
###### Webhook Types
| Value | Name | Description |
| ----- | ---------------- | --------------------------------------------------------------------------------------- |
| 1 | INCOMING | Incoming webhooks can post messages to channels with a generated token |
| 2 | CHANNEL_FOLLOWER | Channel Follower webhooks are internal webhooks used to post new messages into channels |
| 3 | APPLICATION | Application webhooks are webhooks used with interactions |
###### Webhook Channel Structure
| Field | Type | Description |
| ----- | --------- | ------------------------------------------ |
| id | snowflake | The ID of the channel |
| name | string | The name of the channel (1-100 characters) |
###### Example Incoming Webhook
```json
{
"application_id": null,
"avatar": null,
"channel_id": "199737254929760256",
"guild_id": "199737254929760256",
"id": "223704706495545344",
"name": "test webhook",
"type": 1,
"user": {
"id": "828387742575624222",
"username": "jupppper",
"avatar": "e14a7c62b0b38068be88be194b23910f",
"discriminator": "0",
"public_flags": 16384,
"banner": null,
"accent_color": null,
"global_name": "Jup",
"avatar_decoration_data": null,
"primary_guild": null
},
"token": "3d89bb7572e0fb30d8128367b3b1b44fecd1726de135cbe28a41f8b2f777c372ba2939e72279b94526ff5d1bd4358d65cf11",
"url": "https://discord.com/api/webhooks/223704706495545344/3d89bb7572e0fb30d8128367b3b1b44fecd1726de135cbe28a41f8b2f777c372ba2939e72279b94526ff5d1bd4358d65cf11"
}
```
###### Example Channel Follower Webhook
```json
{
"application_id": null,
"avatar": "bb71f469c158984e265093a81b3397fb",
"channel_id": "561885260615255432",
"guild_id": "56188498421443265",
"id": "752831914402115456",
"name": "Guildy name",
"type": 2,
"source_guild": {
"id": "56188498421476534",
"name": "Guildy name",
"icon": "bb71f469c158984e265093a81b3397fb"
},
"source_channel": {
"id": "5618852344134324",
"name": "announcements"
},
"user": {
"id": "828387742575624222",
"username": "jupppper",
"avatar": "e14a7c62b0b38068be88be194b23910f",
"discriminator": "0",
"public_flags": 16384,
"banner": null,
"accent_color": null,
"global_name": "Jup",
"avatar_decoration_data": null,
"primary_guild": null
}
}
```
###### Example Application Webhook
```json
{
"application_id": "658822586720976555",
"avatar": "689161dc90ac261d00f1608694ac6bfd",
"channel_id": null,
"guild_id": null,
"id": "658822586720976555",
"name": "Clyde",
"type": 3,
"user": null
}
```
## Endpoints
Create Webhook
Creates a new webhook. Requires the `MANAGE_WEBHOOKS` permission. Returns a [webhook](#webhook-object) object on success. Fires a [Webhooks Update](/gateway/gateway-events#webhooks-update) Gateway event.
Webhook names follow the naming restrictions set out in the [Usernames and Nicknames](/resources/user#usernames-and-nicknames) documentation.
###### JSON Params
| Field | Type | Description |
| ------- | ---------------------------------- | ------------------------------------------------- |
| name | string | The default name of the webhook (1-80 characters) |
| avatar? | ?[image data](/reference#cdn-data) | The default avatar of the webhook |
List Channel Webhooks
Returns a list of channel [webhook](#webhook-object) objects. Requires the `MANAGE_WEBHOOKS` permission.
List Guild Webhooks
Returns a list of guild [webhook](#webhook-object) objects. Requires the `MANAGE_WEBHOOKS` permission.
Get Webhook
Returns a [webhook](#webhook-object) object for the given webhook ID. Requires the `MANAGE_WEBHOOKS` permission unless the application making the request owns the webhook.
Get Webhook with Token
Same as above, except this call does not require authentication and omits the `user` field in the response.
Modify Webhook
Modifies a webhook. Requires the `MANAGE_WEBHOOKS` permission. Returns the updated [webhook](#webhook-object) object on success. Fires a [Webhooks Update](/gateway/gateway-events#webhooks-update) Gateway event.
###### JSON Params
| Field | Type | Description |
| ----------- | ---------------------------------- | ------------------------------------------------- |
| name? | string | The default name of the webhook (1-80 characters) |
| avatar? | ?[image data](/reference#cdn-data) | The default avatar of the webhook |
| channel_id? | snowflake | The channel ID this webhook should be moved to |
Modify Webhook with Token
Same as above, except this call does not require authentication, does not accept a `channel_id` parameter, and omits the `user` field in the response.
###### JSON Params
| Field | Type | Description |
| ------- | ---------------------------------- | ------------------------------------------------- |
| name? | string | The default name of the webhook (1-80 characters) |
| avatar? | ?[image data](/reference#cdn-data) | The default avatar of the webhook |
Delete Webhook
Deletes a webhook permanently. Requires the `MANAGE_WEBHOOKS` permission. Returns a 204 empty response on success. Fires a [Webhooks Update](/gateway/gateway-events#webhooks-update) Gateway event.
Delete Webhook with Token
Same as above, except this call does not require authentication.
Execute Webhook
Discord may strip certain characters from message content, like invalid unicode characters or characters which cause unexpected message formatting. If you are passing user-generated strings into message content, consider sanitizing the data to prevent unexpected behavior and using `allowed_mentions` to prevent unexpected mentions.
This endpoint cannot be used from Discord client domain origins.
Posts a message to the webhook's channel. Returns a [message](/resources/message#message-object) object or 204 empty response, depending on `wait`. Fires a [Message Create](/gateway/gateway-events#message-create) Gateway event. See [message formatting](/reference#message-formatting) for more information on how to properly format messages.
Files must be attached using a `multipart/form-data` body (or pre-uploaded to Discord's GCP bucket) as described in [Uploading Files](/reference#uploading-files).
###### Limitations
- When executing on a forum channel, _one of_ `thread_id` or `thread_name` must be provided.
- The maximum request size when sending a message is **200 MiB**.
- For the embed object, you can set every field except `type` (it will be `rich` regardless of if you try to set it), `provider`, `video`, and any `height`, `width`, or `proxy_url` values for images.
Note that when sending a message, you must provide a value for **at least one of** `content`, `embeds`, `components`, `files[n]`, or `poll`.
###### Query String Params
| Field | Type | Description |
| ---------- | --------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| wait? | boolean | Waits for confirmation of message send before response, and returns the created message body (default false; when false a message that is not saved does not return an error) |
| thread_id? | snowflake | Send a message to the specified thread within a webhook's channel; the thread will automatically be unarchived |
###### JSON/Form Params
| Field | Type | Description |
| ----------------- | ------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------ |
| username? | string | The name to override the default username of the webhook with (1-80 characters) |
| avatar_url? | string | The avatar URL to override the default avatar of the webhook with |
| thread_name? | string | The name for the thread to create (requires the webhook channel to be a thread-only channel, 1-100 characters) |
| applied_tags? | array[snowflake] | The IDs of the tags that are applied to the thread (requires the webhook channel to be a thread-only channel, max 5) |
| content? | string | The message contents (up to 2000 characters) |
| tts? | boolean | Whether this is a TTS message |
| embeds? | array[[embed](/resources/message#embed-object) object] | Embedded `rich` content (max 6000 characters, max 10) |
| allowed_mentions? | [allowed mention](/resources/message#allowed-mentions-object) object | Allowed mentions for the message |
| components? ^2^ | array[[message component](/resources/components#component-object) object] | The components to include with the message |
| flags? | integer | The [message's flags](/resources/message#message-flags) (only `SUPPRESS_EMBEDS`, `SUPPRESS_NOTIFICATIONS`, and `VOICE_MESSAGE` can be set) |
| files[n]? ^1^ | file contents | Contents of the file being sent (max 10) |
| attachments? ^1^ | array[partial [attachment](/resources/message#attachment-object) object] | Partial attachment objects with `filename` and `description` (max 10) |
| poll? | [poll create request](/resources/message#poll-create-structure) object | A poll! |
^1^ See [Uploading Files](/reference#uploading-files) for details.
^2^ Requires `with_components` query parameter. Interactions only work with an application-owned webhook.
Get Service Webhook
Validates a given webhook and service. Currently, the only supported services are `github` and `slack`. Returns a 200 OK response on success.
Execute Service Webhook
Posts a message to the webhook's channel from a supported service. Currently, the only supported services are `github` and `slack`. Returns a [message](/resources/message#message-object) object or 204 empty response, depending on `wait`.
Fires a [Message Create](/gateway/gateway-events#message-create) Gateway event. See [message formatting](/reference#message-formatting) for more information on how to properly format messages.
This endpoint cannot be used from Discord client domain origins.
###### Slack-Compatible Webhook
Refer to [Slack's documentation](https://api.slack.com/incoming-webhooks) for more information. Does not support Slack's `channel`, `icon_emoji`, `mrkdwn`, or `mrkdwn_in` properties.
###### Github-Compatible Webhook
[Add a new webhook](https://support.discord.com/hc/en-us/articles/228383668-Intro-to-Webhooks), and use this endpoint as the "Payload URL".
You can choose what events your Discord channel receives by choosing the "Let me select individual events" option and selecting individual events for the new webhook you're configuring.
The supported [events](https://docs.github.com/en/webhooks/webhook-events-and-payloads) are `commit_comment`, `create`, `delete`, `fork`, `issue_comment`, `issues`, `member`, `public`, `pull_request`, `pull_request_review`, `pull_request_review_comment`, `push`, `release`, `watch`, `check_run`, `check_suite`, `discussion`, and `discussion_comment`.
###### Query String Params
| Field | Type | Description |
| ---------- | --------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| wait? | boolean | Waits for confirmation of message send before response, and returns the created message body (default false; when false a message that is not saved does not return an error) |
| thread_id? | snowflake | Send a message to the specified thread within a webhook's channel; the thread will automatically be unarchived |
Get Webhook Message
Returns a previously-sent webhook [message](/resources/message#message-object) object from the same token.
Edit Webhook Message
Edits a previously-sent webhook message from the same token. Returns the updated [message](/resources/message#message-object) object on success. Fires a [Message Update](/gateway/gateway-events#message-update) Gateway event.
When the `content` field is edited, the `mentions` array in the message object will be reconstructed from scratch based on the new content. The `allowed_mentions` field of the edit request controls how this happens. If there is no explicit `allowed_mentions` in the edit request, the content will be parsed with _default_ allowances, that is, without regard to whether or not an `allowed_mentions` was present in the request that originally created the message.
Refer to [Uploading Files](/reference#uploading-files) for details on attachments and `multipart/form-data` requests.
Any provided files will be **appended** to the message. To remove or replace files you will have to supply the `attachments` field which specifies the files to retain on the message after edit.
This endpoint cannot be used from Discord client domain origins.
Starting with API v10, the `attachments` array must contain all attachments that should be present after edit, including **retained and new** attachments provided in the request body.
###### JSON/Form Params
| Field | Type | Description |
| ----------------- | ------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------ |
| content? | string | The message contents (up to 2000 characters) |
| tts? | boolean | Whether this is a TTS message |
| embeds? | array[[embed](/resources/message#embed-object) object] | Embedded `rich` content (max 6000 characters, max 10) |
| allowed_mentions? | [allowed mention](/resources/message#allowed-mentions-object) object | Allowed mentions for the message |
| components? ^2^ | array[[message component](/resources/components#component-object) object] | The components to include with the message |
| flags? | integer | The [message's flags](/resources/message#message-flags) (only `SUPPRESS_EMBEDS`, `SUPPRESS_NOTIFICATIONS`, and `VOICE_MESSAGE` can be set) |
| files[n]? ^1^ | file contents | Contents of the file being sent (max 10) |
| attachments? ^1^ | array[partial [attachment](/resources/message#attachment-object) object] | Partial attachment objects with `filename` and `description` (max 10) |
^1^ See [Uploading Files](/reference#uploading-files) for details.
^2^ Requires an application-owned webhook.
Delete Webhook Message
Deletes a message that was created by the webhook. Returns a 204 empty response on success. Fires a [Message Delete](/gateway/gateway-events#message-delete) Gateway event.
This endpoint cannot be used from Discord client domain origins.
---
# Collectibles
Link: https://docs.discord.food/resources/collectibles
Collectibles are SKUs representing digital items that users typically purchase in the Discord Shop to customize their profiles and avatars.
### Collectible Product Object
###### Collectible Product Structure
| Field | Type | Description |
| -------------------- | ------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------ |
| sku_id | snowflake | The SKU ID of the collectible product |
| store_listing_id | snowflake | The store listing ID associated with the collectible product |
| type | integer | The [type of collectible](#collectible-product-type) |
| bundled_products? | array[[collectible product](#collectible-product-structure) object] | The bundled products included in the collectible product |
| category_sku_id | snowflake | The category SKU ID of the collectible product |
| google_sku_ids? | map[integer, string] | The Google SKU IDs for the collectible per [purchase type](/resources/store#subscription-plan-purchase-type) |
| eligible_offers? | array[snowflake] | The IDs of eligible user discount offers for the product |
| items ^3^ | array[[collectible item](#collectible-item-object) object] | The items included in the collectible product |
| name | string | The name of the collectible product |
| premium_type | integer | The premium type required to purchase the collectible product |
| prices? | map[integer, [subscription prices](/resources/store#subscription-prices-structure) object] | The prices for the collectible per [purchase type](/resources/store#subscription-plan-purchase-type) |
| preview_assets? | [collectible preview assets](#collectible-preview-assets-structure) object | Preview assets for the collectible product |
| styles | [collectible styles](#collectible-style-structure) object | The colors to use in the client |
| summary | string | A description of the collectible product |
| unpublished_at | ?ISO8601 timestamp | When the collectible product should be unpublished |
| base_variant_name? | string | The name of the base variant of the collectible product |
| base_variant_sku_id? | snowflake | The SKU ID of the base variant of the collectible product |
| expires_at? ^2^ | ?ISO8601 timestamp | When the collectible product expires |
| purchase_type? ^2^ | integer | The [purchase type](#collectible-purchase-type) of the collectible product |
| purchased_at? ^2^ | ISO8601 timestamp | When the collectible product was purchased |
| badge_override? | ?string | The badge override text for the collectible product |
| hide_badge? | boolean | Whether to hide the product badge (default false) |
| variant_label? | string | The label for the variant of the collectible product |
| variant_value? | string | The hex value of the color for the variant of the collectible product |
| variants? ^1^ | array[[collectible product](#collectible-product-structure) object] | The variants of the collectible product |
^1^ Only included when `variants_return_style` is set to `VARIANTS_GROUP`, otherwise each variant will be returned as a separate product.
^2^ Only present on collectibles purchases endpoint.
^3^ If the product type is `VARIANTS_GROUP`, `items` will be empty and instead `variants` should be used.
###### Collectible Style Structure
| Field | Type | Description |
| ----------------- | -------------- | ----------------------------- |
| background_colors | array[integer] | An array of background colors |
| button_colors | array[integer] | An array of button colors |
| confetti_colors | array[integer] | An array of confetti colors |
###### Collectible Preview Assets Structure
| Field | Type | Description |
| ------------ | ------ | ------------------------------------- |
| fg_static? | string | The static foreground preview asset |
| fg_animated? | string | The animated foreground preview asset |
| bg_static? | string | The static background preview asset |
| bg_animated? | string | The animated background preview asset |
###### Collectible Purchase Type
| Value | Name | Description |
| ----- | ------------ | ------------------------------------ |
| 1 | PURCHASED | Purchased normally |
| 5 | PROMOTIONAL | Received through a promotional event |
| 6 | GIFTED | Received as a gift |
| 7 | SUBSCRIPTION | Claimed with a premium subscription |
| 10 | QUEST | Received from a quest |
### Collectible Item Object
###### Collectible Product Type
| Value | Name | Description |
| ----- | ------------------------------------------------------------------ | ----------------------------------------------- |
| 0 | [AVATAR_DECORATION](#avatar-decoration-collectible-item-structure) | An avatar decoration |
| 1 | [PROFILE_EFFECT](#profile-effect-collectible-item-structure) | A profile effect |
| 2 | [NAMEPLATE](#nameplate-collectible-item-structure) | A nameplate |
| 3 | [PROFILE_FRAME](#profile-frame-collectible-item-structure) | A profile frame |
| 1000 | BUNDLE | A bundle of collectibles |
| 2000 | VARIANTS_GROUP | A group of variants |
| 3000 | EXTERNAL_SKU | A non-collectible SKU (e.g. fractional premium) |
###### Avatar Decoration Collectible Item Structure
| Field | Type | Description |
| ------ | -------------------------------------------- | -------------------------------------------------------------------- |
| type | integer | The [type of collectible](#collectible-product-type) |
| sku_id | snowflake | The SKU ID of the avatar decoration |
| asset | string | The asset hash of the avatar decoration |
| assets | [item assets](#item-assets-structure) object | The URLs for the static and animated images of the avatar decoration |
| label | string | The avatar decoration accessibility description |
###### Profile Effect Collectible Item Structure
| Field | Type | Description |
| ------------------- | ----------------------------------------------------------------------------- | ---------------------------------------------------------------------------------- |
| type | integer | The [type of collectible](#collectible-product-type) |
| sku_id | snowflake | The ID of the profile effect SKU |
| title | string | The title of the profile effect |
| description | string | The description of the profile effect |
| accessibilityLabel | string | An accessible description of the profile effect |
| animationType | integer | The [type of animation](#profile-effect-animation-type) used by the profile effect |
| thumbnailPreviewSrc | string | The URL of the profile effect's thumbnail preview image (in APNG format) |
| reducedMotionSrc | string | A URL of the profile effect with reduced motion (in APNG format) |
| staticFrameSrc? | string | The URL of the static frame of the profile effect (in PNG format) |
| effects | array[[profile effect animation](#profile-effect-animation-structure) object] | The animation frames for the profile effect |
###### Profile Effect Animation Structure
| Field | Type | Description |
| ----------------- | ----------------------------------------------------------------------- | ---------------------------------------------------------------- |
| src | string | The URL of the animation image (in APNG format) |
| loop | boolean | Whether the animation frame should loop |
| height | integer | The height of the animation image |
| width | integer | The width of the animation image |
| duration | integer | The duration of the animation frame (in milliseconds) |
| start | integer | The start time of the animation frame (in milliseconds) |
| loopDelay | integer | The delay between loops of the animation frame (in milliseconds) |
| position | [profile effect position](#profile-effect-position-structure) object | The position of the animation frame |
| zIndex | integer | The z-index of the animation frame |
| randomizedSources | array[[profile effect source](#profile-effect-source-structure) object] | The sources to randomize the `src` from |
###### Profile Effect Position Structure
| Field | Type | Description |
| ----- | ------- | --------------------------------------- |
| x | integer | The x-coordinate of the animation frame |
| y | integer | The y-coordinate of the animation frame |
###### Profile Effect Source Structure
| Field | Type | Description |
| ----- | ------ | ----------------------------------------------- |
| src | string | The URL of the animation image (in APNG format) |
###### Profile Effect Animation Type
| Value | Name | Description |
| ----- | ------------ | ---------------------------------- |
| 0 | UNSPECIFIED | The animation type is unspecified |
| 1 | PERSISTENT | The animation type is persistent |
| 2 | INTERMITTENT | The animation type is intermittent |
###### Nameplate Collectible Item Structure
| Field | Type | Description |
| ------- | -------------------------------------------- | ------------------------------------------------------------ |
| type | integer | The [type of collectible](#collectible-product-type) |
| sku_id | snowflake | The SKU ID of the nameplate |
| palette | string | The nameplate's [color palette](#nameplate-color-palette) |
| asset | string | The [nameplate asset path](/reference#cdn-formatting) |
| assets | [item assets](#item-assets-structure) object | The URLs for the static and animated images of the nameplate |
| label | string | The nameplate accessibility description |
###### Nameplate Color Palette
| Value | Description |
| ---------- | ----------- |
| none | None |
| crimson | Crimson |
| berry | Berry |
| sky | Sky |
| teal | Teal |
| forest | Forest |
| bubble_gum | BubbleGum |
| violet | Violet |
| cobalt | Cobalt |
| clover | Clover |
| lemon | Lemon |
| white | White |
###### Profile Frame Collectible Item Structure
| Field | Type | Description |
| ------------------- | ------------------------------------------------------------------- | ---------------------------------------------------- |
| type | integer | The [type of collectible](#collectible-product-type) |
| sku_id | snowflake | The SKU ID of the profile frame |
| label | string | The profile frame accessibility description |
| layers | array[[profile frame layer](#profile-frame-layer-structure) object] | The profile frame layers |
| inner_width | integer | The inner width of the profile frame |
| overflow_top | integer | The top overflow of the profile frame |
| overflow_bottom | integer | The bottom overflow of the profile frame |
| overflow_horizontal | integer | The horizontal overflow of the profile frame |
###### Profile Frame Layer Structure
| Field | Type | Description |
| ----------- | --------- | ----------------------------------------------- |
| id | snowflake | The asset ID of the profile frame layer |
| type | integer | The type of layer |
| order | integer | The layer order |
| anchor | integer | The layer anchor |
| responsive? | boolean | Whether the layer is responsive (default false) |
###### Item Assets Structure
| Field | Type | Description |
| ------------------ | ------ | ------------------------------------------------------------------ |
| static_image_url | string | The URL for the static image of the collectible |
| animated_image_url | string | The URL for the animated image of the collectible (in APNG format) |
| video_url? | string | The URL for the video of the collectible |
### Collectible Category Object
###### Collectible Category Structure
| Field | Type | Description |
| ---------------------------- | ------------------------------------------------------------------- | ------------------------------------------------------------------------------------------ |
| sku_id | snowflake | The SKU ID of the collectible category |
| store_listing_id | snowflake | The store listing ID associated with the collectible category |
| banner_text_color? | string | The color of the banner text as a hexadecimal color string |
| catalog_banner_asset? | [banner asset](#banner-asset-structure) object | The catalog banner asset |
| catalog_banner_animated_url? | string | The URL of the animated catalog banner image |
| catalog_banner_rive_url? | string | The URL of the catalog banner Rive animation |
| featured_block_body? | string | The body text for the featured block |
| featured_block_url? | string | The URL of the featured block image |
| hero_banner_asset? | [banner asset](#banner-asset-structure) object | The hero banner asset |
| hero_banner_animated_url? | string | The URL of the animated hero banner image |
| hero_banner_display_config? | [asset config](#asset-config-structure) object | The display configuration for the hero banner |
| hero_block_title? | string | The title text for the hero block |
| hero_logo_display_config? | [asset config](#asset-config-structure) object | The display configuration for the hero logo |
| hero_logo_url? | string | The URL of the hero logo image |
| is_orbs_exclusive? | boolean | Whether all products in the category are Orbs-exclusive (default false) |
| hero_ranking | ?array[snowflake] | The popularity ranking of SKU IDs within the collectible category |
| hero_rive_url? | string | The URL of the [Rive](https://rive.app/docs/runtimes/advanced-topic/format) hero animation |
| logo_url | string | The URL of the logo image |
| mobile_banner_url? | string | The URL of the mobile banner image |
| mobile_bg_url? | string | The URL of the mobile background image |
| mobile_hero_block_title? | string | The title text for the mobile hero block |
| mobile_products_title? | string | The title text for the mobile products section |
| mobile_summary | string | The summary text for the mobile products section |
| name | string | The name of the collectible category |
| pdp_bg_url | string | The URL of the product display page background image |
| products | array[[collectible product](#collectible-product-structure) object] | The list of products in the collectible category |
| styles | [collectible styles](#collectible-style-structure) object | The colors to use in the client |
| summary | string | A description of the collectible category |
| unpublished_at | ?ISO8601 timestamp | The time at which the collectible category should be unpublished |
| wide_banner_asset? | [asset config](#asset-config-structure) object | The wide banner asset config |
| wide_banner_body? | string | The body text for the wide banner |
| wide_banner_title? | string | The title text for the wide banner |
###### Asset Config Structure
| Field | Type | Description |
| -------- | ------- | ---------------------------------------------- |
| animated | ?string | The URL of the animated image (in APNG format) |
| static | string | The URL of the static image |
###### Banner Asset Structure
| Field | Type | Description |
| ------------------- | -------- | ----------------------------------- |
| background_style | ?string | The CSS the web client should use |
| desktop_max_height? | ?integer | Max height of the banner on desktop |
| mobile_max_height? | ?integer | Max height of the banner on mobile |
| responsive | ?boolean | Whether the banner is responsive |
### Shop Block Object
###### Shop Block Type
| Value | Name | Description |
| ----- | -------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------- |
| 0 | [HERO](#hero-shop-block-structure) | A hero shop block |
| 1 | [FEATURED](#featured-shop-block-structure) | A featured shop block |
| 2 | [FEED](#feed-shop-block-structure) | A feed shop block |
| 3 | [WIDE_BANNER](#wide-banner-shop-block-structure) | A wide banner shop block |
| 4 | [SHELF](#shelf-shop-block-structure) | A shelf shop block |
| 5 | [COUNTDOWN_TIMER](#countdown-timer-shop-block-structure) | A countdown timer shop block |
| 6 | [IMMERSIVE_BANNER](#immersive-banner-shop-block-structure) | An immersive banner shop block |
| 7 | [REWARD_HERO](#reward-hero-shop-block-structure) | A reward hero shop block |
| 9 | [SOCIAL_LAYER_STOREFRONT_PROMOTIONAL_BANNER](#social-layer-storefront-promotional-banner-shop-block-structure) | A social layer storefront promotional banner shop block |
| 10 | [FRAMES_BANNER](#frames-banner-shop-block-structure) | A profile frames banner shop block |
| 11 | [FRAMES_PRODUCT_SHELF](#frames-product-shelf-shop-block-structure) | A profile frames product shelf shop block |
###### Hero Shop Block Structure
| Field | Type | Description |
| ------------------------- | ---------------------------------------------- | ------------------------------------------------------------------------------------------ |
| type | integer | The [shop block type](#shop-block-type) |
| category_sku_id | snowflake | The collectible category SKU ID |
| category_store_listing_id | snowflake | The collectible category store listing ID |
| banner_asset | [asset config](#asset-config-structure) object | The banner asset |
| banner_display_config | [banner asset](#banner-asset-structure) object | The display configuration |
| banner_text_color? | string | The hex color code for the banner text |
| hero_logo_url | string | The URL of the hero logo image |
| hero_rive_url? | string | The URL of the hero [Rive](https://rive.app/docs/runtimes/advanced-topic/format) animation |
| logo_display_config | [banner asset](#banner-asset-structure) object | The shop block logo display config |
| logo_url | string | The URL of the hero logo image |
| name | string | The name of the shop block |
| mobile_title? | string | The title to be displayed on mobile devices |
| mobile_summary? | string | The summary to be displayed on mobile devices |
| mobile_products_title? | string | The products title to be displayed on mobile devices |
| mobile_hero_url? | string | The URL of the mobile hero banner image |
| mobile_hero_animated_url? | string | The URL of the mobile animated hero banner image |
| ranked_sku_ids | array[snowflake] | The SKU IDs ranked by popularity in the collectible category |
| summary | string | A description of the collectible category |
| unpublished_at | ?ISO8601 timestamp | When the collectible category should be unpublished |
###### Featured Shop Block Structure
| Field | Type | Description |
| --------- | -------------------------------------------- | ------------------------------------------------- |
| subblocks | array[subblock](#subblock-structure) object] | The list of sub-blocks in the featured shop block |
| type | integer | The [shop block type](#shop-block-type) |
###### Subblock Structure
| Field | Type | Description |
| ------------------------- | ------------------ | -------------------------------------------------------------------------------------- |
| type | integer | The [subblock type](#subblock-type) |
| category_store_listing_id | snowflake | The [collectible category](#collectible-category-structure) store listing ID |
| asset_url | string | The URL of the shop block asset |
| banner_text_color | ?string | The hex color code of the banner text |
| banner_url | string | The URL of the banner image |
| body_text | ?string | The body text of the shop block |
| name | string | The name of the shop block |
| unpublished_at | ?ISO8601 timestamp | When the [collectible category](#collectible-category-structure) should be unpublished |
###### Subblock Type
| Value | Name | Description |
| ----- | -------- | ------------------- |
| 0 | CATEGORY | A category subblock |
###### Feed Shop Block Structure
| Field | Type | Description |
| -------------- | -------------------------------------------------- | --------------------------------------- |
| ranked_sku_ids | array[snowflake] | All SKU IDs ranked by popularity |
| sorted_sku_ids | [sorted SKU IDs](#sorted-sku-ids-structure) object | The sorted SKU IDs |
| type | integer | The [shop block type](#shop-block-type) |
###### Sorted SKU IDs Structure
| Field | Type | Description |
| ----------- | ---------------- | ------------------------------------ |
| popular | array[snowflake] | The SKU IDs sorted by popularity |
| recommended | array[snowflake] | The SKU IDs sorted by recommendation |
###### Wide Banner Shop Block Structure
| Field | Type | Description |
| --------------------------- | ---------------------------------------------- | ---------------------------------------------------------------------------- |
| type | integer | The [shop block type](#shop-block-type) |
| category_store_listing_id | snowflake | The [collectible category](#collectible-category-structure) store listing ID |
| banner_asset | [asset config](#asset-config-structure) object | The banner asset |
| logo_url | string | The URL of the wide banner logo image |
| title | string | The title of the wide banner |
| body | string | The body text of the wide banner |
| banner_text_color | ?string | The hex color code of the banner text |
| disable_cta | boolean | Whether to disable the CTA for the wide banner |
| cta_text | string | The CTA text for the wide banner |
| cta_route | string | The CTA route for the wide banner |
| is_dismissible | boolean | Whether the wide banner is dismissible |
| dismissible_content_version | integer | The version of the dismissible content |
| wide_banner_url | string | The URL of the wide banner image |
| wide_banner_animated_url? | string | The URL of the animated wide banner image |
###### Shelf Shop Block Structure
| Field | Type | Description |
| ---------------- | ---------------- | ----------------------------------------------------------------------------------------------- |
| type | integer | The [shop block type](#shop-block-type) |
| category_sku_id? | snowflake | The [collectible category](#collectible-category-structure) SKU ID |
| name | string | The name of the shop block |
| ranked_sku_ids | array[snowflake] | The SKU IDs ranked by popularity in the [collectible category](#collectible-category-structure) |
###### Countdown Timer Shop Block Structure
| Field | Type | Description |
| ---------- | ----------------- | --------------------------------------- |
| type | integer | The [shop block type](#shop-block-type) |
| title | string | The title of the countdown timer |
| body | string | The body text of the countdown timer |
| banner_url | string | The URL of the countdown timer banner |
| end_time | ISO8601 timestamp | The end time of the countdown timer |
| text_color | string | The hex color code of the text |
###### Immersive Banner Shop Block Structure
| Field | Type | Description |
| --------------- | ---------------------------------------------- | --------------------------------------- |
| type | integer | The [shop block type](#shop-block-type) |
| title | string | The title of the immersive banner |
| body | string | The body text of the immersive banner |
| help_center_url | string | The URL to the help center article |
| text_color | string | The hex color code of the text |
| end_time | ?ISO8601 timestamp | The end time of the immersive banner |
| banner_asset | [asset config](#asset-config-structure) object | The banner asset |
###### Reward Hero Shop Block Structure
| Field | Type | Description |
| ------------------------- | ---------------------------------------------- | ------------------------------------------------------------------------------------------ |
| type | integer | The [shop block type](#shop-block-type) |
| category_sku_id? | snowflake | The [collectible category](#collectible-category-structure) SKU ID |
| category_store_listing_id | snowflake | The [collectible category](#collectible-category-structure) store listing ID |
| name | string | The name of the shop block |
| summary | string | A description of the collectible category |
| banner_asset | [asset config](#asset-config-structure) object | The banner asset |
| logo_url | string | The URL of the hero logo image |
| title | string | The title of the reward hero shop block |
| banner_text_color? | string | The hex color code for the banner text |
| banner_display_config | [banner asset](#banner-asset-structure) object | The display configuration |
| hero_rive_url? | string | The URL of the hero [Rive](https://rive.app/docs/runtimes/advanced-topic/format) animation |
| logo_display_config | [banner asset](#banner-asset-structure) object | The shop block logo display config |
| mobile_title? | string | The title to be displayed on mobile devices |
| mobile_summary? | string | The summary to be displayed on mobile devices |
| mobile_products_title? | string | The products title to be displayed on mobile devices |
| hero_banner_url | string | The URL of the hero banner image |
| hero_banner_animated_url | string | The URL of the hero animated banner image |
| hero_logo_url | string | The URL of the hero logo image |
| mobile_hero_url? | string | The URL of the mobile hero banner image |
| mobile_hero_animated_url? | string | The URL of the mobile animated hero banner image |
| ranked_sku_ids | array[snowflake] | The SKU IDs ranked by popularity in the collectible category |
| unpublished_at | ?ISO8601 timestamp | When the [collectible category](#collectible-category-structure) should be unpublished |
| reward_sku_id | snowflake | The SKU ID of the reward collectible |
###### Social Layer Storefront Promotional Banner Shop Block Structure
| Field | Type | Description |
| --------------- | ----------------- | --------------------------------------- |
| type | integer | The [shop block type](#shop-block-type) |
| application_id | snowflake | The ID of the application |
| header_text | string | The header text |
| gradient_colors | array[string] | The gradient colors |
| gradient_angle | integer | The gradient angle |
| sku_ids | array[snowflake] | The SKU IDs shown in the banner |
| end_time | ISO8601 timestamp | When the banner ends |
| cta_type? | string | The CTA type (`storefront` or `nitro`) |
| logo_url? | string | The logo URL |
###### Frames Banner Shop Block Structure
| Field | Type | Description |
| ------------------------- | ------- | --------------------------------------- |
| type | integer | The [shop block type](#shop-block-type) |
| title | string | The banner title |
| body | string | The banner body |
| mobile_background_image? | string | The mobile background image URL |
| mobile_foreground_image? | string | The mobile foreground image URL |
| desktop_background_image? | string | The desktop background image URL |
###### Frames Product Shelf Shop Block Structure
| Field | Type | Description |
| ------------------------- | ---------------- | ---------------------------------------------------------------------------- |
| type | integer | The [shop block type](#shop-block-type) |
| title | string | The shelf title |
| category_sku_id | snowflake | The [collectible category](#collectible-category-structure) SKU ID |
| category_store_listing_id | snowflake | The [collectible category](#collectible-category-structure) store listing ID |
| ranked_sku_ids | array[snowflake] | The SKU IDs ranked by popularity in the collectible category |
| background_image? | string | The legacy background image URL |
| desktop_background_image? | string | The desktop background image URL |
| mobile_background_image? | string | The mobile background image URL |
| button_text? | string | The shelf button text |
### Collectibles Marketing Object
###### Collectibles Marketing Type
| Value | Name | Description |
| ----- | ------------------------------------------------------------ | ------------- |
| 0 | [COACHTIP](#coachtip-collectibles-marketing-structure) | A coachtip |
| 1 | [BADGE](#badge-collectibles-marketing-structure) | A badge |
| 2 | [BANNER](#banner-collectibles-marketing-structure) | A banner |
| 3 | [COACHMARK](#coachmark-collectibles-marketing-structure) | A coachmark |
| 4 | [TAB_TOOLTIP](#tab-tooltip-collectibles-marketing-structure) | A tab tooltip |
###### Coachtip Collectibles Marketing Structure
| Field | Type | Description |
| --------------------- | -------------------------------------------------------- | --------------------------------------------------------------- |
| type | integer | The [collectibles marketing type](#collectibles-marketing-type) |
| version | integer | The version of the coachtip |
| title | string | The title of the coachtip |
| body | string | The body text of the coachtip |
| avatar | string | The URL of the coachtip avatar |
| decorations | array[string] | The avatar decoration asset hashes |
| dismissible_content | integer | The ID of the dismissible content |
| ref_target_background | [target background](#target-background-structure) object | The target background configuration |
###### Target Background Structure
| Field | Type | Description |
| ----- | -------------------------------------------------------------------------------- | ----------------------------------------- |
| style | [target background information](#target-background-information-structure) object | The style configuration of the background |
| asset | [target background information](#target-background-information-structure) object | The asset configuration of the background |
###### Target Background Information Structure
| Field | Type | Description |
| ------- | -------------------------------------------------------------------- | ------------------------------- |
| resting | [target background state](#target-background-state-structure) object | The resting state configuration |
| hovered | [target background state](#target-background-state-structure) object | The hovered state configuration |
###### Target Background State Structure
| Field | Type | Description |
| ----- | ------- | ------------------------------- |
| light | ?string | The URL of the light mode image |
| dark | ?string | The URL of the dark mode image |
###### Badge Collectibles Marketing Structure
| Field | Type | Description |
| ---------------------- | -------------------------------------------------------- | --------------------------------------------------------------- |
| type | integer | The [collectibles marketing type](#collectibles-marketing-type) |
| version | integer | The version of the badge |
| dismissible_content | integer | The ID of the dismissible content |
| ref_target_background? | [target background](#target-background-structure) object | The target background configuration |
| badge_icon? | string | The badge icon [asset path](/reference#cdn-formatting) |
| badge_text? | string | The badge text |
| show_hover_gradient? | boolean | Whether to show a hover gradient (default false) |
###### Banner Collectibles Marketing Structure
| Field | Type | Description |
| ------------------ | ------- | --------------------------------------------------------------- |
| type | integer | The [collectibles marketing type](#collectibles-marketing-type) |
| version | integer | The version of the banner |
| title | string | The title of the banner |
| body | string | The body text of the banner |
| asset | string | The URL of the banner image |
| popout_asset | string | The URL of the banner popout image |
| revert_text_color? | boolean | Whether to revert the text color on the banner |
###### Coachmark Collectibles Marketing Structure
| Field | Type | Description |
| --------------------- | ------- | --------------------------------------------------------------- |
| type | integer | The [collectibles marketing type](#collectibles-marketing-type) |
| title | string | The title of the coachmark |
| body | string | The body text of the coachmark |
| asset_dark | string | The URL of the dark mode coachmark image |
| asset_light | string | The URL of the light mode coachmark image |
| version | integer | The version of the coachmark |
| ref_target_background | object | The target background configuration |
| badge_icon? | string | The badge icon [asset path](/reference#cdn-formatting) |
| badge_text? | string | The badge text |
| button_label? | string | The coachmark button label |
###### Tab Tooltip Collectibles Marketing Structure
| Field | Type | Description |
| ---------------------- | -------------------------------------------------------- | --------------------------------------------------------------- |
| type | integer | The [collectibles marketing type](#collectibles-marketing-type) |
| title | string | The title of the tooltip |
| body? | string | The body text of the tooltip |
| asset | string | The tooltip asset |
| dismissible_content | integer | The ID of the dismissible content |
| version | integer | The version of the tooltip |
| ref_target_background? | [target background](#target-background-structure) object | The target background configuration |
| badge_icon? | string | The badge icon [asset path](/reference#cdn-formatting) |
| badge_text? | string | The badge text |
| show_hover_gradient? | boolean | Whether to show a hover gradient (default false) |
## Endpoints
List Collectibles Categories
Returns the list of [collectible categories](#collectible-category-structure) objects available in the store.
###### Query String Params
| Field | Type | Description |
| ------------------------ | ------- | ---------------------------------------------------------------------------------------------- |
| country_code? | string | The user's [ISO 3166-1 alpha-2](https://en.wikipedia.org/wiki/ISO_3166-1_alpha-2) country code |
| include_bundles? | boolean | Whether to include bundles (default false) |
| include_dynamic_blocks? | boolean | Whether to include dynamic shop blocks (default false) |
| include_unpublished? ^1^ | boolean | Whether to include unpublished categories (default false) |
| no_cache? ^1^ | boolean | Whether to bypass the cache (default false) |
| payment_gateway? | integer | The [payment gateway](/resources/billing#payment-gateway) of the payment source |
| shop_home_config? | string | The [shop home configuration](#collectibles-shop-home-config) override |
| skip_num_categories? ^1^ | integer | The number of categories to skip |
| tab? | string | The [shop tab](#collectibles-shop-home-tab) to retrieve |
| variants_return_style? | integer | The [variant style](#variants-return-style) to return |
^1^ Only usable by Discord employees.
###### Variants Return Style
| Value | Name | Description |
| ----- | ------------------- | -------------------------------------------------- |
| 1 | INDIVIDUAL_PRODUCTS | Variants should be returned as individual products |
| 2 | VARIANTS_GROUP | Variants should be returned as a group |
List Collectibles Categories V2
Returns the collectible categories available in the store.
###### Query String Params
| Field | Type | Description |
| ------------------------ | ------- | ---------------------------------------------------------------------------------------------- |
| country_code? | string | The user's [ISO 3166-1 alpha-2](https://en.wikipedia.org/wiki/ISO_3166-1_alpha-2) country code |
| include_bundles? | boolean | Whether to include bundles (default false) |
| include_dynamic_blocks? | boolean | Whether to include dynamic shop blocks (default false) |
| include_unpublished? ^1^ | boolean | Whether to include unpublished categories (default false) |
| no_cache? ^1^ | boolean | Whether to bypass the cache (default false) |
| payment_gateway? | integer | The [payment gateway](/resources/billing#payment-gateway) of the payment source |
| shop_home_config? | string | The [shop home configuration](#collectibles-shop-home-config) override |
| skip_num_categories? ^1^ | integer | The number of categories to skip |
| tab? | string | The [shop tab](#collectibles-shop-home-tab) to retrieve |
| variants_return_style? | integer | The [variant style](#variants-return-style) to return |
^1^ Only usable by Discord employees.
###### Response Body
| Field | Type | Description |
| --------------- | ------------------------------------------------------------------------------------ | -------------------------------------- |
| categories | array[[collectible category](#collectible-category-structure) object] | The collectible categories |
| collections | array[[storefront collection](/resources/store#storefront-collection-object) object] | The storefront collections |
| user_discounts? | array[[collectible user discount](#collectible-user-discount-structure) object] | The discounts the user is eligible for |
###### Collectible User Discount Structure
| Field | Type | Description |
| ----------- | ------------------ | ------------------------- |
| amount | integer | How much the discount is |
| discount_id | snowflake | The discount ID |
| expires_at | ?ISO8601 timestamp | When the discount expires |
Get Collectibles Shop
Returns the list of [collectible categories](#collectible-category-structure) available in the store.
###### Query String Params
| Field | Type | Description |
| ------------------------ | ------- | ---------------------------------------------------------------------------------------------- |
| country_code? | string | The user's [ISO 3166-1 alpha-2](https://en.wikipedia.org/wiki/ISO_3166-1_alpha-2) country code |
| tab? | string | The [tab](#collectibles-shop-home-tab) to retrieve |
| shop_home_config? | string | The shop home configuration override |
| include_bundles? | boolean | Whether to include bundles (default false) |
| include_dynamic_blocks? | boolean | Whether to include dynamic blocks (default false) |
| include_unpublished? ^1^ | boolean | Whether to include unpublished categories (default false) |
| no_cache? ^1^ | boolean | Whether to bypass the cache (default false) |
| payment_gateway? | integer | The [payment gateway](/resources/billing#payment-gateway) of the payment source |
| skip_num_categories? ^1^ | integer | The number of categories to skip |
| variants_return_style? | integer | The [variant style](#variants-return-style) to return |
^1^ Only usable by Discord employees.
###### Collectibles Shop Home Tab
| Value | Description |
| ------------------ | -------------------------- |
| home | The home tab |
| catalog | The catalog tab |
| orbs | The orbs tab |
| avatar-decorations | The avatar decorations tab |
| profile-effects | The profile effects tab |
| nameplates | The nameplates tab |
| profile-frames | The profile frames tab |
| bundles | The bundles tab |
| layout | The layout tab |
| collection-index | The collection index tab |
| game-shops | The game shops tab |
###### Collectibles Shop Home Config
| Value | Description |
| ---------------------- | -------------------------------------------------- |
| default | The default shop home configuration |
| default_with_orb_shelf | The default shop home configuration with orb shelf |
| orb_tab | The orb tab shop home configuration |
| summer_sale_takeover | The summer sale takeover shop home configuration |
###### Response Body
| Field | Type | Description |
| --------------- | ------------------------------------------------------------------------------- | -------------------------------------- |
| categories | array[[collectible category](#collectible-category-structure) object] | The collectible categories |
| shop_blocks | array[[shop block](#shop-block-object) object] | The shop blocks |
| user_discounts? | array[[collectible user discount](#collectible-user-discount-structure) object] | The discounts the user is eligible for |
Search Collectibles
Returns the collectible SKUs that match the given query.
###### Query String Params
| Field | Type | Description |
| --------------- | ------------- | -------------------------------------------------------------------------- |
| item_types? | array[string] | The [item types](#shop-item-type) to search for |
| colors? | array[string] | The products to search for that have the [color](#shop-product-color) |
| themes? | array[string] | The products with the specified [theme](#shop-product-theme) to search for |
| orbs_eligible? | boolean | Whether you can purchase the products with orbs |
| offset? | integer | Number of products to skip before returning results |
| limit? | integer | Max amount of SKU IDs to return (max 100, default 20) |
| sort_type? | string | How should the results be [sorted](#shop-sort-type) |
| sort_direction? | string | The direction to sort the results in (`asc` or `desc`, default `desc`) |
| search? | string | The query to match (max 256 characters) |
###### Shop Item Type
| Value | Description |
| ----------------- | -------------------------------- |
| ALL | All collectible product types |
| AVATAR_DECORATION | An avatar decoration product |
| PROFILE_EFFECT | A profile effect product |
| NAMEPLATE | A nameplate product |
| PROFILE_FRAME | A profile frame product |
| BUNDLE | A bundle of collectible products |
###### Shop Product Theme
| Value | Description |
| ---------------------------------- | ----------------------------------------- |
| COLLECTIBLES_THEME_ANIME | Products with an anime theme |
| COLLECTIBLES_THEME_GAMING | Products with a gaming theme |
| COLLECTIBLES_THEME_CUTE_COZY | Products with a cute and cozy theme |
| COLLECTIBLES_THEME_FOOD_DRINKS | Products with a food and drinks theme |
| COLLECTIBLES_THEME_ANIMALS_PETS | Products with an animals and pets theme |
| COLLECTIBLES_THEME_MOVIES_TV_SHOWS | Products with a movies and TV shows theme |
| COLLECTIBLES_THEME_FANTASY | Products with a fantasy theme |
| COLLECTIBLES_THEME_DARK_MOODY | Products with a dark and moody theme |
| COLLECTIBLES_THEME_NATURE | Products with a nature theme |
| COLLECTIBLES_THEME_SCI_FI | Products with a sci-fi theme |
###### Shop Product Color
| Value | Description |
| ------------------------- | ------------ |
| COLLECTIBLES_COLOR_BLUE | Blue color |
| COLLECTIBLES_COLOR_GREEN | Green color |
| COLLECTIBLES_COLOR_PINK | Pink color |
| COLLECTIBLES_COLOR_RED | Red color |
| COLLECTIBLES_COLOR_YELLOW | Yellow color |
| COLLECTIBLES_COLOR_ORANGE | Orange color |
| COLLECTIBLES_COLOR_PURPLE | Purple color |
| COLLECTIBLES_COLOR_BROWN | Brown color |
| COLLECTIBLES_COLOR_BLACK | Black color |
| COLLECTIBLES_COLOR_WHITE | White color |
###### Shop Sort Type
| Value | Description |
| ------------ | ------------------- |
| relevance | Sort by relevance |
| price | Sort by price |
| alphabetical | Sort alphabetically |
| recency | Sort by recency |
| popularity | Sort by popularity |
###### Response Body
| Field | Type | Description |
| ---------- | ------------------------------------------ | ---------------------------- |
| pagination | [pagination](#pagination-structure) object | The pagination information |
| skus | array[snowflake] | The list of matching SKU IDs |
###### Pagination Structure
| Field | Type | Description |
| -------- | ------- | ------------------------------ |
| offset | integer | The offset of the current page |
| limit | integer | The limit of items per page |
| total | integer | The total number of items |
| has_more | boolean | Whether there are more pages |
Get Collectibles Product
Returns the [collectible product](#collectible-product-structure) for a given SKU ID.
###### Query String Params
| Field | Type | Description |
| ---------------------- | ------- | ---------------------------------------------------------------------------------------------- |
| country_code? | string | The user's [ISO 3166-1 alpha-2](https://en.wikipedia.org/wiki/ISO_3166-1_alpha-2) country code |
| include_bundles? | boolean | Whether to include bundles (default false) |
| variants_return_style? | integer | The [variant style](#variants-return-style) to return |
List User Purchased Collectibles
Returns the list of [collectible products](#collectible-product-structure) owned by the current user.
###### Query String Params
| Field | Type | Description |
| ---------------------- | ------- | ----------------------------------------------------- |
| variants_return_style? | integer | The [variant style](#variants-return-style) to return |
Get Valid Collectibles Gift Recipient
Returns a [gift eligibility](#gift-eligibility-structure) object for the given user and collectible SKU ID.
###### Query String Params
| Field | Type | Description |
| ------------ | --------- | ------------------------------------------------ |
| recipient_id | snowflake | The ID of the user to check for gift eligibility |
| sku_id | snowflake | The SKU ID of the collectible to gift |
###### Gift Eligibility Structure
| Field | Type | Description |
| ----- | ------- | ----------------------------------------------------- |
| valid | boolean | Whether the recipient is eligible to receive the gift |
Get Valid Collectibles Gift Recipients Batch
Returns a mapping of SKU IDs to [gift eligibility](#gift-eligibility-structure) object for the given user and collectible SKU IDs.
###### Query String Params
| Field | Type | Description |
| ------------ | ---------------- | ------------------------------------------------ |
| recipient_id | snowflake | The ID of the user to check for gift eligibility |
| sku_ids | array[snowflake] | The SKU IDs of the collectibles to gift |
Claim Premium Collectibles Product
Claims a collectible SKU provided for free to premium users. Returns a list of [collectible products](#collectible-product-structure) objects owned by the current user if the user hasn't claimed the product yet, otherwise returns a 204 empty response.
###### JSON Params
| Field | Type | Description |
| ------ | --------- | ------------------------------------------------------ |
| sku_id | snowflake | The SKU ID of the premium collectible product to claim |
Claim Reward Category Product
Claims a reward product from a collectible category. Returns a list of [collectible products](#collectible-product-structure) objects owned by the current user.
###### JSON Params
| Field | Type | Description |
| ----------- | --------- | --------------------------------------------- |
| category_id | snowflake | The SKU ID of the reward collectible category |
Get Collectibles Marketing
Returns collectibles marketing information for the current user.
###### Query String Params
| Field | Type | Description |
| -------- | ------- | ----------------------------------------------------------------------------------------- |
| platform | integer | The [platform](#collectibles-marketing-platform-type) to get marketing information for |
| release? | integer | The [release type](#collectibles-marketing-release-type) to get marketing information for |
###### Collectibles Marketing Platform Type
| Value | Name | Description |
| ----- | ------- | ----------- |
| 0 | DESKTOP | Desktop |
| 1 | MOBILE | Mobile |
###### Collectibles Marketing Release Type
| Value | Name | Description |
| ----- | -------- | ------------------ |
| 0 | PROD | Production release |
| 1 | BETA ^1^ | Beta release |
^1^ Only usable by Discord employees.
###### Response Body
| Field | Type | Description |
| ---------- | ----------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------- |
| marketings | map[integer, [collectibles marketing](#collectibles-marketing-object) object] | The mapping of [collectibles marketing surface](#collectibles-marketing-surface-type) to [collectibles marketing](#collectibles-marketing-object) object |
###### Collectibles Marketing Surface Type
| Value | Name | Description |
| ----- | --------------------- | --------------------- |
| 0 | DESKTOP_SHOP_BUTTON | Desktop shop button |
| 1 | MOBILE_SHOP_BUTTON | Mobile shop button |
| 2 | EDIT_PROFILE_SETTINGS | Edit profile settings |
Get Collectibles Shop Tab Layout
Returns the layout ID for the specified collectibles shop tab.
###### Response Body
| Field | Type | Description |
| --------- | ------ | ------------------------------------------------------------------- |
| layout_id | string | The layout-system layout ID for the requested collectibles shop tab |
---
# Subscriptions
Link: https://docs.discord.food/resources/subscription
Subscriptions in Discord represent an user making recurring payments for at least one SKU over an ongoing period. Successful payments grant the user access to entitlements associated with the SKU.
### Subscription Object
###### Subscription Structure
| Field | Type | Description |
| -------------------------------- | ---------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------- |
| id | snowflake | The ID of the subscription |
| type | integer | The [type](#subscription-type) of subscription |
| payment_gateway | ?integer | The [payment gateway](/resources/billing#payment-gateway) used to bill the subscription |
| currency | string | The lower-cased [ISO 4217](https://en.wikipedia.org/wiki/ISO_4217) currency code |
| items | array[[subscription item](#subscription-item-structure) object] | The items in the subscription |
| payment_gateway_plan_id | ?string | The payment gateway's plan ID for the subscription |
| payment_gateway_subscription_id? | ?string | The payment gateway's subscription ID for the subscription |
| current_period_start | ISO8601 timestamp | When the current billing period started |
| current_period_end | ISO8601 timestamp | When the current billing period ends |
| streak_started_at? | ISO8601 timestamp | When the current subscription streak started |
| status | integer | The [status](#subscription-status) of subscription |
| renewal_mutations? | [subscription renewal mutations](#subscription-renewal-mutations-structure) object | The mutations to the subscription that will occur after renewal |
| trial_id? | snowflake | The ID of the trial the subscription is from |
| payment_source_id | ?snowflake | The ID of the payment source the subscription is paid with |
| created_at | ISO8601 timestamp | When the subscription was created |
| canceled_at? | ISO8601 timestamp | When the subscription was canceled |
| country_code | ?string | The [ISO 3166-1 alpha-2](https://en.wikipedia.org/wiki/ISO_3166-1_alpha-2) country code the subscription is billed in |
| trial_ends_at? | ISO8601 timestamp | When the trial ends |
| metadata? | [subscription metadata](#subscription-metadata-structure) object | Extra metadata about the subscription |
| latest_invoice? | [subscription invoice](/resources/payment#invoice-object) object | The latest invoice for the subscription |
| use_storekit_resubscribe | boolean | Whether the subscription should be managed through StoreKit |
| price | ?integer | The price of the subscription (only available for certain third-party subscriptions) |
| entitlements? | array[[entitlement](/resources/entitlement#entitlement-object) object] | The entitlements granted by the subscription |
###### Partial Subscription Structure
| Field | Type | Description |
| -------------------------------- | --------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------- |
| id | snowflake | The ID of the subscription |
| type | integer | The [type](#subscription-type) of subscription |
| payment_gateway | ?integer | The [payment gateway](/resources/billing#payment-gateway) used to bill the subscription |
| currency | string | The lower-cased [ISO 4217](https://en.wikipedia.org/wiki/ISO_4217) currency code the subscription is billed in |
| items | array[[subscription item](#subscription-item-structure) object] | The items in the subscription |
| payment_gateway_plan_id | ?string | The payment gateway's plan ID for the subscription |
| payment_gateway_subscription_id? | ?string | The payment gateway's subscription ID for the subscription |
| current_period_start | ISO8601 timestamp | When the current billing period started |
| current_period_end | ISO8601 timestamp | When the current billing period ends |
| streak_started_at? | ISO8601 timestamp | When the current subscription streak started |
###### Subscription Type
| Value | Name | Description |
| ----- | ----------- | ------------------------------------------------------ |
| 1 | PREMIUM | Subscription is a Discord premium (Nitro) subscription |
| 2 | GUILD | Subscription is a guild role subscription |
| 3 | APPLICATION | Subscription is an application subscription |
###### Subscription Status
| Value | Name | Description |
| ----- | ------------- | ------------------------------------------ |
| 0 | UNPAID | Subscription is unpaid |
| 1 | ACTIVE | Subscription is active |
| 2 | PAST_DUE | Subscription is past due |
| 3 | CANCELED | Subscription is canceled |
| 4 | ENDED | Subscription has ended |
| 6 | ACCOUNT_HOLD | Subscription is on account hold |
| 7 | BILLING_RETRY | Subscription failed to bill and will retry |
| 8 | PAUSED | Subscription is paused |
| 9 | PAUSE_PENDING | Subscription is pending pause |
###### Subscription Item Structure
| Field | Type | Description |
| -------- | --------- | --------------------------------------------------- |
| id | snowflake | The ID of the subscription item |
| quantity | integer | How many of the items have been/are being purchased |
| plan_id | snowflake | The ID of the plan the item is for |
###### Subscription Renewal Mutations Structure
| Field | Type | Description |
| ------------------------ | --------------------------------------------------------------- | ------------------------------------------------------ |
| payment_gateway_plan_id? | ?string | The payment gateway's new plan ID for the subscription |
| items? | array[[subscription item](#subscription-item-structure) object] | The new items of the subscription |
###### Subscription Metadata Structure
| Field | Type | Description |
| ---------------------------------- | ----------------- | ------------------------------------------------------------------------------------------------------------------------------------------------- |
| is_egs? | boolean | Whether the subscription was received from an Epic Games store trial |
| is_holiday_promotion_2021? | boolean | Whether the subscription was received from 2021 Holiday promotion |
| ended_at? | string | When the subscription ended |
| guild_id? **(deprecated)** | snowflake | The ID of the guild the subscription's entitlements apply to |
| application_subscription_guild_id? | snowflake | The ID of the guild the subscription's entitlements apply to |
| grace_period_expires_date? | ISO8601 timestamp | When the grace period expires |
| apple_grace_period_expires_date? | ISO8601 timestamp | When the grace period expires (only applicable for [`APPLE`](/resources/billing#payment-gateway) payment gateway) |
| google_grace_period_expires_date? | ISO8601 timestamp | When the grace period expires (only applicable for [`GOOGLE`](/resources/billing#payment-gateway) payment gateway) |
| google_original_expires_date? | string | When the subscription expires, disregarding the grace period (only applicable for [`GOOGLE`](/resources/billing#payment-gateway) payment gateway) |
| user_trial_offer_id? | snowflake | The ID of the user trial offer on the subscription |
| user_discount_offer_id? | snowflake | The ID of the user discount offer on the subscription |
| active_discount_id? | snowflake | The ID of the discount on the subscription |
| active_discount_expires_at? | ISO8601 timestamp | When the subscription discount expires |
### Subscription Trial Object
###### Subscription Trial Structure
| Field | Type | Description |
| -------------- | --------- | ------------------------------------------------------------------------ |
| id | snowflake | The ID of the trial |
| interval | integer | The [interval](/resources/store#subscription-interval) of the trial plan |
| interval_count | integer | The number of intervals included in the trial |
| sku_id | snowflake | The ID of the SKU the trial is for |
###### Partial Subscription Trial Structure
| Field | Type | Description |
| -------------- | ------- | ------------------------------------------------------------------------ |
| interval | integer | The [interval](/resources/store#subscription-interval) of the trial plan |
| interval_count | integer | The number of intervals included in the trial |
###### Example Subscription Trial
```json
{
"id": "1073698058383917056",
"interval": 3,
"interval_count": 14,
"sku_id": "521847234246082599"
}
```
### Premium Guild Subscription Slot Object
Represents a premium guild subscription (boost) slot.
###### Premium Guild Subscription Slot Structure
| Field | Type | Description |
| -------------------------- | ---------------------------------------------------------------------------------------- | --------------------------------------------------------------- |
| id | snowflake | The ID of the premium guild subscription slot |
| subscription_id | snowflake | The ID of the subscription |
| canceled | boolean | Whether the premium guild subscription slot was canceled |
| cooldown_ends_at | ?string | When the cooldown for this premium guild subscription slot ends |
| premium_guild_subscription | ?[premium guild subscription](/resources/guild#premium-guild-subscription-object) object | The premium guild subscription, if the slot was already applied |
###### Example Premium Guild Subscription Slot
```json
{
"id": "1315132642890350601",
"subscription_id": "1315132642890350600",
"canceled": false,
"cooldown_ends_at": null,
"premium_guild_subscription": {
"id": "1315132642890350602",
"user_id": "673658900435697665",
"guild_id": "1081635484209520802",
"ended": false,
"pause_ends_at": null,
"user": {
"id": "673658900435697665",
"username": "android",
"global_name": "Android",
"avatar": "08f104f8d5406c4d46916794fe2efeb7",
"avatar_decoration_data": {
"asset": "a_8552f9857793aed0cf816f370e2df3be",
"sku_id": "1232071712695386162",
"expires_at": null
},
"collectibles": null,
"discriminator": "0",
"public_flags": 4194560,
"primary_guild": null
}
}
}
```
## Endpoints
List Subscriptions
Returns a list of [subscription](#subscription-object) objects.
###### Query String Params
| Field | Type | Description |
| ------------------------ | ------- | ------------------------------------------------------------------------------------------- |
| include_inactive? | boolean | Whether to include inactive subscriptions (default false) |
| limit? | integer | Max number of subscriptions to return (1-20, default unlimited) |
| exclude_unpaid_statuses? | boolean | Whether to exclude subscriptions of [`UNPAID`](#subscription-status) status (default false) |
| subscription_type? | integer | Return only subscriptions with the specified [type](#subscription-type) |
| sync_level? | integer | The [sync level](#user-lazy-perk-sync-level) (default `NONE`) |
###### User Lazy Perk Sync Level
| Value | Name | Description |
| ----- | --------------------- | ---------------------- |
| 0 | NONE | Do not resync anything |
| 1 | ADD_PERKS_IF_DETECTED | Add perks if detected |
| 2 | FULL_RESYNC | Fully resync perks |
Get Subscription
Returns a [subscription](#subscription-object) object for the given subscription ID.
Create Subscription
Creates a new subscription. Returns a [subscription](#subscription-object) object on success. Fires a [User Subscriptions Update](/gateway/gateway-events#user-subscriptions-update) and [Payment Update](/gateway/gateway-events#payment-update) Gateway event.
###### JSON Params
| Field | Type | Description |
| --------------------------- | ----------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------ |
| items ^1^ | array[partial [subscription item](#subscription-item-structure) object] | The items in the subscription |
| payment_source_id? | snowflake | The ID of the payment source to pay with |
| payment_source_token? | ?string | The token used to authorize with the payment source |
| return_url? ^2^ | ?string | TThe URL to redirect to after payment is complete (max 2048 characters) |
| currency? | string | The lower-cased [ISO 4217](https://en.wikipedia.org/wiki/ISO_4217) currency code |
| trial_id? | ?snowflake | The ID of the trial to apply to the subscription |
| expected_invoice_price? ^3^ | ?[expected price structure](#expected-price-structure) object | The expected price for the invoice in the smallest currency unit |
| expected_renewal_price? ^3^ | ?[expected price structure](#expected-price-structure) object | The expected renewal price in the smallest currency unit |
| purchase_token ^4^ | string | The purchase token of the payment client (max 1024 characters) |
| gateway_checkout_context? | ?[gateway checkout context](/resources/billing#gateway-checkout-context-structure) object | The context for the gateway checkout, if applicable |
| code? | string | Unknown |
| metadata? | [subscription metadata request](#subscription-metadata-request-structure) object | Extra metadata about the subscription |
| load_id? | string | A client-generated UUID used to identify the current checkout session, used for purchase deduplication |
^1^ Only the `plan_id` field is required.
^2^ If required, this URL is typically set to the [Create Billing Popup Bridge Redirect](/resources/billing#create-billing-popup-bridge-redirect) endpoint with a `response_type` of `success`, which redirects the user back to the Discord client for handling.
^3^ If the actual amount charged does not match these expected values, the purchase will fail.
^4^ See the section on [payment clients](/resources/payment#payment-clients) for more information.
###### Expected Price Structure
| Field | Type | Description |
| -------- | ------- | -------------------------------------------------------------------------------- |
| currency | string | The lower-cased [ISO 4217](https://en.wikipedia.org/wiki/ISO_4217) currency code |
| amount | integer | The price amount in the smallest currency unit |
###### Subscription Metadata Request Structure
| Field | Type | Description |
| --------- | --------- | ----------------------------------------------------------------- |
| guild_id? | snowflake | The ID of the guild the subscription's entitlements will apply to |
Modify Subscription
Modifies a subscription. Returns the updated [subscription](#subscription-object) object on success. Fires a [User Subscriptions Update](/gateway/gateway-events#user-subscriptions-update) Gateway event.
###### Query String Params
| Field | Type | Description |
| --------------- | ------ | ----------------------------------------------------------- |
| location? | string | The analytics location the request initiated from |
| location_stack? | string | The stack of analytics locations the request initiated from |
###### JSON Params
| Field | Type | Description |
| --------------------------- | ----------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------ |
| items? ^1^ | array[partial [subscription item](#subscription-item-structure) object] | The items in the subscription |
| payment_source_id? | snowflake | The ID of the payment source to pay with |
| payment_source_token? | string | The token used to authorize with the payment source |
| return_url? ^2^ | ?string | TThe URL to redirect to after payment is complete (max 2048 characters) |
| currency? | string | The lower-cased [ISO 4217](https://en.wikipedia.org/wiki/ISO_4217) currency code |
| status? | integer | The [status](#subscription-status) of subscription |
| pause_duration? | integer | The duration to pause the subscription for, in days |
| expected_invoice_price? ^3^ | ?[expected price structure](#expected-price-structure) object | The expected price for the invoice in the smallest currency unit |
| expected_renewal_price? ^3^ | ?[expected price structure](#expected-price-structure) object | The expected renewal price in the smallest currency unit |
| purchase_token? ^4^ | string | The purchase token of the payment client (max 1024 characters) |
| gateway_checkout_context? | ?[gateway checkout context](/resources/billing#gateway-checkout-context-structure) object | The context for the gateway checkout, if applicable |
| load_id? | string | A client-generated UUID used to identify the current checkout session, used for purchase deduplication |
^1^ Only the `plan_id` field is required.
^2^ If required, this URL is typically set to the [Create Billing Popup Bridge Redirect](/resources/billing#create-billing-popup-bridge-redirect) endpoint with a `response_type` of `success`, which redirects the user back to the Discord client for handling.
^3^ If the actual amount charged does not match these expected values, the purchase will fail.
^4^ See the section on [payment clients](/resources/payment#payment-clients) for more information.
Delete Subscription
Deletes a subscription. Returns a 204 empty response on success. Fires a [User Subscriptions Update](/gateway/gateway-events#user-subscriptions-update) Gateway event.
###### Query String Params
| Field | Type | Description |
| --------------- | ------ | ----------------------------------------------------------- |
| location? | string | The analytics location the request initiated from |
| location_stack? | string | The stack of analytics locations the request initiated from |
Create Subscription Preview
Previews a new subscription. Returns an [invoice](/resources/payment#invoice-object) object on success.
###### JSON Params
| Field | Type | Description |
| ------------------- | ----------------------------------------------------------------------- | -------------------------------------------------------------------------------- |
| items ^1^ | array[partial [subscription item](#subscription-item-structure) object] | The items in the subscription |
| currency? | string | The lower-cased [ISO 4217](https://en.wikipedia.org/wiki/ISO_4217) currency code |
| payment_source_id? | ?snowflake | The ID of the payment source to pay with |
| trial_id? | ?snowflake | The ID of the trial to apply to the subscription |
| apply_entitlements? | boolean | Whether to apply entitlements (credits) to the previewed subscription |
| renewal? | boolean | Whether the previewed subscription should be a renewal |
| code? | string | Unknown |
| metadata? | map[string, any] | Extra metadata about the subscription |
^1^ Only the `plan_id` field is required.
Get Subscription Preview
Returns an [invoice](/resources/payment#invoice-object) object representing the next upcoming invoice for the subscription.
Modify Subscription Preview
Previews an invoice for the given subscription ID. Returns an [invoice](/resources/payment#invoice-object) on success.
###### JSON Params
| Field | Type | Description |
| ----------------------- | ----------------------------------------------------------------------- | -------------------------------------------------------------------------------- |
| items? ^1^ | array[partial [subscription item](#subscription-item-structure) object] | The items the previewed invoice should have |
| payment_source_id? | snowflake | The ID of the payment source the previewed invoice should be paid with |
| currency? | string | The lower-cased [ISO 4217](https://en.wikipedia.org/wiki/ISO_4217) currency code |
| apply_entitlements? | boolean | Whether to apply entitlements (credits) to the previewed invoice |
| renewal? | boolean | Whether the previewed invoice should be a renewal |
| user_discount_offer_id? | snowflake | The ID of the discount offer to apply to the previewed invoice |
^1^ Only the `plan_id` field is required.
List Subscription Invoices
Returns a list of [invoice](/resources/payment#invoice-object) objects for the given subscription ID.
Pay Subscription Invoice
Pays the subscription invoice. Returns a [subscription](#subscription-object) object on success.
###### JSON Params
| Field | Type | Description |
| --------------------- | ---------- | -------------------------------------------------------------------------------------------- |
| payment_source_id | ?snowflake | The ID of the payment source the invoice should be paid with |
| payment_source_token? | string | The token used to authorize with the payment source |
| currency? | string | The lower-cased [ISO 4217](https://en.wikipedia.org/wiki/ISO_4217) currency code to pay with |
| return_url? | string | The URL to return to after the payment is complete |
Claim Subscription Promotion Reward
Claims a promotion reward from the given subscription.
###### Response Body
| Field | Type | Description |
| ------------ | --------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------- |
| eligible | boolean | Whether the subscription is eligible for the reward |
| reason | string | The [reason whether the subscription is eligible](#subscription-promotion-reward-eligibility-reason) |
| entitlement? | [entitlement](/resources/entitlement#entitlement-object) object | The granted reward entitlement |
###### Subscription Promotion Reward Eligibility Reason
| Value | Description |
| -------------------------------- | -------------------------------------------- |
| user_eligible_for_reward | User is eligible for reward |
| user_not_eligible_for_experiment | User is not eligible for relevant experiment |
Get Premium Guild Subscription Cooldown
Returns the cooldown for premium guild subscription slot changes.
###### Response Body
| Field | Type | Description |
| --------- | ----------------- | ----------------------------------------------------------------------------- |
| ends_at | ISO8601 timestamp | When the cooldown resets |
| limit | integer | The maximum number of changes that can be made before the cooldown is applied |
| remaining | integer | The number of changes remaining before the cooldown is applied |
List Applied Premium Guild Subscriptions
Returns a list of [premium guild subscription](/resources/guild#premium-guild-subscription-object) objects applied by the current user.
###### Query String Params
| Field | Type | Description |
| ------- | ------- | ------------------------------------------------------------------------- |
| paused? | boolean | Whether to return only paused premium guild subscriptions (default false) |
List Premium Guild Subscription Slots
Returns a list of [premium guild subscription slot](#premium-guild-subscription-slot-object) objects for the current user.
Cancel Premium Guild Subscription Slot
Cancels the given premium guild subscription slot. Returns the canceled [premium guild subscription slot](#premium-guild-subscription-slot-object) object. Fires [User Premium Guild Subscription Slot Update](/gateway/gateway-events#user-premium-guild-subscription-slot-update) and optionally [Guild Applied Boosts Update](/gateway/gateway-events#guild-applied-boosts-update) Gateway events.
Uncancel Premium Guild Subscription Slot
Uncancels the given premium guild subscription slot. Returns the uncanceled [premium guild subscription slot](#premium-guild-subscription-slot-object) object. Fires a [User Premium Guild Subscription Slot Update](/gateway/gateway-events#user-premium-guild-subscription-slot-update) Gateway event.
---
# Game Invites
Link: https://docs.discord.food/resources/game-invite
Game invites allow users to invite their friends to play from their console.
### Game Invite Object
###### Game Invite Structure
| Field | Type | Description |
| ----------------- | ----------------- | -------------------------------------------------------------------------------------------------------- |
| invite_id | snowflake | The ID of the game invite |
| created_at | ISO8601 timestamp | When the game invite was created |
| ttl | integer | Duration in seconds after which the game invite expires |
| inviter_id | snowflake | The ID of the user who created the game invite |
| recipient_id | snowflake | The ID of the user who received the game invite |
| platform_type | string | The [type of the platform](/resources/connected-accounts#connection-type) the game invite was created on |
| launch_parameters | string | The [parameters for launching the game](#game-launch-parameters), generally encoded as a JSON string |
| installed? | boolean | Whether the game is installed (default false) |
| joinable? | boolean | Whether the game is joinable (default false) |
| fallback_url | ?string | The URL for installing the game |
| application_asset | string | The URL of the game icon |
| application_name | string | The name of the game |
###### Example Game Invite
```json
{
"invite_id": "1387169389857607774",
"created_at": "2025-06-24T20:35:54.903000+00:00",
"ttl": 900,
"inviter_id": "1001086404203389018",
"recipient_id": "852892297661906993",
"platform_type": "xbox",
"launch_parameters": "{\"titleId\":1750797354,\"inviteToken\":\"3bFFu5mTMiitj8cp8n1rbio1F850A8eE\"}",
"fallback_url": null,
"application_asset": "https://images-ext-1.discordapp.net/external/GyQicPLz_zQO15bOMtiGTtC4Kud7JjQbs1Ecuz7RrtU/https/cdn.discordapp.com/app-icons/356875570916753438/166fbad351ecdd02d11a3b464748f66b.png",
"application_name": "Minecraft"
}
```
###### Game Launch Parameters
| Field | Type | Description |
| ------------ | -------- | ---------------------------- |
| titleId? | ?integer | The ID of the title |
| inviteToken? | ?string | The token of the game invite |
## Endpoints
Create Game Invite
Creates a game invite. Fires a [Game Invite Create](/gateway/gateway-events#game-invite-create) Gateway event.
This endpoint is meant to be used by the Xbox integration only. Because of this, it is only usable with an OAuth2 access token, and is locked to the Xbox application ID (`622174530214821906`).
###### JSON Params
| Field | Type | Description |
| ----------------- | --------- | -------------------------------------------------------------------------------------------------------------------------- |
| recipient_id | snowflake | The ID of the recipient to send game invite to |
| launch_parameters | string | The [parameters for launching the game](#game-launch-parameters), generally encoded as a JSON string (max 8192 characters) |
| application_asset | string | The URL of the game icon |
| application_name | string | The name of the game (2-128 characters) |
| fallback_url? | ?string | The URL for installing the game |
| ttl? | ?integer | Duration in seconds after which the game invite expires (300-86400, default 900) |
###### Response Body
| Field | Type | Description |
| --------- | --------- | --------------------------------- |
| invite_id | snowflake | The ID of the created game invite |
Delete Game Invite
Deletes a game invite. Returns a 204 empty response on success. Fires a [Game Invite Delete](/gateway/gateway-events#game-invite-delete) Gateway event.
Delete Game Invites
Deletes all game invites for the current user. Returns a 204 empty response on success. Fires a [Game Invite Delete Many](/gateway/gateway-events#game-invite-delete-many) Gateway event.
---
# Entitlements
Link: https://docs.discord.food/resources/entitlement
Entitlements in Discord represent a user or guild's access to a specific SKU. Entitlements can represent purchases, subscriptions, or gifts, and are used to power many different features in Discord.
### Entitlement Object
###### Entitlement Structure
| Field | Type | Description |
| ------------------- | ----------------------------------------------------------------------------- | ----------------------------------------------------------------------------------- |
| id | snowflake | The ID of the entitlement |
| type | integer | The [type of entitlement](#entitlement-type) |
| sku_id | snowflake | The ID of the SKU granted |
| application_id | snowflake | The ID of the application that owns the SKU |
| user_id | snowflake | The ID of the user that is granted access to the SKU |
| user? | partial [user](/resources/user#user-object) object | The user that is granted access to the SKU |
| guild_id? | snowflake | The ID of the guild that is granted access to the SKU |
| parent_id? | snowflake | The ID of the parent entitlement |
| deleted | boolean | Whether the entitlement is deleted |
| consumed? | boolean | For consumable items, whether the entitlement has been consumed |
| branches? | array[snowflake] | The IDs of the application branches granted |
| starts_at | ?ISO8601 timestamp | When the entitlement validity period starts |
| ends_at | ?ISO8601 timestamp | When the entitlement validity period ends |
| promotion_id | ?snowflake | The ID of the promotion the entitlement is from |
| subscription_id? | snowflake | The ID of the subscription the entitlement is from |
| gift_code_flags | integer | The [flags for the gift code](#gift-code-flags) the entitlement is attached to |
| gift_code_batch_id? | snowflake | The ID of the batch the gift code attached to the entitlement is from |
| gifter_user_id? | snowflake | The ID of the user that gifted the entitlement |
| gift_style? | integer | The [style of the gift](#gift-style) attached to the entitlement |
| fulfillment_status? | integer | The [tenant fulfillment status](#entitlement-fulfillment-status) of the entitlement |
| fulfilled_at? | ISO8601 timestamp | When the entitlement was fulfilled |
| source_type? | integer | The [special source type](#entitlement-source-type) of the entitlement |
| tenant_metadata? | [tenant metadata](#tenant-metadata-structure) object | Tenant metadata for the entitlement |
| sku? | [SKU](/resources/store#sku-object) object | The SKU granted |
| subscription_plan? | partial [subscription plan](/resources/store#subscription-plan-object) object | The subscription plan granted |
###### Tenant Metadata Structure
| Field | Type | Description |
| ------------- | ------------------------------------------------------------------ | ----------------------------------------------------------- |
| quest_rewards | [quest rewards metadata](#quest-rewards-metadata-structure) object | Metadata about the quest rewards granted by the entitlement |
###### Quest Rewards Metadata Structure
| Field | Type | Description |
| ------------ | ---------------------------------------------------------------------- | ------------------------------------------------------------------------- |
| tag | integer | The [reward type](/resources/quests#quest-reward-type) of the entitlement |
| reward_code? | [quest reward code](/resources/quests#quest-reward-code-object) object | The reward granted by the entitlement |
###### Entitlement Type
| Value | Name | Description |
| ----- | --------------------------- | ------------------------------------------------------------------- |
| 1 | PURCHASE | Entitlement was purchased by a user |
| 2 | PREMIUM_SUBSCRIPTION | Entitlement is for a premium (Nitro) subscription |
| 3 | DEVELOPER_GIFT | Entitlement was gifted by a developer |
| 4 | TEST_MODE_PURCHASE | Entitlement was purchased by a developer in application test mode |
| 5 | FREE_PURCHASE | Entitlement was granted when the SKU was free |
| 6 | USER_GIFT | Entitlement was gifted by another user |
| 7 | PREMIUM_PURCHASE | Entitlement was claimed for free via a premium subscription |
| 8 | APPLICATION_SUBSCRIPTION | Entitlement is for an application subscription |
| 9 | FREE_STAFF_PURCHASE | Entitlement was claimed for free by a Discord employee |
| 10 | QUEST_REWARD | Entitlement was granted as a reward for completing a quest |
| 11 | FRACTIONAL_REDEMPTION | Entitlement is for a fractional premium subscription |
| 12 | VIRTUAL_CURRENCY_REDEMPTION | Entitlement was purchased with virtual currency (Orbs) |
| 13 | GUILD_POWERUP | Entitlement was purchased with premium guild subscriptions (boosts) |
###### Entitlement Fulfillment Status
| Value | Name | Description |
| ----- | --------------------------- | --------------------------------------------------- |
| 0 | UNKNOWN | Unknown fulfillment status |
| 1 | FULFILLMENT_NOT_NEEDED | Fulfillment is not needed for this entitlement |
| 2 | FULFILLMENT_NEEDED | Fulfillment is needed for this entitlement |
| 3 | FULFILLED | Entitlement has been fulfilled |
| 4 | FULFILLMENT_FAILED | Fulfillment of the entitlement has failed |
| 5 | UNFULFILLMENT_NEEDED | Unfulfillment is needed for this entitlement |
| 6 | UNFULFILLED | Entitlement has been unfulfilled |
| 7 | UNFULFILLMENT_FAILED | Unfulfillment of the entitlement has failed |
| 8 | UNFULFILLMENT_NEEDED_MANUAL | Manual unfulfillment is needed for this entitlement |
###### Entitlement Source Type
| Value | Name | Description |
| ----- | --------------------------- | ---------------------------------------------------------- |
| 1 | QUEST_REWARD | Entitlement was granted as a reward for completing a quest |
| 2 | DEVELOPER_GIFT | Entitlement was gifted by a developer |
| 3 | INVOICE | Entitlement was granted via an invoice |
| 4 | REVERSE_TRIAL | Entitlement was granted as part of a reverse trial |
| 5 | USER_GIFT | Entitlement was gifted by another user |
| 6 | GUILD_POWERUP | Entitlement was granted via the guild powerups feature |
| 7 | HOLIDAY_PROMOTION | Entitlement was granted as part of a first-party promotion |
| 8 | FRACTIONAL_PREMIUM_GIVEBACK | Unknown |
| 9 | SUBSCRIPTION | Entitlement is for a subscription holder |
| 11 | SUBSCRIPTION_MEMBER | Entitlement is for a subscription member |
###### Example Entitlement
```json
{
"id": "1014639973498097686",
"sku_id": "557494559257526272",
"application_id": "557494559257526272",
"user_id": "852892297661906993",
"promotion_id": null,
"type": 3,
"deleted": false,
"gift_code_flags": 0,
"starts_at": null,
"ends_at": null,
"branches": ["557494559257526272"],
"gift_code_batch_id": "916443614618464296"
}
```
### Gift Code Object
A gift from one user to another, which can be redeemed for an entitlement.
###### Gift Code Structure
| Field | Type | Description |
| --------------------- | ------------------------------------------------------------------------------ | ------------------------------------------------------------ |
| code | string | The gift code |
| sku_id | snowflake | The ID of the SKU that the gift code grants |
| application_id | snowflake | The ID of the application that owns the SKU |
| flags? | integer | The [flags for the gift code](#gift-code-flags) |
| uses | integer | The number of times the gift code has been used |
| max_uses | integer | The maximum number of times the gift code can be used |
| redeemed | boolean | Whether the gift code has been redeemed by the current user |
| expires_at | ?ISO8601 timestamp | When the gift code expires |
| batch_id? | snowflake | The ID of the batch the gift code is from |
| entitlement_branches? | array[snowflake] | The IDs of the application branches granted by the gift code |
| gift_style? | ?integer | The [style of the gift code](#gift-style) |
| user? | partial [user](/resources/user#user-object) object | The user that created the gift code |
| store_listing? | [store listing](/resources/store#store-listing-object) object | The store listing for the SKU the gift code grants |
| subscription_plan_id? | snowflake | The ID of the subscription plan the gift code grants |
| subscription_plan? | [subscription plan](/resources/store#subscription-plan-object) object | The subscription plan the gift code grants |
| subscription_trial? | [subscription trial](/resources/subscription#subscription-trial-object) object | The subscription trial the gift code is from |
| promotion? | promotion object | The promotion the gift code is from |
###### Gift Code Flags
| Value | Name | Description |
| -------- | -------------------------------- | -------------------------------------------------------------------- |
| 1 \<\< 0 | PAYMENT_SOURCE_REQUIRED | Gift requires a payment source to redeem |
| 1 \<\< 1 | EXISTING_SUBSCRIPTION_DISALLOWED | Gift cannot be redeemed by users with existing premium subscriptions |
| 1 \<\< 2 | NOT_SELF_REDEEMABLE | Gift cannot be redeemed by the gifter |
| 1 \<\< 3 | PROMOTION | Gift is from a promotion |
###### Gift Style
| Value | Name | Description |
| ----- | --------------------- | ------------------------------------- |
| 1 | SNOWGLOBE | Snowglobe style gift code |
| 2 | BOX | Box style gift code |
| 3 | CUP | Cup style gift code |
| 4 | STANDARD_BOX | Standard box style gift code |
| 5 | CAKE | Cake style gift code |
| 6 | CHEST | Chest style gift code |
| 7 | COFFEE | Coffee style gift code |
| 8 | SEASONAL_STANDARD_BOX | Seasonal standard box style gift code |
| 9 | SEASONAL_CAKE | Seasonal cake style gift code |
| 10 | SEASONAL_CHEST | Seasonal chest style gift code |
| 11 | SEASONAL_COFFEE | Seasonal coffee style gift code |
| 12 | NITROWEEN_STANDARD | Nitroween standard style gift code |
###### Example Gift Code
```json
{
"code": "2CG6SV9QtRxerJTgCYNDnU7M",
"sku_id": "521847234246082599",
"application_id": "521842831262875670",
"uses": 1,
"max_uses": 1,
"expires_at": null,
"redeemed": false,
"batch_id": "1215710455985610833",
"store_listing": {
"id": "521848044908576803",
"summary": " ",
"sku": {
"id": "521847234246082599",
"type": 5,
"product_line": 1,
"dependent_sku_id": null,
"application_id": "521842831262875670",
"manifest_labels": null,
"access_type": 1,
"name": "Nitro",
"features": [],
"release_date": null,
"premium": false,
"slug": "nitro",
"flags": 68,
"show_age_gate": false
},
"thumbnail": {
"id": "971526227435323423",
"size": 227396,
"mime_type": "image/png",
"width": 834,
"height": 474
},
"benefits": []
},
"subscription_plan_id": "642251038925127690"
}
```
### Gift Code Batch Object
A batch of gift codes created together.
###### Gift Code Batch Structure
| Field | Type | Description |
| ---------------------- | ----------------- | --------------------------------------------- |
| id | snowflake | The ID of the gift code batch |
| sku_id | snowflake | The ID of the SKU for the gift code batch |
| amount | integer | The number of gift codes in the batch |
| description? | string | The description for the gift code batch |
| entitlement_branches? | array[snowflake] | The IDs of the application branches granted |
| entitlement_starts_at? | ISO8601 timestamp | When the entitlements' validity period starts |
| entitlement_ends_at? | ISO8601 timestamp | When the entitlements' validity period ends |
###### Example Gift Code Batch
```json
{
"id": "916443614618464296",
"sku_id": "557494559257526272",
"amount": 10,
"description": "Holiday Giveaway",
"entitlement_branches": ["557494559257526272"]
}
```
## Endpoints
List User Entitlements
Returns a list of [entitlement](#entitlement-object) objects granted to the current user, both active and expired.
###### Query String Params
| Field | Type | Description |
| ----------------- | ------- | ------------------------------------------------------------------ |
| with_sku? | boolean | Whether to include SKU objects in the response (default false) |
| with_application? | boolean | Whether to include application objects in the SKUs (default false) |
| exclude_ended? | boolean | Whether ended entitlements should be omitted (default false) |
| entitlement_type? | integer | The [type of entitlement](#entitlement-type) to filter by |
List User Giftable Entitlements
Returns a list of [entitlement](#entitlement-object) objects that the current user can gift.
###### Query String Params
| Field | Type | Description |
| ------------- | ------ | ---------------------------------------------------------------------------------------------- |
| country_code? | string | The user's [ISO 3166-1 alpha-2](https://en.wikipedia.org/wiki/ISO_3166-1_alpha-2) country code |
List Guild Entitlements
Returns a list of [entitlement](#entitlement-object) objects granted to the given guild, both active and expired.
###### Query String Params
| Field | Type | Description |
| ----------------- | ------- | ------------------------------------------------------------------ |
| with_sku? | boolean | Whether to include SKU objects in the response (default false) |
| with_application? | boolean | Whether to include application objects in the SKUs (default false) |
| exclude_ended? | boolean | Whether ended entitlements should be omitted (default false) |
| exclude_deleted? | boolean | Whether deleted entitlements should be omitted (default true) |
| entitlement_type? | integer | The [type of entitlement](#entitlement-type) to filter by |
List Application Entitlements
Returns a list of [entitlement](#entitlement-object) objects for the given application, both active and expired.
###### Query String Params
| Field | Type | Description |
| ---------------- | ---------------- | ------------------------------------------------------------- |
| user_id? | snowflake | The ID of the user to look up entitlements for |
| sku_ids? | array[snowflake] | The IDs of the SKUs to look up entitlements for |
| guild_id? | snowflake | The ID of the guild to look up entitlements for |
| exclude_ended? | boolean | Whether ended entitlements should be omitted (default false) |
| exclude_deleted? | boolean | Whether deleted entitlements should be omitted (default true) |
| before? | snowflake | Get entitlements before this entitlement ID |
| after? | snowflake | Get entitlements after this entitlement ID |
| limit? | integer | Max number of entitlements to return (1-100, default 100) |
List User Application Entitlements
Returns a list of [entitlement](#entitlement-object) objects granted to the current user for the given application.
###### Query String Params
| Field | Type | Description |
| ---------------- | ---------------- | -------------------------------------------------------------- |
| sku_ids? | array[snowflake] | The IDs of the SKUs to look up entitlements for |
| exclude_consumed | boolean | Whether consumed entitlements should be omitted (default true) |
Get Application Entitlement
Returns an [entitlement](#entitlement-object) object for the given application and entitlement ID.
Create Application Entitlement
Creates a test entitlement to a given subscription SKU for a given guild or user. Returns an [entitlement](#entitlement-object) object on success. Fires an [Entitlement Create](/gateway/gateway-events#entitlement-create) Gateway event.
This endpoint is not usable by user accounts.
###### JSON Params
| Field | Type | Description |
| ---------- | --------- | --------------------------------------------------------------- |
| sku_id | snowflake | The ID of the SKU to grant the entitlement to |
| owner_id | snowflake | The ID of the guild or user to grant the entitlement to |
| owner_type | integer | The [type of owner](#entitlement-owner-type) of the entitlement |
###### Entitlement Owner Type
| Value | Name | Description |
| ----- | ----- | -------------------------- |
| 1 | GUILD | Entitlement is for a guild |
| 2 | USER | Entitlement is for a user |
Consume Application Entitlement
For one-time purchase consumable SKUs, marks a given entitlement for the user as consumed. Returns a 204 empty response on success. Fires an [Entitlement Update](/gateway/gateway-events#entitlement-update) Gateway event.
Delete Application Entitlement
Deletes a currently-active test entitlement. Returns a 204 empty response on success. Fires an [Entitlement Delete](/gateway/gateway-events#entitlement-delete) Gateway event.
Get Gift Code
Returns a [gift code](#gift-code-object) object for the given code.
###### Query String Params
| Field | Type | Description |
| ----------------------- | ------- | ------------------------------------------------------------------------------- |
| with_application? | boolean | Whether to include the application object in the SKU (default false) |
| with_subscription_plan? | boolean | Whether to include the subscription plan object in the response (default false) |
Redeem Gift Code
Redeems a gift code for the current user. Returns an [entitlement](#entitlement-object) object on success. Fires an [Entitlement Create](/gateway/gateway-events#entitlement-create) and [Gift Code Update](/gateway/gateway-events#gift-code-update) Gateway event.
###### JSON Params
| Field | Type | Description |
| ------------------------- | -------------------------------------------------------------------------------------- | ---------------------------------------------------------------- |
| payment_source_id? | ?string | The ID of the payment source to use for the gift code redemption |
| channel_id? | ?snowflake | The ID of the channel the gift code is being redeemed in |
| gateway_checkout_context? | ?[gateway checkout context](/resources/billing#gateway-checkout-context-object) object | The context for the gateway checkout, if applicable |
List User Gift Codes
Returns a list of [gift code](#gift-code-object) objects that the current user has created.
###### Query String Params
| Field | Type | Description |
| --------------------- | ---------------- | -------------------------------------------- |
| sku_ids? | array[snowflake] | The IDs of the SKUs to filter by |
| subscription_plan_id? | snowflake | The ID of the subscription plan to filter by |
Create User Gift Code
Creates a gift code. Requires an eligible giftable entitlement. Returns a [gift code](#gift-code-object) object on success. Fires a [Gift Code Create](/gateway/gateway-events#gift-code-create) Gateway event.
###### JSON Params
| Field | Type | Description |
| --------------------- | --------- | --------------------------------------------------------- |
| sku_id | snowflake | The ID of the SKU to create a gift code for |
| subscription_plan_id? | snowflake | The ID of the subscription plan to create a gift code for |
| gift_style? | integer | The [style of the gift](#gift-style) created |
Revoke User Gift Code
Revokes a gift code created by the current user. Returns a 204 empty response on success.
List Application Gift Code Batches
Returns a list of [gift code batch](#gift-code-batch-object) objects for the given application. User must be the owner of the application or member of the owning team.
Create Application Gift Code Batch
Creates a batch of gift codes. Returns a [gift code batch](#gift-code-batch-object) object on success. User must be the owner of the application or developer of the owning team.
###### JSON Params
| Field | Type | Description |
| ---------------------- | ----------------- | ------------------------------------------------------------- |
| sku_id | snowflake | The ID of the SKU to create gift codes for |
| amount | integer | The number of gift codes to create (1-2500) |
| description | string | The description for the gift code batch |
| entitlement_branches? | array[snowflake] | The IDs of the application branches granted by the gift codes |
| entitlement_starts_at? | ISO8601 timestamp | When the entitlements' validity period starts |
| entitlement_ends_at? | ISO8601 timestamp | When the entitlements' validity period ends |
Get Application Gift Code Batch
Returns a CSV file containing all gift codes in the given batch. User must be the owner of the application or member of the owning team.
---
# Integrations
Link: https://docs.discord.food/resources/integration
Integrations represent a connection between a service and a guild. This may include third-party services such as Twitch or YouTube, Discord-housed integrations such as bots, or internal integrations such as role subscriptions.
### Integration Object
###### Integration Structure
| Field | Type | Description |
| --------------------------------- | ------------------------------------------------------------------------------------------------------------------------ | ----------------------------------------------------------------------------------- |
| id ^1^ | snowflake | The ID of the integration |
| name | string | The name of the integration |
| type | string | The [type of integration](#integration-type) |
| enabled | boolean | Whether this integration is enabled |
| account | [integration account](#integration-account-structure) object | Integration account information |
| syncing? ^2^ | boolean | Whether this integration is syncing |
| role_id? ^2^ | ?snowflake | Role ID that this integration uses for subscribers |
| enable_emoticons? ^2^ | boolean | Whether emoticons should be synced for this integration (Twitch only) |
| expire_behavior? ^2^ | integer | The [behavior of expiring subscribers](#integration-expire-behavior) |
| expire_grace_period? ^2^ | integer | The grace period before expiring subscribers (one of 1, 3, 7, 14, 30, in days) |
| synced_at? ^2^ | ISO8601 timestamp | When this integration was last synced |
| subscriber_count? ^2^ | integer | How many subscribers this integration has |
| revoked? ^2^ | boolean | Whether this integration has been revoked |
| application? ^3^ | [integration application](#integration-application-structure) object | The integrated OAuth2 application |
| scopes? ^3^ | array[string] | The [scopes](/topics/oauth2#oauth2-scopes) the application has been authorized with |
| role_connections_metadata ^3^ ^4^ | array[[application role connection metadata](/resources/application#application-role-connection-metadata-object) object] | The metadata that the application has set for role connections |
| user? ^5^ | partial [user](/resources/user#user-object) object | The user that added this integration |
^1^ This field may also be the literal string "twitch-partners" to represent the Twitch Partners integration.
^2^ Only provided for Twitch and YouTube integrations.
^3^ Only provided for Discord application integrations.
^4^ Only included when fetched from [List Guild Integrations](#list-guild-integrations) with `include_role_connections_metadata` set to `true`.
^5^ Only included for integrations when fetched through the [List Guild Integrations](#list-guild-integrations) endpoint. Some older or internally-created integrations may not have an attached user.
###### Integration Type
| Value | Name |
| ------------------ | -------------------------------------- |
| twitch | Twitch integration |
| youtube | YouTube integration |
| discord | Discord application integration |
| guild_subscription | Internal role subscription integration |
###### Integration Expire Behavior
| Value | Name | Description |
| ----- | ----------- | ------------------------------------------------------ |
| 0 | REMOVE_ROLE | Remove the subscriber role from the user on expiration |
| 1 | KICK | Remove the user from the guild on expiration |
###### Integration Account Structure
| Field | Type | Description |
| ----- | ------ | ----------------------- |
| id | string | The ID of the account |
| name | string | The name of the account |
### Integration Application Object
###### Integration Application Structure
| Field | Type | Description |
| -------------------------------------- | ----------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| id | snowflake | The ID of the application |
| name | string | The name of the application |
| description | string | The description of the application |
| icon | ?string | The application's [icon hash](/reference#cdn-formatting) |
| cover_image? | string | The application's default rich presence invite [cover image hash](/reference#cdn-formatting) |
| splash? | string | The application's [splash hash](/reference#cdn-formatting) |
| type | ?integer | The [type of the application](/resources/application#application-type), if any |
| primary_sku_id? | snowflake | The ID of the application's primary SKU (game, application subscription, etc.) |
| bot? | partial [user](/resources/user#user-object) object | The bot attached to this application |
| deeplink_uri? | ?string | The URL used for deep linking during [OAuth2 authorization](/topics/oauth2) on mobile devices |
| third_party_skus? | array[[application SKU](/resources/game#application-sku-object) object] | The third party SKUs of the application's game |
| role_connections_verification_url? ^1^ | ?string | The role connection verification entry point of the integration; when configured, this will render the application as a verification method in guild role verification configuration |
| connection_entrypoint_url? | string | The URL which users will be directed to when connecting their account in the application to their Discord account |
| is_verified | boolean | Whether the application is verified |
| is_discoverable | boolean | Whether the application is discoverable in the application directory |
| is_monetized | boolean | Whether the application has monetization enabled |
| parent_id? | snowflake | The ID of the parent application |
^1^ Only present when fetched from the [List Guild Integrations](#list-guild-integrations) endpoint with `include_role_connections_metadata` set to `true`.
### Integration Guild Object
###### Integration Guild Structure
| Field | Type | Description |
| ----- | --------- | -------------------------------------------------- |
| id | snowflake | The ID of the guild |
| name | string | The name of the guild (2-100 characters) |
| icon | ?string | The guild's [icon hash](/reference#cdn-formatting) |
### GIF Object
###### GIF Structure
| Field | Type | Description |
| ---------------------- | ------- | ------------------------------------------------ |
| id | string | The ID of the GIF |
| title **(deprecated)** | string | The title of the GIF |
| url | string | The provider source URL of the GIF |
| src | string | The media URL of the GIF in the requested format |
| gif_src | string | The media URL of the GIF in GIF format |
| preview | string | A preview image of the GIF |
| width | integer | Width of image |
| height | integer | Height of image |
###### GIF Media Format
| Value | Description |
| --------- | ---------------------------------------- |
| mp4 | MP4 video |
| tinymp4 | MP4 video in a smaller size |
| nanomp4 | MP4 video in a very small size |
| loopedmp4 | MP4 video that loops (same as `mp4`) |
| webm | WebM video |
| tinywebm | WebM video in a smaller size |
| nanowebm | WebM video in a very small size |
| gif | GIF image |
| mediumgif | GIF image in a medium size |
| tinygif | GIF image in a smaller size |
| nanogif | GIF image in a very small size |
| webp | Animated WebP image |
| tinywebp | Animated WebP image in a smaller size |
| nanowebp | Animated WebP image in a very small size |
###### Example GIF
```json
{
"id": "12409989992265318124",
"title": "",
"url": "https://tenor.com/view/tasha-steelz-gif-25509948",
"src": "https://media.tenor.com/rDkkJaMgfuwAAAP4/tasha-steelz.webm",
"gif_src": "https://media.tenor.com/rDkkJaMgfuwAAAAC/tasha-steelz.gif",
"width": 150,
"height": 84,
"preview": "https://media.tenor.com/rDkkJaMgfuwAAAAD/tasha-steelz.png"
}
```
## Endpoints
List Guild Integrations
Returns a list of [integration](#integration-object) objects for the guild. Requires the `MANAGE_GUILD` permission.
This endpoint returns a maximum of 50 integrations. If a guild has more integrations, they cannot be accessed.
###### Query String Parameters
| Field | Type | Description |
| ---------------------------------- | ------- | ------------------------------------------------------------------------------------------------- |
| has_commands? | boolean | Whether to only include Discord application integrations with registered commands (default false) |
| include_role_connections_metadata? | boolean | Whether to include integration role connection metadata (default false) |
Create Guild Integration
Enables an integration for the guild. Requires the `MANAGE_GUILD` permission. Returns a 204 empty response on success. Fires [Guild Integrations Update](/gateway/gateway-events#guild-integrations-update) and [Integration Create](/gateway/gateway-events#integration-create) Gateway events.
###### JSON Params
| Field | Type | Description |
| ----- | ------ | -------------------------------------------------------------------------------------------------- |
| type | string | The [type of integration](#integration-type) to enable (only `twitch` and `youtube` are supported) |
| id | string | The ID of the integration account to enable |
Sync Guild Integration
Syncs an integration for the guild. Requires the `MANAGE_GUILD` permission. Returns a 204 empty response on success. Fires [Guild Integrations Update](/gateway/gateway-events#guild-integrations-update) and [Integration Update](/gateway/gateway-events#integration-update) Gateway events.
Modify Guild Integration
Modifies the behavior and settings of the integration in the guild. Requires the `MANAGE_GUILD` permission. Returns a 204 empty response on success. Fires [Guild Integrations Update](#integration-object) and [Integration Update](#integration-object) Gateway events.
###### JSON Params
| Field | Type | Description |
| -------------------- | ------- | ------------------------------------------------------------------------------ |
| expire_behavior? | integer | The [behavior of expiring subscribers](#integration-expire-behavior) |
| expire_grace_period? | integer | The grace period before expiring subscribers (one of 1, 3, 7, 14, 30, in days) |
| enable_emoticons? | boolean | Whether emoticons should be synced for this integration (Twitch only) |
Delete Guild Integration
Removes the given integration ID from the guild. Deletes any associated webhooks and kicks the associated bot (if there is one). Requires the `MANAGE_GUILD` permission. Returns a 204 empty response on success. Fires [Guild Integrations Update](/gateway/gateway-events#guild-integrations-update), [Integration Delete](/gateway/gateway-events#integration-delete), and optionally [Guild Member Remove](/gateway/gateway-events#guild-member-remove) and [Webhooks Update](/gateway/gateway-events#webhooks-update) Gateway events.
Migrate Guild Command Scope
Migrates all Discord application integrations in the guild to the [`applications.commands` OAuth2 scope](/topics/oauth2#oauth2-scopes). Requires the `MANAGE_GUILD` permission. Fires a [Guild Integrations Update](/gateway/gateway-events#guild-integrations-update) and multiple [Integration Update](/gateway/gateway-events#integration-update) Gateway events.
###### Response Body
| Field | Type | Description |
| --------------------------------- | ---------------- | ------------------------------------------------------------------------------ |
| integration_ids_with_app_commands | array[snowflake] | The IDs of migrated integrations that now have application commands registered |
Get Guild Integration Application IDs
Returns a mapping of guild IDs to lists of application IDs attached to the integrations in the current user's guilds.
###### Example Response
```json
{
"81384788765712384": [
"157858575924985856",
"157889000391180288",
"157873248346832897",
"157947794294833152",
"173805066229252096"
],
"1046920999469330512": []
}
```
List Channel Integrations
Returns a list of [integration](#integration-object) objects for the private channel.
This endpoint returns a maximum of 50 integrations. If a channel has more integrations, they cannot be accessed.
Delete Channel Integration
Removes the given integration ID from the channel. Returns a 204 empty response on success. Fires an [Integration Delete](#integration-object) Gateway event.
Join Integration Guild
Joins the user to the given integration ID's guild. Returns a 204 empty response on success. Fires a [Guild Create](/gateway/gateway-events#guild-create) Gateway event.
This endpoint is only usable with [integrations found on the user's connections](/resources/connected-accounts#connection-object).
List Trending GIF Search Terms
Returns a list of the top trending search terms.
###### Query String Parameters
| Field | Type | Description |
| ---------- | ------- | -------------------------------------------------------------- |
| limit? ^1^ | integer | The maximum number of search terms to return (1-50, default 5) |
| locale? | string | The locale to use in search results (default `en-US`) |
^1^ The limit is only a suggestion; the API may return fewer GIFs.
List Suggested GIF Search Terms
Returns a list of recommended search terms based on the provided query.
###### Query String Parameters
| Field | Type | Description |
| ---------- | ------- | --------------------------------------------------------------- |
| q | string | The search query to use |
| limit? ^1^ | integer | The maximum number of search terms to return (1-50, default 20) |
| locale? | string | The locale to use in search results (default `en-US`) |
^1^ The limit is only a suggestion; the API may return fewer GIFs.
Search GIFs
Returns a list of [GIF](#gif-structure) objects based on the provided query.
###### Query String Parameters
| Field | Type | Description |
| ---------------- | ------- | ----------------------------------------------------------- |
| q | string | The search query to use |
| limit? ^1^ | integer | The maximum number of GIFs to return (20-500) (default 100) |
| media_format ^2^ | string | The [media format](#gif-media-format) to use |
| locale? | string | The locale to use in search results (default `en-US`) |
^1^ The limit is only a suggestion; the API may return fewer GIFs.
^2^ Invalid values default to `mp4`.
List Trending GIF Categories
Returns trending GIF categories and their associated preview GIFs.
###### Query String Parameters
| Field | Type | Description |
| ------------ | ------ | ----------------------------------------------------- |
| media_format | string | The [media format](#gif-media-format) to use |
| locale? | string | The locale to use in search results (default `en-US`) |
###### Response Body
| Field | Type | Description |
| ---------- | ----------------------------------------------------- | -------------------------------------- |
| categories | array[[GIF category](#gif-category-structure) object] | The trending GIF categories |
| gifs | array[[GIF](#gif-structure) object] | A trending GIF to use as a placeholder |
###### GIF Category Structure
| Field | Type | Description |
| ----- | ------ | ------------------------------ |
| name | string | The name of the category |
| src | string | The media URL of a preview GIF |
###### Example Response
```json
{
"categories": [
{
"name": "whatever",
"src": "https://media.tenor.com/97c0UK_cAHMAAAAd/whatever-sassy.gif"
}
],
"gifs": [
{
"id": "16750982996130936929",
"title": "",
"url": "https://tenor.com/view/peace-out-peace-sign-peace-ice-age-eddie-gif-16750982996130936929",
"src": "https://media.tenor.com/6HdySNL-OGEAAAAC/peace-out-peace-sign.gif",
"gif_src": "https://media.tenor.com/6HdySNL-OGEAAAAC/peace-out-peace-sign.gif",
"width": 498,
"height": 498,
"preview": "https://media.tenor.com/6HdySNL-OGEAAAAD/peace-out-peace-sign.png"
}
]
}
```
List Trending GIFs
Returns a list of [GIF](#gif-structure) objects that are currently trending.
###### Query String Parameters
| Field | Type | Description |
| ------------ | ------- | ----------------------------------------------------- |
| limit? ^1^ | integer | The maximum number of GIFs to return (20-500) |
| media_format | string | The [media format](#gif-media-format) to use |
| locale? | string | The locale to use in search results (default `en-US`) |
^1^ The limit is only a suggestion; the API may return fewer GIFs.
Track Selected GIF
Tracks the selection of a GIF by the user. Returns a 204 empty response on success.
###### JSON Params
| Field | Type | Description |
| ----- | ------ | ------------------------------------- |
| id | string | The ID of the selected GIF |
| q | string | The search query used to find the GIF |
---
# Games
Link: https://docs.discord.food/resources/game
The games APIs further extend applications resources to power advanced game detection and rich presence features.
### Detectable Application Object
###### Detectable Application Structure
| Field | Type | Description |
| -------------------------- | ---------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| id | snowflake | The ID of the application |
| name | string | The name of the application |
| icon_hash? | ?string | The application's [icon hash](/reference#cdn-formatting) |
| cover_image_hash? | ?string | The application's default rich presence invite [cover image hash](/reference#cdn-formatting) |
| aliases | array[string] | Other names the application's game is associated with |
| executables | array[[application executable](#application-executable-object) object] | The unique executables of the application's game |
| themes | array[string] | The themes of the application's game |
| hook | boolean | Whether the Discord client is allowed to hook into the application's game directly |
| overlay | boolean | Whether the application's game supports the [Discord overlay](https://support.discord.com/hc/en-us/articles/217659737-Game-Overlay-101) (default false) |
| overlay_methods | ?integer | The [methods of overlaying](/resources/application#overlay-method-flags) that the application's game supports |
| overlay_warn | boolean | Whether the [Discord overlay](https://support.discord.com/hc/en-us/articles/217659737-Game-Overlay-101) is known to be problematic with this application's game (default false) |
| overlay_compatibility_hook | boolean | Whether to use the compatibility hook for the overlay (default false) |
| linked_applications? | array[[linked application](#linked-application-structure) object] | The other applications linked to this application |
###### Linked Application Structure
| Field | Type | Description |
| ----- | --------- | ---------------------------------------------------------- |
| id | snowflake | The ID of the application |
| type | integer | The [type of linked application](#linked-application-type) |
###### Linked Application Type
| Value | Name | Description |
| ----- | -------- | ------------------------------------ |
| 1 | LINKED | Application is linked |
| 2 | OFFICIAL | Application is official |
| 3 | NVIDIA | Application is on NVIDIA GeForce NOW |
###### Example Detectable Application
```json
{
"aliases": ["PUBG: BATTLEGROUNDS", "PUBG"],
"executables": [
{
"is_launcher": false,
"name": "win64/tslgame_be.exe",
"os": "win32"
},
{
"is_launcher": false,
"name": "win64/tslgame.exe",
"os": "win32"
},
{
"is_launcher": false,
"name": "tslgame.exe",
"os": "win32"
},
{
"is_launcher": false,
"name": "win64/tslgame_uc.exe",
"os": "win32"
},
{
"is_launcher": false,
"name": "tslgame_be.exe",
"os": "win32"
}
],
"hook": true,
"id": "356873622985506820",
"name": "PLAYERUNKNOWN'S BATTLEGROUNDS",
"overlay": true,
"overlay_compatibility_hook": true,
"overlay_methods": null,
"overlay_warn": false,
"themes": ["Action", "Warfare"]
}
```
### Application Executable Object
###### Application Executable Structure
| Field | Type | Description |
| ----------- | ------- | ------------------------------------------------------------------------------------------------ |
| os | string | The [operating system](/resources/presence#operating-system-type) the executable can be found on |
| name | string | The name of the executable |
| is_launcher | boolean | Whether the executable is for a game launcher |
###### Example Application Executable
```json
{
"os": "win32",
"name": "spaceship looter/spaceship_looter.exe",
"is_launcher": false
}
```
### Application SKU Object
###### Application SKU Structure
| Field | Type | Description |
| ----------- | ------- | ------------------------------------------------ |
| id | ?string | The ID of the game |
| sku | ?string | The SKU of the game |
| distributor | string | The [distributor](#distributor-type) of the game |
##### Distributor Type
| Value | Description |
| -------------- | ------------------- |
| discord | Discord Store |
| steam | Steam |
| twitch | Twitch |
| uplay | Ubisoft Connect |
| battlenet | Battle.net |
| origin | Origin |
| gog | GOG.com |
| epic | Epic Games Store |
| microsoft | Microsoft Store |
| igdb | IGDB.com |
| glyph | Glyph.net |
| google_play | Google Play Store |
| nvidia_gdn_app | NVIDIA Cloud Gaming |
| gop | Gameopedia |
| roblox | Roblox Game |
| gdco | GameDiscover.co |
| xbox | Xbox Store |
| xbox_title | Xbox Title |
| xbox_game_pass | Xbox Game Pass |
| playstation | PlayStation Store |
| opencritic | OpenCritic |
###### Example Application SKU
```json
{
"id": "445220",
"sku": "445220",
"distributor": "steam"
}
```
### Game Object
This structure is a superset of the [detectable application](#detectable-application-object) object above with the following additional fields:
| Field | Type | Description |
| ----------------------- | ---------------------------------------------------------------- | ------------------------------------------------------------------ |
| supplemental_game_data? | [game data](#game-data-structure) object | The supplemental game data |
| genres? | array[integer] | The [genres](/resources/store#sku-genre) of the game |
| platforms? | array[integer] | The [platforms that the game is available on](#game-platform-type) |
| websites? | array[[game website](#game-website-structure) object] | The websites relating to the game |
| companies | array[[company](#company-structure) object] | The companies working on the game |
| screenshot_hashes? | array[string] | The game's [screenshot hashes](/reference#cdn-formatting) |
| screenshot_urls? | array[string] | The URLs to the game screenshots |
| trailers? | array[[store asset](/resources/store#store-asset-object) object] | The game trailers |
| l30_rank? | integer | The popularity rank of the game over a 30-day window |
###### Game Website Structure
| Field | Type | Description |
| -------- | ------- | ------------------------------------------------- |
| url | string | The URL of the website |
| category | integer | The [category of website](#game-website-category) |
###### Game Website Category
| Value | Name | Description |
| ----- | --------- | --------------------- |
| 1 | OFFICIAL | Official game website |
| 2 | WIKIA | Fandom |
| 3 | WIKIPEDIA | Wikipedia |
| 4 | FACEBOOK | Facebook |
| 5 | TWITTER | Twitter |
| 6 | TWITCH | Twitch |
| 8 | INSTAGRAM | Instagram |
| 9 | YOUTUBE | YouTube |
| 10 | IPHONE | iPhone |
| 11 | IPAD | iPad |
| 12 | ANDROID | Android |
| 13 | STEAM | Steam |
| 14 | REDDIT | Subreddit |
| 15 | ITCH | Itch.io |
| 16 | EPICGAMES | Epic Games Store |
| 17 | GOG | GOG |
| 18 | DISCORD | Discord server |
| 19 | BLUESKY | Bluesky |
| 20 | BATTLENET | Battle.net |
| 21 | RIOT | Riot Games |
| 22 | ROBLOX | Roblox |
| 23 | MINECRAFT | Minecraft |
###### Company Structure
| Field | Type | Description |
| ----- | -------------- | ------------------------ |
| name | string | The name of the company |
| roles | array[integer] | The roles of the company |
###### Game Data Structure
| Field | Type | Description |
| ------------------------- | ---------------------------------------------------------------- | ------------------------------------------------------------------ |
| application_id | snowflake | The ID of the game application |
| igdb_game_id | ?string | The ID of the game on IGDB |
| name | string | The name of the application |
| summary? | ?string | The summary of the game |
| summary_localized? | ?string | The localized summary of the game |
| websites? | array[[game website](#game-website-structure) object] | The websites relating to the game |
| themes? | array[integer] | The [themes](#game-theme-type) of the game |
| genres? | array[integer] | The [genres](/resources/store#sku-genre) of the game |
| platforms? | array[integer] | The [platforms that the game is available on](#game-platform-type) |
| artwork_urls? | array[string] | The URLs to the game artworks |
| screenshot_urls? | array[string] | The URLs to the game screenshots |
| icon_hash? | ?string | The game's [icon hash](/reference#cdn-formatting) |
| cover_image_url? | ?string | The URL to the game's default rich presence invite cover image |
| first_release_date? | ?ISO8601 timestamp | When the game first released |
| publisher_names? | array[string] | The names of the game publishers |
| developer_names? | array[string] | The names of the game developers |
| trailers? | array[[store asset](/resources/store#store-asset-object) object] | The game trailers |
| shop_collection_ids? | array[snowflake] | The IDs of the storefront collections |
| steam_release_status? | integer | The [game release status on Steam](#steam-release-status) |
| reviews? | [game data reviews](#game-data-reviews-structure) | The reviews of the game |
| opencritic_url? | string | The URL to reviews on OpenCritic |
| steam_id? | string | The ID of the game on Steam |
| announcements_channel_id? | snowflake | The ID of the announcements channel |
| l30_rank | integer | The popularity rank of the game over a 30-day window |
| game_flags? | integer | The [game's flags](#game-flags) |
###### Game Data Reviews Structure
| Field | Type | Description |
| ----------- | ------------------------------------------------------------------------------ | ------------------------- |
| steam? | [game data steam reviews](#game-data-steam-reviews-structure) object | The reviews on Steam |
| opencritic? | [game data opencritic reviews](#game-data-opencritic-reviews-structure) object | The reviews on OpenCritic |
###### Game Data Steam Reviews Structure
| Field | Type | Description |
| ----------------------- | ------- | ------------------------------------------------------------------------------------------------------- |
| rating? | float | Overall positive review ratio for the game across all time, as a value between 0 and 1 |
| rating_count? | integer | Total number of reviews submitted across all time |
| recent_rating? | float | Positive review ratio calculated from reviews submitted in the last 30 days, as a value between 0 and 1 |
| recent_rating_count? | integer | Total number of reviews submitted in the last 30 days |
| localized_rating? | float | Positive review ratio filtered to reviews written in the user's locale, as a value between 0 and 1 |
| localized_rating_count? | integer | Total number of reviews written in the user's locale |
###### Game Data OpenCritic Reviews Structure
| Field | Type | Description |
| ----------------------- | -------- | ------------------------------------------------------ |
| top_critic_rating | ?integer | The rating on OpenCritic |
| top_critic_rating_count | ?integer | Number of reviews on OpenCritic |
| tier | ?integer | The [tier](#opencritic-tier) of the game on OpenCritic |
###### OpenCritic Tier
| Value | Name | Description |
| ----- | ------ | ----------- |
| 1 | MIGHTY | Mighty |
| 2 | STRONG | Strong |
| 3 | FAIR | Fair |
| 4 | WEAK | Weak |
###### Game Theme Type
| Value | Name | Description |
| ----- | --------------- | --------------- |
| 0 | THRILLER | Thriller |
| 1 | SCIENCE_FICTION | Science fiction |
| 2 | ACTION | Action |
| 3 | HORROR | Horror |
| 4 | SURVIVAL | Survival |
| 5 | FANTASY | Fantasy |
| 6 | HISTORICAL | Historical |
| 7 | STEALTH | Stealth |
| 8 | COMEDY | Comedy |
| 9 | BUSINESS | Business |
| 10 | DRAMA | Drama |
| 11 | NON_FICTION | Non fiction |
| 12 | KIDS | Kids |
| 13 | SANDBOX | Sandbox |
| 14 | OPEN_WORLD | Open world |
| 15 | WARFARE | Warfare |
| 16 | EDUCATIONAL | Educational |
| 17 | MYSTERY | Mystery |
| 18 | PARTY | Party |
| 19 | ROMANCE | Romance |
| 20 | EROTIC | Erotic |
###### Game Platform Type
| Value | Name | Description |
| ----- | ----------- | ------------------------------------ |
| 0 | DESKTOP | Game is available on desktop |
| 1 | XBOX | Game is available on Xbox |
| 2 | PLAYSTATION | Game is available on PlayStation |
| 3 | IOS | Game is available on iOS |
| 4 | ANDROID | Game is available on Android |
| 5 | NINTENDO | Game is available on Nintendo Switch |
| 6 | LINUX | Game is available on Linux |
| 7 | MACOS | Game is available on macOS |
###### Steam Release Status
| Value | Name | Description |
| ----- | ----------------- | ----------------- |
| 1 | PRE_RELEASE | Pre-release |
| 2 | DAY_OF_RELEASE | Day of release |
| 3 | POST_RELEASE | Post-release |
| 4 | RETIRED_ABANDONED | Retired/abandoned |
| 6 | CHILD_APP | Child application |
###### Game Flags
| Value | Name | Description |
| -------- | --------------------- | ---------------------------- |
| 1 \<\< 0 | GAME_PROFILE_DISABLED | The game profile is disabled |
### Game Claim Object
###### Game Claim Structure
| Field | Type | Description |
| ----------------- | ----------------------------------------------------------- | ------------------------------------------- |
| game_id | snowflake | The ID of the unclaimed game application |
| application_id | snowflake | The ID of the application |
| claim_status | string | The [game claim status](#game-claim-status) |
| third_party_urls? | array[[third party URL](#third-party-url-structure) object] | The URLs to third-party sources |
| updated_at | ISO8601 timestamp | When the game claim was updated |
| invite_proof | string | The code for invite ownership proof |
###### Third Party URL Structure
| Field | Type | Description |
| ----------- | ------ | ------------------------------------------------ |
| distributor | string | The [distributor](#distributor-type) of the game |
| url | string | The URL of the game |
###### Game Claim Status
| Value | Description |
| ------------------------------------------------- | ------------------------------------------------------- |
| not_started | Game claim is not started |
| ready_to_process | Game claim is ready to process |
| fetching_official_guild | Official guild is being fetched |
| has_fetched_official_guild | Official guild is fetched |
| awaiting_verification_code | Awaiting verification code |
| verification_passed | Verification was passed |
| claim_approved | Game claim was approved |
| claim_rejected | Game claim was rejected |
| claim_revoked | Game claim was revoked |
| failed_no_game | The game was found |
| failed_no_application | The application was found |
| failed_no_team | The team was found |
| failed_to_fetch_official_guild_from_third_parties | Failed to fetch official guild |
| failed_no_official_guild_found | Official guild was not found |
| failed_multiple_official_guilds_found | Multiple official guilds were found |
| failed_invite_proof_missing | Invite proof is missing |
| failed_invite_proof_invalid | Invite proof is invalid |
| failed_official_guild_owner_not_found | Owner of official guild owner is not found |
| failed_official_guild_owner_not_on_team | Owner of official guild owner is not on team |
| failed_official_guild_owner_mfa_not_enabled | Owner of official guild owner does not have MFA enabled |
| failed_verification_code_sent_too_recently | Verification code was sent too recently |
| failed_verification_code_not_sent | Verification code was not sent |
| failed_verification_code_invalid | Verification code is invalid |
| failed_unknown | Unknown |
## Endpoints
List Application Game Claims
Returns a list of [game claim](/resources/game#game-claim-object) objects for the given application ID.
Get Application Game Claim
Returns a [game claim](/resources/game#game-claim-object) object for the given application ID.
Create Application Game Claim
Creates a game claim for the given application ID. Returns a [game claim](/resources/game#game-claim-object) object on success. May fire a [Guild Official Game Applications Update](/gateway/gateway-events#guild-official-game-applications-update) Gateway event.
###### Query String Params
| Field | Type | Description |
| ------------------------- | ------- | ------------------------------------------------------- |
| verification_code? | string | The verification code (max 8 characters) |
| reset_verification? | boolean | Whether to reset verification (default false) |
| resend_verification_code? | boolean | Whether to resend the verification code (default false) |
| full_name? | string | Full legal name of the applicant (max 100 characters) |
| business_email? | string | Business email of the applicant (max 320 characters) |
| business_role? | string | Business role of the applicant (max 100 characters) |
| business_website? | string | The business website (max 256 characters) |
Modify Application Game Claim
Modifies the game claim. Returns a [game claim](#game-claim-object) object on success.
###### JSON Params
| Field | Type | Description |
| ------------------------- | ---------- | ----------------------------------- |
| announcements_channel_id? | ?snowflake | The ID of the announcements channel |
Delete Application Game Claim
Deletes the given game claim. Returns a 204 empty response.
List Detectable Non Game Applications
Returns a list of [detectable application](/resources/game#detectable-application-object) objects representing non-games that can be detected by Discord for rich presence.
List Detectable Games
Returns a list of [detectable application](/resources/game#detectable-application-object) objects representing games that can be detected by Discord for rich presence.
List Detectable Game Exclusions
Returns the patterns which should be ignored when detecting games.
###### Response Body
| Field | Type | Description |
| ----------- | ------------- | ---------------------------------------------------------- |
| executables | array[string] | Names of ignored processes |
| patterns | array[string] | Regular expression patterns to match against process names |
List Games
Returns a list of [game](#game-object) objects for the given application IDs.
###### Query String Params
| Field | Type | Description |
| ----------------------- | ---------------- | -------------------------------------------------------- |
| game_ids | array[snowflake] | The IDs of the applications (1-25) |
| with_supplemental_data? | boolean | Whether to include supplemental game data (default true) |
Get Game
Returns a [game](#game-object) object for the given application ID.
###### Query String Params
| Field | Type | Description |
| ----------------------- | ------- | -------------------------------------------------------- |
| with_supplemental_data? | boolean | Whether to include supplemental game data (default true) |
List Game Announcements
Returns messages in the game's announcements channel.
###### Query String Params
| Field | Type | Description |
| ----- | ------- | --------------------------------------------------- |
| limit | integer | Max number of messages to return (1-50, default 50) |
###### Response Body
| Field | Type | Description |
| ---------- | ---------------------------------------------------------- | ----------------------------------------- |
| guild_id | ?snowflake | The ID of the guild |
| channel_id | ?snowflake | The ID of the channel |
| messages | array[[message](/resources/message#message-object) object] | The messages in the announcements channel |
---
# Quests
Link: https://docs.discord.food/resources/quests
Quests are a way for Discord to promote games and other content to users. Users can receive rewards for completing quests, such as redeemable codes, in-game items, or collectibles.
### Quest Object
A sponsored quest.
###### Quest Structure
| Field | Type | Description |
| ------------------------------------- | ------------------------------------------------------ | --------------------------------------------------------------------- |
| id | snowflake | The ID of the quest |
| config | [quest config](#quest-config-object) object | The configuration and metadata for the quest |
| user_status | ?[quest user status](#quest-user-status-object) object | The user's quest progress, if it has been accepted |
| targeted_content **(deprecated)** ^1^ | ?array[integer] | The [content areas where the quest can be shown](#quest-content-type) |
| preview | boolean | Whether the quest is unreleased and in preview for Discord employees |
| traffic_metadata_sealed? | string | Sealed traffic metadata for the delivered quest |
^1^ Some quest content areas may be dismissed using the [Dismiss Quest Content](#dismiss-quest-content) endpoint.
###### Partial Quest Structure
| Field | Type | Description |
| --------------- | ---------- | ------------------------------------------------------------ |
| id | snowflake | The ID of the quest |
| replacement_id? | ?snowflake | The ID of the analogous replacement for an unavailable quest |
### Quest Config Object
The quest definition.
###### Quest Config Structure
The config structure has multiple distinct versions with different field sets. Only actively used versions are kept documented. As of now, only the latest version is available.
| Field | Type | Description |
| ------------------- | ---------------------------------------------------------------------- | ---------------------------------------------------------- |
| id | snowflake | The ID of the quest |
| config_version | integer | [Quest configuration version](#quest-config-version) |
| starts_at | ISO8601 timestamp | When the quest period starts |
| expires_at | ISO8601 timestamp | When the quest period ends |
| features | array[integer] | The [quest features](#quest-feature) enabled for the quest |
| application | [quest application](#quest-application-structure) object | The application metadata for the quest |
| assets | [quest assets](#quest-assets-structure) object | Object that holds the quest's assets |
| colors | [quest gradient](#quest-gradient-structure) object | The accent colors for the quest |
| messages | [quest messages](#quest-messages-structure) object | Human-readable metadata for the quest |
| task_config_v2 | [quest task config](#quest-task-config-structure) object | The task configuration for the quest |
| rewards_config | [quest rewards config](#quest-rewards-config-structure) object | Specifies rewards for the quest (e.g. collectibles) |
| cosponsor_metadata? | [quest cosponsor metadata](#quest-cosponsor-metadata-structure) object | The configuration for the quest co-sponsor |
| share_policy | string | The [share policy](#quest-share-policy) for the quest |
| cta_config | [quest CTA config](#quest-cta-config-structure) object | The quest call-to-action configuration |
###### Quest Application Structure
| Field | Type | Description |
| ------------------------- | --------- | --------------------------- |
| id | snowflake | The ID of the application |
| name | string | The name of the application |
| link **(deprecated)** ^1^ | string | The link to the game's page |
^1^ See the `cta_config` field instead.
###### Quest Assets Structure
An object holding [CDN asset names](/reference#cdn-formatting).
| Field | Type | Description |
| ------------------------ | ------- | --------------------------------------------------------------------------------------------------------------------------------------------------- |
| hero | string | The quest's [hero image](https://en.wiktionary.org/wiki/hero_image) |
| hero_video | ?string | A video representation of the hero image |
| quest_bar_hero | string | The [hero image](https://en.wiktionary.org/wiki/hero_image) used in the quest popup that appears when launching the game before accepting the quest |
| quest_bar_hero_blurhash? | ?string | The blurhash for the quest bar hero image |
| quest_bar_hero_video | ?string | A video representation of the quest bar hero image |
| game_tile | string | The game's icon |
| game_tile_light? | string | The game's icon for light backgrounds |
| game_tile_dark? | string | The game's icon for dark backgrounds |
| logotype | string | The game's [logo](https://en.wikipedia.org/wiki/Logo) |
| logotype_light? | string | The game's logo for light backgrounds |
| logotype_dark? | string | The game's logo for dark backgrounds |
###### Quest Gradient Structure
A 2-point gradient with a `primary` and `secondary` color.
| Field | Type | Description |
| --------- | ------ | ----------------------------------------------- |
| primary | string | The hex-encoded primary color of the gradient |
| secondary | string | The hex-encoded secondary color of the gradient |
###### Quest Messages Structure
| Field | Type | Description |
| -------------- | ------ | ------------------------------------------ |
| quest_name | string | The name of the quest |
| game_title | string | The title of the game the quest is for |
| game_publisher | string | The publisher of the game the quest is for |
###### Quest Task Config Structure
| Field | Type | Description |
| ----------------- | ------------------------------------------------------- | ----------------------------------------------------------------------------- |
| join_operator ^1^ | string | The eligibility operator used to join multiple tasks (`and` or `or`) |
| tasks | map[string, [quest task](#quest-task-structure) object] | Tasks required to complete the quest, keyed by their [type](#quest-task-type) |
^1^ For a task set to be considered complete, the user must complete either all tasks (when `join_operator` is `and`) or at least one task (when `join_operator` is `or`).
###### Quest Task Structure
| Field | Type | Description |
| -------------------------- | ------------------------------------------------------------------------- | ---------------------------------------------- |
| type | string | The [type of task event](#quest-task-type) |
| target ^1^ | integer | The required value |
| applications? | array[[quest task application](#quest-task-application-structure) object] | The application targets that satisfy this task |
| external_ids? | array[string] | IDs of the target game on console platforms |
| assets? | [quest video assets](#quest-video-assets-structure) object | Video task assets |
| messages? | [quest task messages](#quest-task-messages-structure) object | Human-readable task metadata |
| event_name? | string | The achievement event name |
| account_link_instructions? | string | Instructions for linking an account |
^1^ While this is an opaque value, for duration-based tasks, this will be a duration in seconds.
###### Quest Task Application Structure
| Field | Type | Description |
| ----- | --------- | ------------------------- |
| id | snowflake | The ID of the application |
###### Quest Task Messages Structure
| Field | Type | Description |
| ----------------- | ------ | -------------------- |
| video_title? | string | The title of a video |
| task_title? | string | The task title |
| task_description? | string | The task description |
###### Quest Task Type
| Value | Description |
| --------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| STREAM_ON_DESKTOP | The user must play and stream the game on desktop to at least one other user for a certain duration (see [Update Activity Session](/resources/presence#update-activity-session)) |
| PLAY_ON_DESKTOP | The user must play the game on desktop for a certain duration (see [Update Activity Session](/resources/presence#update-activity-session)) |
| ~~PLAY_ON_DESKTOP_V2~~ | ~~The user must play the game on desktop for a certain duration (see [Update Activity Session](/resources/presence#update-activity-session))~~ |
| PLAY_ON_XBOX | The user must play the game on Xbox for a certain duration |
| PLAY_ON_PLAYSTATION | The user must play the game on PlayStation for a certain duration |
| WATCH_VIDEO | The user must watch a video for a certain duration |
| WATCH_VIDEO_ON_MOBILE | The user must watch a video on mobile for a certain duration |
| PLAY_ACTIVITY | The user must play the embedded activity for a certain duration |
| ACHIEVEMENT_IN_GAME ^1^ | The user must complete an achievement in the game |
| ACHIEVEMENT_IN_ACTIVITY ^1^ | The user must complete an achievement in the embedded activity |
^1^ Completion of this task is tracked by the application itself.
###### Quest Rewards Config Structure
| Field | Type | Description |
| ----------------- | ----------------------------------------------------- | -------------------------------------------------------------------- |
| assignment_method | integer | [How the rewards are assigned](#quest-reward-assignment-method) |
| rewards | array[[quest reward](#quest-reward-structure) object] | The possible rewards for the quest, ordered by tier (if applicable) |
| rewards_expire_at | ?ISO8601 timestamp | When the reward claiming period ends |
| platforms | array[integer] | The [platforms](#quest-platform-type) the rewards can be redeemed on |
###### Quest Reward Structure
| Field | Type | Description |
| ---------------------- | ---------------------------------------------------------------- | ----------------------------------------------------------- |
| type | integer | The [reward's type](#quest-reward-type) |
| sku_id | snowflake | The ID of the SKU awarded |
| asset? | ?string | The reward's [media asset](/reference#cdn-formatting) |
| asset_video? | ?string | The reward's [video asset](/reference#cdn-formatting) |
| messages | [quest reward messages](#quest-reward-messages-structure) object | Human-readable metadata for the reward |
| approximate_count? ^1^ | ?integer | An approximate count of how many users can claim the reward |
| redemption_link? | ?string | The link to redeem the reward |
| expires_at? | ?ISO8601 timestamp | When the reward expires |
| expires_at_premium? | ?ISO8601 timestamp | When the reward expires for premium users |
| expiration_mode? | integer | The [expiration mode](#quest-reward-expiration-mode) |
| orb_quantity? | integer | The amount of Discord Orbs awarded |
| premium_orb_quantity? | integer | The amount of Discord Orbs awarded to premium users |
| quantity? | integer | The days of fractional premium awarded |
^1^ If the amount of users who claimed the awards exceeds this count, then all future claimers will be assigned the next reward tier in the list.
###### Quest Reward Messages Structure
| Field | Type | Description |
| ------------------------------------ | -------------------- | -------------------------------------------------------------------------- |
| name | string | The reward's name |
| name_with_article | string | The article variant of the name (e.g. a Cybernetic Headgear Decoration) |
| redemption_instructions_by_platform? | map[integer, string] | Instructions for redeeming the reward [per-platform](#quest-platform-type) |
###### Quest Reward Assignment Method
The method used to assign the reward to a user.
| Value | Name | Description |
| ----- | ------ | ---------------------------------------------------- |
| 1 | ALL | All rewards are assigned to the user upon completion |
| 2 | TIERED | The rewards are assigned in tiers |
###### Quest Reward Type
The type of reward that the user will receive.
| Value | Name | Description |
| ----- | ------------------ | ------------------------------------------------------------------------------------- |
| 1 | REWARD_CODE | The reward is a redeemable code |
| 2 | IN_GAME | The reward is automatically given to the user in the promoted game |
| 3 | COLLECTIBLE | The reward is a Discord collectible (e.g. an avatar decoration) |
| 4 | VIRTUAL_CURRENCY | The reward is a virtual currency (Discord Orbs) |
| 5 | FRACTIONAL_PREMIUM | The reward is a limited free premium (Nitro) trial for a fraction of a billing period |
###### Quest Reward Expiration Mode
Controls the expiration behavior of `COLLECTIBLE` rewards.
| Value | Name | Description |
| ----- | ----------------- | ------------------------------------------------------------------------------------------ |
| 1 | NORMAL | The reward expires after a set period of time |
| 2 | PREMIUM_EXTENSION | The reward lasts longer for premium (Nitro) users |
| 3 | PREMIUM_PERMANENT | The reward is permanent for premium (Nitro) users, even after their subscription has ended |
###### Quest Video Assets Structure
| Field | Type | Description |
| -------------- | -------------------------------------------------------- | ------------------------------ |
| video | [quest video asset](#quest-video-asset-structure) object | The primary video asset |
| video_low_res? | [quest video asset](#quest-video-asset-structure) object | The low-resolution video asset |
| video_hls? | [quest video asset](#quest-video-asset-structure) object | The HLS video asset |
###### Quest Video Asset Structure
| Field | Type | Description |
| ----------- | ------- | ------------------------ |
| url | string | The video asset URL |
| width? | integer | The video width |
| height? | integer | The video height |
| thumbnail? | string | The thumbnail asset URL |
| caption? | string | The caption asset URL |
| transcript? | string | The transcript asset URL |
###### Quest Cosponsor Metadata Structure
| Field | Type | Description |
| ----------------------- | ------ | ------------------------------------------------- |
| name | string | The name of the co-sponsor |
| logotype | string | The co-sponsor's logo asset |
| logotype_light? | string | The co-sponsor's logo asset for light backgrounds |
| logotype_dark? | string | The co-sponsor's logo asset for dark backgrounds |
| redemption_instructions | string | The co-sponsor's redemption instructions |
###### Quest CTA Config Structure
| Field | Type | Description |
| ------------ | ---------------------------------------------------------------------- | --------------------------- |
| link | string | The CTA link |
| button_label | string | The CTA button label |
| subtitle? | string | The CTA subtitle |
| android? | [Android quest CTA config](#android-quest-cta-config-structure) object | Android-specific CTA config |
| ios? | [iOS quest CTA config](#ios-quest-cta-config-structure) object | iOS-specific CTA config |
###### Android Quest CTA Config Structure
| Field | Type | Description |
| -------------- | ------ | ------------------------------------ |
| android_app_id | string | The Android application package name |
###### iOS Quest CTA Config Structure
| Field | Type | Description |
| ---------- | ------ | ---------------------- |
| ios_app_id | string | The iOS application ID |
###### Quest Share Policy
| Value | Description |
| -------------------- | ---------------------------------- |
| shareable_everywhere | The quest can be shared everywhere |
| not_shareable | The quest cannot be shared |
###### Quest Config Version
The version of the quest configuration.
| Value | Status |
| ----- | ------------ |
| 2 | Active |
| 1 | Discontinued |
###### Quest Content Type
Areas where the quest can be shown in the Discord client.
| Value | Name | Description | Dismissable |
| ----- | ------------------------------------- | ------------------------------------------------------------------- | ----------- |
| 0 | GIFT_INVENTORY_SETTINGS_BADGE | This quest is shown as a badge in User Settings | Yes |
| 1 | QUEST_BAR | This quest is shown as a bar above the user popout | Yes |
| 2 | QUEST_INVENTORY_CARD | This quest is shown as a card in the user's gift inventory | No |
| 3 | QUESTS_EMBED | This quest is shown as an embed in chat | No |
| 4 | ACTIVITY_PANEL | This quest is shown in the Active Now page | Yes |
| 5 | QUEST_LIVE_STREAM | This quest is shown while watching a stream | Yes |
| 6 | MEMBERS_LIST | This quest is shown in the member list | No |
| 7 | QUEST_BADGE | This quest is shown on the quest profile badge upsell | No |
| 8 | GIFT_INVENTORY_FOR_YOU | This quest is featured in the user's gift inventory for you section | No |
| 9 | GIFT_INVENTORY_OTHER | This quest is featured in the user's gift inventory | No |
| 10 | QUEST_BAR_V2 | This quest is shown in the new quest bar design | Yes |
| 11 | QUEST_HOME_DESKTOP | This quest is shown on the desktop Quest discovery page | No |
| 12 | QUEST_HOME_MOBILE | This quest is shown on the mobile Quest discovery page | No |
| 13 | QUEST_BAR_MOBILE | This quest is shown in the mobile Quest bar design | Yes |
| 14 | THIRD_PARTY_APP | This quest is shown in a third-party app | No |
| 15 | QUEST_BOTTOM_SHEET | This quest is shown in the bottom sheet | No |
| 16 | QUEST_EMBED_MOBILE | This quest is shown in the mobile Quest embed | No |
| 17 | QUEST_HOME_MOVE_CALLOUT | This quest is shown in the move callout on the Quest discovery page | No |
| 18 | DISCOVERY_SIDEBAR | This quest is shown in the discovery sidebar | No |
| 19 | QUEST_SHARE_LINK | This quest is eligible to be shared as a link | No |
| 20 | CONNECTIONS_MODAL | This quest is shown in the user connections modal | No |
| 21 | DISCOVERY_COMPASS | This quest is shown on the discovery button | No |
| 22 | TROPHY_CASE_CARD | This quest is shown as a card in the user's trophy case | No |
| 23 | VIDEO_MODAL | This quest has a video modal | No |
| 24 | VIDEO_MODAL_END_CARD | This quest has an end card in the video modal | No |
| 25 | REWARD_MODAL | This quest is shown in the reward modal | No |
| 26 | EXCLUDED_QUEST_EMBED | This quest is excluded from the Quest embed | No |
| 27 | VIDEO_MODAL_MOBILE | This quest is shown in the mobile video modal | No |
| 28 | ORBS_ANNOUNCEMENT_MODAL | This quest is shown in the Orbs announcement modal | No |
| 29 | ORBS_BALANCE_MENU | This quest is shown in the Orbs balance menu | No |
| 30 | QUEST_ENROLLMENT_BLOCKED_BOTTOM_SHEET | This quest is shown in the enrollment blocked bottom sheet | No |
| 31 | ORBS_SHOP_HERO_CTA | This quest is shown in the Orbs shop hero CTA | No |
| 32 | QUEST_ENROLLMENT_BLOCKED_MODAL | This quest is shown in the enrollment blocked modal | No |
| 33 | INTERNAL_PREVIEW_TOOL | This quest is shown in the internal preview tool | No |
| 34 | ORBS_REHEAT_COACHMARK_CTA | This quest is shown in the Orbs reheat coachmark CTA | No |
| 35 | INVALID_QUEST_EMBED | This quest is shown for invalid quest embeds | No |
| 36 | NOT_SHAREABLE_QUEST_EMBED | This quest is shown for quest embeds that cannot be shared | No |
| 37 | QUEST_HOME_MOVE_CALLOUT_DISCOVER | This quest is shown in the Quest Home move callout discover CTA | No |
| 38 | SPONSORED_QUEST_SHEET | This quest is shown in the sponsored quest sheet | No |
| 39 | MOBILE_ORBS_ONBOARDING_DC | This quest is shown in mobile Orbs onboarding dismissible content | No |
| 40 | RUNNING_ACTIVITY | This quest is shown from a running activity | No |
| 41 | VIDEO_MODAL_PRIMARY_CTA | This quest is shown in the video modal primary CTA | No |
| 42 | QUEST_HOME_TAKEOVER | This quest is shown in the Quest Home takeover | No |
| 43 | USER_PROFILE_ACTIVITY | This quest is shown in user profile activity | No |
| 44 | MEMBERS_LIST_CARD | This quest is shown in a member list card | No |
| 45 | APP_LAUNCHER | This quest is shown in the app launcher | No |
| 46 | ACTIVITY_SUGGESTION | This quest is shown as an activity suggestion | No |
| 47 | QUEST_HOME_ENTRYPOINT | This quest is shown in the Quest Home entrypoint | No |
| 48 | QUEST_HOME_ENTRYPOINT_THEMED | This quest is shown in the themed Quest Home entrypoint | No |
| 49 | QUEST_ACTIVITY_UNENROLLED_MODAL | This quest is shown in the quest activity unenrolled modal | No |
| 50 | QUEST_HOME_HERO | This quest is shown in the Quest Home hero | No |
| 51 | QUEST_ACTIVITY_HEADER | This quest is shown in the quest activity header | No |
| 52 | USER_PROFILE_HEADER | This quest is shown in the user profile header | No |
| 53 | USER_SETTINGS | This quest is shown in user settings | No |
| 54 | NITRO_HOME_PERK_CARD | This quest is shown on a Nitro Home perk card | No |
| 55 | QUEST_HOME_MOBILE_CAROUSEL | This quest is shown in the mobile Quest Home carousel | No |
| 56 | QUEST_HOME_HERO_SHELF | This quest is shown in the Quest Home hero shelf | No |
| 57 | VIDEO_MODAL_ICON_END_CARD | This quest has an icon end card in the video modal | No |
| 58 | ACHIEVEMENT_IN_GAME_MODAL | This quest is shown in the in-game achievement modal | No |
| 59 | QUEST_HOME_FEATURED_SECTION | This quest is shown in the Quest Home featured section | No |
| 60 | QUEST_HOME_IN_PROGRESS_SECTION | This quest is shown in the Quest Home in-progress section | No |
| 61 | QUEST_HOME_ENDING_SOON_SECTION | This quest is shown in the Quest Home ending soon section | No |
| 62 | QUEST_HOME_ORB_SECTION | This quest is shown in the Quest Home Orbs section | No |
| 63 | QUEST_HOME_DISCOVERED_SECTION | This quest is shown in the Quest Home discovered section | No |
| 64 | QUEST_HOME_SEARCH_RESULT | This quest is shown in Quest Home search results | No |
| 65 | PLAY_QUEST_MODAL | This quest is shown in the play quest modal | No |
| 66 | VIDEO_MODAL_MOBILE_FOOTER | This quest is shown in the mobile video modal footer | No |
| 67 | QUEST_HOME_ENTRYPOINT_MOBILE | This quest is shown in the mobile Quest Home entrypoint | No |
| 68 | BOUNTIES_END_INTERSTITIAL | This quest is shown in the bounties end interstitial | No |
| 69 | QUEST_HOME_EXPIRED_SECTION | This quest is shown in the Quest Home expired section | No |
| 70 | QUEST_HOME_PREVIEW_SECTION | This quest is shown in the Quest Home preview section | No |
| 71 | SOCIAL_LAYER_STOREFRONT | This quest is shown in the social layer storefront | No |
| 72 | QUEST_HOME_SPECIAL_QUESTS_SECTION | This quest is shown in the Quest Home special quests section | No |
###### Quest Platform Type
Specifies the platforms that the quest reward can be redeemed on.
| Value | Name | Description |
| ----- | -------------- | ---------------------------------------------- |
| 0 | CROSS_PLATFORM | This reward can be redeemed on all platforms |
| 1 | XBOX | This reward can be redeemed on Xbox |
| 2 | PLAYSTATION | This reward can be redeemed on PlayStation |
| 3 | SWITCH | This reward can be redeemed on Nintendo Switch |
| 4 | PC | This reward can be redeemed on PC |
###### Quest Feature
A behavioral variant for a quest.
| Value | Name | Description |
| ----- | ----------------------------------- | --------------------------------------------------- |
| 1 | POST_ENROLLMENT_CTA | The quest has a post-enrollment call-to-action |
| ~~2~~ | ~~PLAYTIME_CRITERIA~~ | ~~The quest has a playtime criteria~~ |
| 3 | QUEST_BAR_V2 | The quest uses the new quest bar design |
| ~~4~~ | ~~EXCLUDE_MINORS~~ | ~~The quest is not shown to minors~~ |
| 5 | EXCLUDE_RUSSIA | The quest is not shown in Russia |
| 6 | IN_HOUSE_CONSOLE_QUEST | The console quest is first-party |
| 7 | MOBILE_CONSOLE_QUEST | The console quest is available on mobile |
| 8 | START_QUEST_CTA | The quest has a start call-to-action |
| 9 | REWARD_HIGHLIGHTING | The quest has reward highlighting |
| 10 | FRACTIONS_QUEST | The quest offers fractional rewards |
| 11 | ADDITIONAL_REDEMPTION_INSTRUCTIONS | The quest has additional redemption instructions |
| 12 | PACING_V2 | The quest uses the new pacing system |
| 13 | DISMISSAL_SURVEY | The quest presents a survey upon dismissal |
| 14 | MOBILE_QUEST_DOCK | The quest is shown in the mobile quest dock |
| 15 | QUESTS_CDN | The quest uses the CDN for assets |
| 16 | PACING_CONTROLLER | The quest uses the pacing controller |
| 17 | QUEST_HOME_FORCE_STATIC_IMAGE | The quest displays a static image on the Quest Home |
| 18 | VIDEO_QUEST_FORCE_HLS_VIDEO | The video quest forces HLS video playback |
| 19 | VIDEO_QUEST_FORCE_END_CARD_CTA_SWAP | The video quest swaps the end card CTA |
| 20 | EXPERIMENTAL_TARGETING_TRAITS | The quest uses experimental targeting traits |
| 21 | DO_NOT_DISPLAY | The quest should not be displayed |
| 22 | EXTERNAL_DIALOG | The quest uses an external dialog |
| 23 | MOBILE_ONLY_QUEST_PUSH_TO_MOBILE | The quest is mobile-only and pushes users to mobile |
| 24 | MANUAL_HEARTBEAT_INITIALIZATION | The quest uses manual heartbeat initialization |
| 25 | CLOUD_GAMING_ACTIVITY | The quest uses cloud gaming activity behavior |
| 26 | NON_GAMING_PLAY_QUEST | The quest is a non-gaming play quest |
| 27 | ACTIVITY_QUEST_AUTO_ENROLLMENT | The activity quest can auto-enroll users |
| 28 | PACKAGE_ACTION_ADVENTURE | The quest is in the action/adventure package |
| 29 | PACKAGE_RPG_MMO | The quest is in the RPG/MMO package |
| 30 | PACKAGE_RACING_SPORTS | The quest is in the racing/sports package |
| 31 | PACKAGE_SANDBOX_CREATIVE | The quest is in the sandbox/creative package |
| 32 | PACKAGE_FAMILY_FRIENDLY | The quest is in the family-friendly package |
| 33 | PACKAGE_HOLIDAY_SEASON | The quest is in the holiday season package |
| 34 | PACKAGE_NEW_YEARS | The quest is in the New Years package |
| 35 | FULL_EPISODE_VIDEO_QUEST | The quest is a full episode video quest |
| 36 | MOBILE_ACTIVITY_QUEST | The quest is a mobile activity quest |
| 37 | QUEST_BAR_UNFURL | The quest supports quest bar unfurl behavior |
| 38 | NO_PREMIUM_ORBS_PERK | The quest does not use the premium Orbs perk |
| 39 | NITRO_CONTROL_CTA | The quest has a Nitro control CTA |
| 40 | NITRO_2_POINT_0_CTA | The quest has a Nitro 2.0 CTA |
| 41 | ORBS_MULTIPLIER_QUEST | The quest is an Orbs multiplier quest |
| 42 | XBOX_GAME_PASS_QUEST | The quest is an Xbox Game Pass quest |
###### Example Quest
```json
{
"id": "8206816794116096000",
"config": {
"id": "8206816794116096000",
"config_version": 2,
"starts_at": "2025-02-21T18:00:00+00:00",
"expires_at": "2025-02-28T01:00:00+00:00",
"features": [3, 9, 12, 14, 15, 16],
"application": {
"link": "https://alien.studios/cyberalien",
"id": "891436233903964161",
"name": "Cyberalien 2077"
},
"assets": {
"hero": "hero.jpg",
"hero_video": "hero.mp4",
"quest_bar_hero": "questbar.jpg",
"quest_bar_hero_video": "questbar.mp4",
"game_tile": "gametile.jpg",
"logotype": "wordmark.png"
},
"colors": {
"primary": "#E944D4",
"secondary": "#5318A7"
},
"messages": {
"quest_name": "Kill the Aliens",
"game_title": "Cyberalien 2077",
"game_publisher": "Alien Studios"
},
"task_config_v2": {
"join_operator": "or",
"tasks": {
"PLAY_ON_DESKTOP": {
"type": "PLAY_ON_DESKTOP",
"target": 900,
"applications": [{ "id": "891436233903964161" }]
},
"PLAY_ON_XBOX": {
"type": "PLAY_ON_XBOX",
"target": 900,
"external_ids": ["267696969"],
"applications": [{ "id": "891436233903964161" }]
},
"PLAY_ON_PLAYSTATION": {
"type": "PLAY_ON_PLAYSTATION",
"target": 900,
"external_ids": ["CUSA42069_00"],
"applications": [{ "id": "891436233903964161" }]
}
}
},
"rewards_config": {
"assignment_method": 1,
"rewards": [
{
"type": 1,
"sku_id": "1342624440894361624",
"asset": "CYBERNETIC_HEADGEAR_HELL_YEAHHH.png",
"asset_video": null,
"messages": {
"name": "Cybernetic Headgear",
"name_with_article": "a Cybernetic Headgear",
"redemption_instructions_by_platform": {
"0": "Reward Instructions:\nGo to https://alien.studios/redeem\nEnter your code\nClaim your reward!"
}
},
"approximate_count": null,
"redemption_link": "https://alien.studios/redeem"
}
],
"rewards_expire_at": "2025-03-28T00:00:00+00:00",
"platforms": [0]
},
"share_policy": "shareable_everywhere",
"cta_config": {
"link": "https://alien.studios/cyberalien",
"button_label": "Play Now"
}
},
"user_status": null,
"targeted_content": [],
"preview": false
}
```
### Claimed Quest Object
A claimed quest.
###### Claimed Quest Structure
| Field | Type | Description |
| ----------- | -------------------------------------------------------------- | -------------------------------------------- |
| id | snowflake | The ID of the quest |
| config | [claimed quest config](#claimed-quest-config-structure) object | The configuration and metadata for the quest |
| user_status | [quest user status](#quest-user-status-object) object | The user's quest progress |
###### Claimed Quest Config Structure
| Field | Type | Description |
| ---------- | --------------------------------------------------------------------- | ---------------------------------------------------------- |
| id | snowflake | The ID of the quest |
| starts_at | ISO8601 timestamp | When the quest period starts |
| expires_at | ISO8601 timestamp | When the quest period ends |
| features | array[integer] | The [quest features](#quest-feature) enabled for the quest |
| colors | [quest gradient](#quest-gradient-structure) object | The accent colors for the quest |
| assets | [quest assets](#quest-assets-structure) object | Object that holds the quest's assets |
| messages | [quest messages](#quest-messages-structure) object | Human-readable metadata for the quest |
| rewards | array[[claimed quest reward](#claimed-quest-reward-structure) object] | The claimed rewards for the quest |
###### Claimed Quest Reward Structure
| Field | Type | Description |
| -------------------- | ------------------ | ----------------------------------------------------------------------- |
| type | integer | The [reward's type](#quest-reward-type) |
| sku_id | snowflake | The ID of the SKU awarded |
| name | string | The reward's name |
| name_with_article | string | The article variant of the name (e.g. a Cybernetic Headgear Decoration) |
| asset | string | The reward's [media asset](/reference#cdn-formatting) |
| asset_video | ?string | The reward's [video asset](/reference#cdn-formatting) |
| orb_quantity | ?integer | The amount of Discord Orbs awarded |
| collectible_product? | collectible object | The collectible product awarded |
###### Example Claimed Quest
```json
{
"id": "8206816794116096000",
"config": {
"id": "8206816794116096000",
"starts_at": "2025-02-21T18:00:00+00:00",
"expires_at": "2025-02-28T01:00:00+00:00",
"features": [3, 9, 12, 14, 15, 16],
"colors": {
"primary": "#E944D4",
"secondary": "#5318A7"
},
"assets": {
"hero": "hero.jpg",
"hero_video": "hero.mp4",
"quest_bar_hero": "questbar.jpg",
"quest_bar_hero_video": "questbar.mp4",
"game_tile": "gametile.jpg",
"logotype": "wordmark.png"
},
"messages": {
"quest_name": "Kill the Aliens",
"game_title": "Cyberalien 2077",
"game_publisher": "Alien Studios"
},
"rewards": [
{
"sku_id": "1342624440894361624",
"type": 1,
"name": "Cybernetic Headgear",
"name_with_article": "a Cybernetic Headgear",
"asset": "CYBERNETIC_HEADGEAR_HELL_YEAHHH.png",
"asset_video": null,
"orb_quantity": null
}
]
},
"user_status": null
}
```
### Quest User Status Object
The user's quest progression.
###### Quest User Status Structure
| Field | Type | Description |
| ----------------------------- | ------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| user_id | snowflake | The ID of the user |
| quest_id? | snowflake | The ID of the quest |
| enrolled_at | ?ISO8601 timestamp | When the user accepted the quest |
| completed_at | ?ISO8601 timestamp | When the user completed the quest |
| claimed_at | ?ISO8601 timestamp | When the user claimed the quest's reward |
| claimed_tier? | ?integer | Which reward tier the user has claimed, if the quest's [`assignment_method`](#quest-rewards-config-structure) is [`TIERED`](#quest-reward-assignment-method) |
| orb_quantity_claimed? | ?integer | The amount of Discord Orbs claimed |
| last_stream_heartbeat_at? ^1^ | ?ISO8601 timestamp | When the last heartbeat was received |
| stream_progress_seconds? ^1^ | integer | Duration (in seconds) the user has streamed the game for since the quest was accepted |
| dismissed_quest_content? | integer | The [content areas the user has dismissed](#dismissible-quest-content-flags) for the quest |
| progress | map[string, [quest task progress](#quest-task-progress-structure) object] | The user's progress for each task in the quest, keyed by their [type](#quest-task-type) |
^1^ These fields are only used for quest config version 1, where the event is always `STREAM_ON_DESKTOP`.
###### Quest Task Progress Structure
| Field | Type | Description |
| -------------- | --------------------------------------------------------------- | ------------------------------------------ |
| event_name | string | The [type of task event](#quest-task-type) |
| value ^1^ | integer | The current task value |
| updated_at | ISO8601 timestamp | When the task was last updated |
| completed_at | ?ISO8601 timestamp | When the task was completed |
| heartbeat? ^2^ | ?[quest task heartbeat](#quest-task-heartbeat-structure) object | The task's heartbeat data |
^1^ While this is an opaque value, for duration-based tasks, this will be a duration in seconds. To complete the task, this value must match the `target` value.
^2^ Heartbeats are only present for events `STREAM_ON_DESKTOP`, `PLAY_ON_DESKTOP`, and `PLAY_ACTIVITY`.
###### Quest Task Heartbeat Structure
| Field | Type | Description |
| ------------ | ------------------ | ------------------------------------ |
| last_beat_at | ISO8601 timestamp | When the last heartbeat was received |
| expires_at | ?ISO8601 timestamp | When the task progress expires |
###### Dismissible Quest Content Flags
Dismissed [quest content areas](#quest-content-type).
| Value | Name | Description |
| -------- | ----------------------------- | ----------------------------------------------------- |
| 1 \<\< 0 | GIFT_INVENTORY_SETTINGS_BADGE | User has dismissed the quest from User Settings |
| 1 \<\< 1 | QUEST_BAR ^1^ | User has dismissed the quest from the Quest Bar |
| 1 \<\< 2 | ACTIVITY_PANEL | User has dismissed the quest from the Active Now page |
| 1 \<\< 3 | QUEST_LIVE_STREAM | User has dismissed the quest from the stream overlay |
^1^ This flag dismisses any `QUEST_BAR` content area, including `QUEST_BAR`, `QUEST_BAR_V2`, and `QUEST_BAR_MOBILE`.
###### Example Quest User Status
```json
{
"user_id": "222069018507345921",
"quest_id": "8206816794116096000",
"enrolled_at": "2077-01-01T11:59:59+00:00",
"completed_at": "2077-01-01T11:59:59+00:00",
"claimed_at": "2077-01-01T11:59:59+00:00",
"claimed_tier": null,
"last_stream_heartbeat_at": null,
"stream_progress_seconds": 0,
"dismissed_quest_content": 0,
"progress": {
"PLAY_ON_DESKTOP": {
"value": 900,
"event_name": "PLAY_ON_DESKTOP",
"updated_at": "2025-03-11T18:19:54.189229+00:00",
"completed_at": "2025-03-11T18:19:54.189231+00:00",
"heartbeat": {
"last_beat_at": "2077-01-01T11:59:59+00:00",
"expires_at": null
}
}
}
}
```
### Quest Reward Code Object
An object that holds the quest's reward code.
###### Quest Reward Code Structure
| Field | Type | Description |
| ---------- | ----------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| quest_id | snowflake | The ID of the quest |
| code | string | The redeem code |
| platform | integer | The [platform this redeem code applies to](#quest-platform-type) |
| user_id | snowflake | The ID of the user who this code belongs to |
| claimed_at | ISO8601 timestamp | When the user claimed the quest's reward |
| tier | ?integer | Which reward tier the code belongs to, if the quest's [`assignment_method`](#quest-rewards-config-structure) is set to [`TIERED`](#quest-reward-assignment-method) |
###### Example Quest Reward Code
```json
{
"quest_id": "8206816794116096000",
"code": "111-1111111",
"platform": 0,
"user_id": "222069018507345921",
"claimed_at": "2077-01-01T18:41:29.706194+00:00",
"tier": null
}
```
## Endpoints
List Current User Quests
Returns information on the current [quests](#quest-object) for the current user.
###### Response Body
| Field | Type | Description |
| ------------------------------ | -------------------------------------------- | ---------------------------------------------- |
| quests | array[[quest](#quest-object) object] | The current quests for the user |
| excluded_quests | array[partial [quest](#quest-object) object] | The quests that the user cannot participate in |
| quest_enrollment_blocked_until | ?ISO8601 timestamp | When the user can enroll in quests again |
List Claimed Quests
Returns information on the [claimed quests](#claimed-quest-object) for the current user.
###### Response Body
| Field | Type | Description |
| ------ | ---------------------------------------------------- | ------------------------------- |
| quests | array[[claimed quest](#claimed-quest-object) object] | The claimed quests for the user |
Get Quest Config
Returns a [quest config](#quest-config-object) object for the specified quest. Quest must be currently active.
Get Quest Preview
Returns a [quest](#quest-object) object for the specified preview quest.
This endpoint is only available to authorized quests previewers.
Get Quest Placement
Returns the sponsored quest that should be shown to the user in a specific placement.
###### Query String Params
| Field | Type | Description |
| -------------------------------- | ---------------- | ------------------------------------------------------------------------------ |
| placement | integer | The [quest placement area](#quest-placement-area) to get the quest for |
| client_heartbeat_session_id? ^1^ | string | A client-generated UUID representing the current persisted analytics heartbeat |
| client_ad_session_id? ^2^ | string | A client-generated UUID representing the current ad attribution session |
| visible_guild_ids? | array[snowflake] | Visible guild IDs used as ad context (max 50) |
^1^ This value is also sent in the [client properties](/reference#client-properties).
^2^ This value is used to correlate ad decision requests, ad heartbeat events, and follow-up actions. Clients should reuse an ad session until it has been idle for 30 minutes or active for 12 hours.
###### Quest Placement Area
| Value | Name | Description |
| ----- | -------------------------- | ----------------------------- |
| 1 | DESKTOP_ACCOUNT_PANEL_AREA | Account panel on desktop |
| 2 | MOBILE_HOME_DOCK_AREA | Home dock on mobile |
| 3 | QUEST_HOME_BANNER_DESKTOP | Quest Home banner on desktop |
| 4 | QUEST_HOME_MOBILE_CAROUSEL | Quest Home carousel on mobile |
| 5 | VIDEO_MODAL_MOBILE | Video modal on mobile |
###### Response Body
| Field | Type | Description |
| ------------------------ | --------------------------------------------------------------- | ----------------------------------------------------- |
| request_id | string | The advertisement decision ID |
| quest | ?[quest](#quest-object) object | The quest to show to the user |
| creative | ?[quest ad creative](#quest-ad-creative-structure) object | The advertisement creative to show to the user |
| ad_identifiers | ?[quest ad identifiers](#quest-ad-identifiers-structure) object | The advertisement identifiers for the delivered quest |
| ad_context | ?[quest ad context](#quest-ad-context-structure) object | The advertisement context for the delivered quest |
| response_ttl_seconds? | integer | How long the response should be cached, in seconds |
| metadata_sealed? | ?string | Sealed metadata for the advertisement |
| traffic_metadata_sealed? | ?string | Sealed traffic metadata for the advertisement |
###### Quest Ad Identifiers Structure
| Field | Type | Description |
| -------------- | --------- | ------------------------------------------------------- |
| campaign_id? | snowflake | The ID of the advertisement campaign |
| ad_set_id? | snowflake | The ID of the advertisement set |
| ad_id? | snowflake | The ID of the advertisement |
| creative_id? | snowflake | The ID of the advertisement creative |
| creative_type? | integer | The [type of advertisement creative](#ad-creative-type) |
| is_targeted? | boolean | Whether the advertisement is targeted |
| ad_content_id? | snowflake | The ID of the advertisement content |
###### Quest Ad Context Structure
| Field | Type | Description |
| ----------------------- | ------- | ---------------------------------------------------- |
| is_campaign_ias_enabled | boolean | Whether the campaign has Integral Ad Science enabled |
###### Quest Ad Decision Structure
| Field | Type | Description |
| ------------------------ | -------------------------------------------------------------- | ----------------------------------------------------- |
| creative | ?[quest ad creative](#quest-ad-creative-structure) object | The advertisement creative to show to the user |
| ad_identifiers? | [quest ad identifiers](#quest-ad-identifiers-structure) object | The advertisement identifiers for the delivered quest |
| ad_context? | [quest ad context](#quest-ad-context-structure) object | The advertisement context for the delivered quest |
| response_ttl_seconds? | integer | How long the response should be cached, in seconds |
| metadata_sealed? | ?string | Sealed metadata for the advertisement |
| traffic_metadata_sealed? | ?string | Sealed traffic metadata for the advertisement |
###### Quest Ad Creative Structure
| Field | Type | Description |
| ---------------- | ----------------- | ------------------------------------------------------- |
| creative_type | integer | The [type of advertisement creative](#ad-creative-type) |
| creative_content | object | The creative content; shape depends on `creative_type` |
| starts_at | ISO8601 timestamp | When the creative starts being available |
| ends_at | ISO8601 timestamp | When the creative stops being available |
###### Ad Creative Type
| Value | Name | Description |
| ----- | --------------- | ------------------------------------------------------------------------------------------------ |
| 1 | QUEST | The creative content is a [quest config](#quest-config-object) object |
| 2 | QUEST_HOME_HERO | The creative content is a [quest home hero creative](#quest-home-hero-creative-structure) object |
| 3 | BOUNTY | The creative content is a [quest bounty creative](#quest-bounty-creative-structure) object |
###### Quest Home Hero Creative Structure
| Field | Type | Description |
| ---------------------- | ---------------------------------------------------------------- | -------------------------------------- |
| id | snowflake | The ID of the quest home hero creative |
| label_title | string | The hero title |
| label_subtitle? | string | The hero subtitle |
| hero_image | string | The hero image asset |
| hero_video? | string | The hero video asset |
| sponsor_image? | string | The sponsor image asset |
| cta | [quest creative CTA](#quest-creative-cta-structure) object | The hero CTA |
| quest_ids? | array[snowflake] | The quests represented by the hero |
| quest_home_entrypoint? | [quest home entrypoint](#quest-home-entrypoint-structure) object | Quest Home entrypoint metadata |
| shelf_image? | string | The shelf image asset |
| shelf_video? | string | The shelf video asset |
###### Quest Bounty Creative Structure
| Field | Type | Description |
| --------------------- | ---------------------------------------------------------- | ---------------------------------------------------- |
| id | snowflake | The ID of the bounty creative |
| advertiser_name | string | The advertiser name |
| product_name? | string | The advertised product name |
| product_icon? | string | The advertised product icon asset |
| video_preview? | string | The preview video asset |
| image_preview? | string | The preview image asset |
| video_hls | string | The HLS video asset |
| cta | [quest creative CTA](#quest-creative-cta-structure) object | The bounty CTA |
| reward_timer_seconds? | integer | The number of seconds before a reward can be claimed |
###### Quest Creative CTA Structure
| Field | Type | Description |
| ------------ | ---------------------------------------------------------------------- | --------------------------- |
| url | string | The CTA URL |
| button_label | string | The CTA button label |
| android? | [Android quest CTA config](#android-quest-cta-config-structure) object | Android-specific CTA config |
| ios? | [iOS quest CTA config](#ios-quest-cta-config-structure) object | iOS-specific CTA config |
###### Quest Home Entrypoint Structure
| Field | Type | Description |
| ----------------- | ---------------------------------------------------------------------------------- | -------------------------- |
| linear_gradient? | [quest home entrypoint gradient](#quest-home-entrypoint-gradient-structure) object | The linear gradient |
| radial_gradient? | [quest home entrypoint gradient](#quest-home-entrypoint-gradient-structure) object | The radial gradient |
| gradient_preset? | integer | The gradient preset |
| image? | string | The entrypoint image asset |
| tooltip_image? | string | The tooltip image asset |
| tooltip_title? | string | The tooltip title |
| tooltip_subtitle? | string | The tooltip subtitle |
###### Quest Home Entrypoint Gradient Structure
| Field | Type | Description |
| ----- | ------ | ------------------------ |
| start | string | The gradient start color |
| end | string | The gradient end color |
Get Earned Quest Placement
Returns the earned quests that should be shown to the user in a specific content area.
###### Query String Params
| Field | Type | Description |
| -------------------------------- | ------------- | ------------------------------------------------------------------------------ |
| quest_ids | array[string] | Quest IDs to evaluate (1-20) |
| content | integer | The [content location](#quest-content-type) to get earned quests for |
| client_heartbeat_session_id? ^1^ | string | A client-generated UUID representing the current persisted analytics heartbeat |
^1^ This value is also sent in the [client properties](/reference#client-properties).
###### Response Body
| Field | Type | Description |
| --------------------- | ---------------------------------------------- | -------------------------------------------------- |
| quests | map[snowflake, ?[quest](#quest-object) object] | The earned quests, keyed by quest ID |
| response_ttl_seconds? | integer | How long the response should be cached, in seconds |
| request_id? | ?string | The advertisement decision request ID |
Get Quest Decisions
Returns one or more quest advertisement decisions for a placement.
###### Query String Params
| Field | Type | Description |
| -------------------------------- | ------- | ------------------------------------------------------------------------------ |
| placement | integer | The [quest placement area](#quest-placement-area) to get decisions for |
| num_decisions_requested | integer | The number of decisions to request (1-15) |
| client_heartbeat_session_id? ^1^ | string | A client-generated UUID representing the current persisted analytics heartbeat |
| client_ad_session_id? ^2^ | string | A client-generated UUID representing the current ad attribution session |
^1^ This value is also sent in the [client properties](/reference#client-properties).
^2^ This value is used to correlate ad decision requests, ad heartbeat events, and follow-up actions. Clients should reuse an ad session until it has been idle for 30 minutes or active for 12 hours.
###### Response Body
| Field | Type | Description |
| ---------- | --------------------------------------------------------------- | ------------------------------------- |
| request_id | string | The advertisement decision request ID |
| decisions | array[[quest ad decision](#quest-ad-decision-structure) object] | The advertisement decisions |
Get Quest Creative Preview
Returns quest advertisement decisions for specific advertisement creatives.
This endpoint is only available to authorized quests previewers.
###### Query String Params
| Field | Type | Description |
| --------------- | ---------------- | ------------------------------ |
| ad_creative_ids | array[snowflake] | The advertisement creative IDs |
###### Response Body
| Field | Type | Description |
| ---------- | --------------------------------------------------------------- | ------------------------------------- |
| request_id | string | The advertisement decision request ID |
| decisions | array[[quest ad decision](#quest-ad-decision-structure) object] | The advertisement decisions |
Accept Quest
Accepts a quest and returns a [quest user status](#quest-user-status-object) object. Fires a [Quests User Status Update](/gateway/gateway-events#quests-user-status-update) Gateway event.
###### JSON Params
| Field | Type | Description |
| ------------------------ | ------- | -------------------------------------------------------------------------- |
| location | integer | The [content location](#quest-content-type) where the action was initiated |
| metadata_sealed? | ?string | Sealed metadata for the advertisement decision |
| traffic_metadata_sealed? | ?string | Sealed traffic metadata for the advertisement decision |
Claim Quest Reward
Claims the quest's rewards, setting the `completed_at` and `claimed_at` fields of the [quest user status](#quest-user-status-object) to the current timestamp.
Fires a [Quests User Status Update](/gateway/gateway-events#quests-user-status-update) Gateway event.
###### JSON Params
| Field | Type | Description |
| ------------------------ | ------- | -------------------------------------------------------------------------- |
| location | integer | The [content location](#quest-content-type) where the action was initiated |
| platform | integer | The [platform](#quest-platform-type) to claim the reward for |
| metadata_sealed? | ?string | Sealed metadata for the advertisement decision |
| traffic_metadata_sealed? | ?string | Sealed traffic metadata for the advertisement decision |
###### Response Body
| Field | Type | Description |
| ------------------------------- | ---------------------------------------------------------------------------------------------------- | ------------------------------------------------- |
| claimed_at | ?ISO8601 timestamp | When the rewards were claimed |
| entitlement_expiration_metadata | map[snowflake, [entitlement expiration metadata](#entitlement-expiration-metadata-structure) object] | The expiration metadata for each entitlement |
| entitlements | array[[entitlement](/resources/entitlement#entitlement-object) object] | The entitlements the user received |
| errors | array[[JSON error](/topics/errors#json) object] | The errors that occured while claiming the reward |
###### Entitlement Expiration Metadata Structure
| Field | Type | Description |
| ---------- | ------- | ---------------------------------------------------------------------------------- |
| extended | boolean | Whether the entitlement expiration has been extended due to a premium subscription |
| extendable | boolean | Whether the entitlement expiration can be extended due to a premium subscription |
###### Example Response
```json
{
"claimed_at": "2024-04-17T23:30:41.000321+00:00",
"entitlement_expiration_metadata": {
"1230299425620885624": {
"extended": false,
"extendable": true
}
},
"entitlements": [
{
"id": "1230299425620885624",
"sku_id": "1226939756617793606",
"application_id": "1242265603276800000",
"user_id": "222069018507345921",
"deleted": false,
"starts_at": null,
"ends_at": null,
"type": 10,
"tenant_metadata": {},
"gift_code_flags": 0,
"promotion_id": null
}
],
"errors": []
}
```
Claim Quest Creative Reward
Claims the reward for a quest advertisement creative. Returns a 204 empty response on success.
###### JSON Params
| Field | Type | Description |
| -------------------------------- | ------- | ------------------------------------------------------------------------------ |
| decision_metadata_sealed? | ?string | Sealed metadata for the advertisement decision |
| traffic_metadata_sealed? | ?string | Sealed traffic metadata for the advertisement decision |
| client_heartbeat_session_id? ^1^ | string | A client-generated UUID representing the current persisted analytics heartbeat |
| client_ad_session_id? ^2^ | string | A client-generated UUID representing the current ad attribution session |
^1^ This value is also sent in the [client properties](/reference#client-properties).
^2^ This value is used to correlate ad decision requests, ad heartbeat events, and follow-up actions. Clients should reuse an ad session until it has been idle for 30 minutes or active for 12 hours.
Get Quest Reward Code
Retrieves the current user's claimed reward code. Returns a [quest reward code](#quest-reward-code-object) object on success.
Send Quest Heartbeat
Tells the server to update the `value` and `heartbeat` fields of the current task. Used for keeping track of how long the stream has been running for, and for checking if the user has met the [task duration requirement](#quest-task-structure).
Returns a [quest user status](#quest-user-status-object) object on success. Fires a [Quests User Status Update](/gateway/gateway-events#quests-user-status-update) Gateway event.
The `value` field within the [quest task progress](#quest-task-progress-structure) object is incremented by the amount of seconds since the last heartbeat request, up to 2 minutes at once.
Heartbeated quest tasks may only be completed from desktop clients. If the requesting user-agent does not include electron version info (e.g. `Electron/28.2.10`), the request will fail with a 401 unauthorized error.
###### JSON Params
| Field | Type | Description |
| ----------------------- | --------- | ------------------------------------------------------------------------------------------------------------------------------------------- |
| stream_key? ^1^ | string | The [encoded key of the stream](/gateway/gateway-events#stream-key) (e.g `guild:169256939211980800:1050497861969793164:222069018507345921`) |
| application_id? | snowflake | The ID of the application being played |
| terminal? | boolean | Whether this is the last heartbeat in the sequence (default false) |
| executable_path? | ?string | The executable path for the detected game |
| executable_fingerprint? | ?string | The executable fingerprint for the detected game |
^1^ Only required for stream quests.
Send Quest Video Progress
Tells the server to update the `value` field of the current video task. Used for keeping track of how long the video has been watched for, and for checking if the user has met the [task duration requirement](#quest-task-structure).
Returns a [quest user status](#quest-user-status-object) object on success. Fires a [Quests User Status Update](/gateway/gateway-events#quests-user-status-update) Gateway event.
Quest video progress should be submitted in small intervals (e.g. every 10-15 seconds a video plays).
###### JSON Params
| Field | Type | Description |
| --------- | ------- | ----------------------------------------------- |
| timestamp | integer | How far into the video the user is (in seconds) |
Start Console Quest
Starts completing a quest on console. Fires a [Quests User Status Update](/gateway/gateway-events#quests-user-status-update) Gateway event.
###### Query String Params
| Field | Type | Description |
| -------- | ------- | ---------------------------------------------------- |
| preview? | boolean | Whether the quest is in preview mode (default false) |
###### Response Body
| Field | Type | Description |
| ----------------- | -------------------------------------------------------------- | ------------------------------------------------- |
| started | boolean | Whether the quest was successfully started |
| quest_user_status | ?[quest user status](#quest-user-status-object) object | The user's quest progress |
| error_hints | ?array[string] | The errors that occurred while starting the quest |
| error_hints_v2 | ?array[[quest error hint](#quest-error-hint-structure) object] | The errors that occurred while starting the quest |
###### Quest Error Hint Structure
| Field | Type | Description |
| ---------------------- | --------- | ------------------------------------------------------------------------------------------------------------ |
| type | string | The type of error |
| message | string | The error message |
| connected_account_id | snowflake | The ID of the [connection](/resources/connected-accounts#connection-object) the console account is linked to |
| connected_account_type | string | The type of [connection](/resources/connected-accounts#connection-object) the console account is linked to |
###### Example Response
```json
{
"started": false,
"quest_user_status": null,
"error_hints": ["Xbox account DiscordGamer seems to be offline."],
"error_hints_v2": [
{
"type": "no_game_offline",
"message": "Xbox account DiscordGamer seems to be offline.",
"connected_account_id": "3076467402341699",
"connected_account_type": "xbox"
}
]
}
```
Stop Console Quest
Stops completing a quest on console. Returns a 204 empty response on success. Fires a [Quests User Status Update](/gateway/gateway-events#quests-user-status-update) Gateway event.
Complete Quest
Forcefully completes the quest for the current user. Returns a [quest user status](#quest-user-status-object) object. Fires a [Quests User Status Update](/gateway/gateway-events#quests-user-status-update) Gateway event.
This endpoint is only available to authorized quests previewers.
Reset Quest
Resets the quest's status for the current user. Returns a [quest user status](#quest-user-status-object) object. Fires a [Quests User Status Update](/gateway/gateway-events#quests-user-status-update) Gateway event.
This endpoint is only available to authorized quests previewers.
Reset Recent Quest Completions
Clears recent quest completion tracking for the current user. Returns a 204 empty response on success.
This endpoint is only available to Discord employees.
Dismiss Quest Content
Dismisses the specified [quest content area](#quest-content-type) for the current user. Not all content areas can be dismissed.
Returns a [quest user status](#quest-user-status-object) object. Fires a [Quests User Status Update](/gateway/gateway-events#quests-user-status-update) Gateway event.
Reset Quest Dismissibility
Resets the dismissibility of the quest's content areas for the current user (sets the [`dismissed_quest_content` field](#quest-user-status-object) to 0).
Returns a [quest user status](#quest-user-status-object) object. Fires a [Quests User Status Update](/gateway/gateway-events#quests-user-status-update) Gateway event.
This endpoint is only available to authorized quests previewers.
---
# Components
Link: https://docs.discord.food/resources/components
This document serves as a comprehensive reference for all available components. It covers three main categories:
- **Layout Components** - For organizing and structuring content (Action Rows, Sections, Containers)
- **Content Components** - For displaying static text, images, and files (Text Display, Media Gallery, Thumbnails)
- **Interactive Components** - For user interactions (Buttons, Select Menus, Text Input)
To use these components, you need to send the [`IS_COMPONENTS_V2` message flag](/resources/message#message-flags), which can be sent on a per-message basis. Once a message has been sent with this flag, it can't be removed from the message. This enables the new components system with the following changes:
- The `content` and `embeds` fields will no longer work, but you'll be able to use [Text Display](#text-display) and [Container](#container) as replacements
- Attachments won't show by default—they must be exposed through components
- The `poll` and `stickers` fields are disabled
- Messages allow up to 40 total components
- The combined length of all text across all components cannot exceed 4000 characters
## What is a Component
Components allow you to style and structure your messages, modals, and interactions. They are interactive elements that can create rich user experiences in your Discord integrations.
Components are a field on the [message object](/resources/message#message-object) and in modals. You can use them when creating messages or responding to an interaction, like an [application command](/interactions/application-commands).
## Legacy Message Component Behavior
Before the introduction of the `IS_COMPONENTS_V2` flag, message components were sent in conjunction with message content.
This means that you could send a message using a subset of the available components without setting the `IS_COMPONENTS_V2` flag, and the components would be included in the message content along with `content` and `embeds`.
Additionally, components of messages preceding components v2 will contain an `id` of `0`.
## Component Object
###### Component Type
| Value | Name | Description | Style | Usage |
| ----- | ------------------------------------------------------- | -------------------------------------------------------------- | ----------- | ------------------------------- |
| 1 | [ACTION_ROW](#action-row) | A container for other components | Layout | Message, Modal **(deprecated)** |
| 2 | [BUTTON](#button) | A button object | Interactive | Message |
| 3 | [STRING_SELECT](#string-select) | Select menu for picking from defined text options | Interactive | Message, Modal |
| 4 | [TEXT_INPUT](#text-input) | Text input object | Interactive | Modal |
| 5 | [USER_SELECT](#user-select) | Select menu for users | Interactive | Message, Modal |
| 6 | [ROLE_SELECT](#role-select) | Select menu for roles | Interactive | Message, Modal |
| 7 | [MENTIONABLE_SELECT](#mentionable-select) | Select menu for mentionables (users _and_ roles) | Interactive | Message, Modal |
| 8 | [CHANNEL_SELECT](#channel-select) | Select menu for channels | Interactive | Message, Modal |
| 9 | [SECTION](#section) ^1^ | Container to display text alongside an accessory component | Layout | Message |
| 10 | [TEXT_DISPLAY](#text-display) ^1^ | Markdown text | Content | Message, Modal |
| 11 | [THUMBNAIL](#thumbnail) ^1^ | Small image that can be used as an accessory | Content | Message |
| 12 | [MEDIA_GALLERY](#media-gallery) ^1^ | Display images and other media | Content | Message |
| 13 | [FILE](#file) ^1^ | Displays an attached file | Content | Message |
| 14 | [SEPARATOR](#separator) ^1^ | Component to add vertical padding between other components | Layout | Message |
| 16 | [CONTENT_INVENTORY_ENTRY](#content-inventory-entry) ^2^ | Displays an activity feed entry | Content | Message |
| 17 | [CONTAINER](#container) ^1^ | Container that visually groups a set of components | Layout | Message |
| 18 | [LABEL](#label) | Container associating a label and description with a component | Layout | Modal |
| 19 | [FILE_UPLOAD](#file-upload) | Component to upload one or more files | Interactive | Modal |
| 20 | [CHECKPOINT_CARD](#checkpoint-card) ^2^ | Displays a [checkpoint](/resources/checkpoint) | Content | Message |
| 21 | [RADIO_GROUP](#radio-group) | Single-choice set of radio options | Interactive | Modal |
| 22 | [CHECKBOX_GROUP](#checkbox-group) | Multi-select group of checkboxes | Interactive | Modal |
| 23 | [CHECKBOX](#checkbox) | Single checkbox for binary choice | Interactive | Modal |
^1^ Requires the [`IS_COMPONENTS_V2` message flag](/resources/message#message-flags).
^2^ Not usable by bots.
###### Anatomy of a Component
All components have the following fields:
| Field | Type | Description |
| ----- | ------- | --------------------------------------------------------------- |
| type | integer | The [type](#component-type) of the component |
| id? | integer | 32-bit integer used as an optional identifier for the component |
The `id` field is optional and is used to identify components in the response from an interaction that aren't interactive components.
The `id` must be unique within the message and is generated sequentially if left empty. Generation of `id`s won't use another `id` that exists in the message if you have one defined for another component.
Sending components with an `id` of `0` is allowed but will be treated as empty and replaced by the API.
###### Custom ID
Additionally, interactive components like buttons and selects must have a `custom_id` field. The developer defines this field when sending the component payload, and it is returned in the interaction payload sent when a user interacts with the component.
For example, if you set `custom_id: click_me` on a button, you'll receive an interaction containing `custom_id: click_me` when a user clicks that button.
`custom_id` is only available on interactive components and must be unique per component. Multiple components on the same message must not share the same `custom_id`. This field is a string of a maximum of 100 characters and can be used flexibly to maintain state or pass through other important data.
| Field | Type | Description |
| --------- | ------ | ----------------------------------------------- |
| custom_id | string | Developer-defined identifier (1-100 characters) |
### Action Row
An Action Row is a top-level layout component used in messages and modals.
Action Rows can contain:
- Up to 5 contextually grouped [buttons](#button)
- A single select component ([string select](#string-select), [user select](#user-select), [role select](#role-select), [mentionable select](#mentionable-select), or [channel select](#channel-select))
- A single [text input](#text-input) (in modals)
###### Action Row Structure
| Field | Type | Description |
| ---------- | -------------------------------------------- | ----------------------------------------------------------------------------------- |
| type | integer | Always [`ACTION_ROW`](#component-type) |
| id? | integer | An optional identifier for the component |
| components | array[[component](#component-object) object] | Up to 5 [button](#button) components or a single [select](#string-select) component |
###### Example Action Row
```json
{
"type": 1,
"components": [
{
"type": 2,
"label": "Accept",
"style": 1,
"custom_id": "click_yes"
},
{
"type": 2,
"label": "Learn More",
"style": 5,
"url": "http://watchanimeattheoffice.com/"
},
{
"type": 2,
"label": "Decline",
"style": 4,
"custom_id": "click_no"
}
]
}
```
### Button
A Button is an interactive component that can only be used in messages. It creates clickable elements that users can interact with, sending an [interaction](/interactions/receiving-and-responding#interaction-object) to your app when clicked.
Buttons must be placed inside an [Action Row](#action-row) or a [Section](#section)'s `accessory` field.
###### Button Structure
| Field | Type | Description |
| --------- | ----------------------------------------------------- | --------------------------------------------------------------------------------- |
| type | integer | Always [`BUTTON`](#component-type) |
| id? | integer | An optional identifier for the component |
| style | integer | A [button style](#button-style) |
| label? | string | Text that appears on the button (max 80 characters) |
| emoji? | partial [emoji](/resources/emoji#emoji-object) object | The emoji that appears on the button |
| custom_id | string | Developer-defined identifier for the button (1-100 characters) |
| sku_id? | snowflake | Identifier for a purchasable SKU, only available when using premium-style buttons |
| url? | string | URL for link-style buttons (max 512 characters) |
| disabled? | boolean | Whether the button is disabled (default false) |
Buttons come in various styles to convey different types of actions. These styles also define what fields are valid for a button.
- Non-link and non-premium buttons **must** have a `custom_id`, and cannot have a `url` or a `sku_id`.
- Link buttons **must** have a `url`, and cannot have a `custom_id`
- Link buttons do not send an [interaction](/interactions/receiving-and-responding#interaction-object) to your app when clicked
- Premium buttons **must** contain a `sku_id`, and cannot have a `custom_id`, `label`, `url`, or `emoji`.
- Premium buttons do not send an [interaction](/interactions/receiving-and-responding#interaction-object) to your app when clicked
###### Button Style
| Value | Name | Action | Required Field |
| ----- | --------- | -------------------------------------------------------------- | -------------- |
| 1 | PRIMARY | The most important or recommended action in a group of options | `custom_id` |
| 2 | SECONDARY | Alternative or supporting actions | `custom_id` |
| 3 | SUCCESS | Positive confirmation or completion actions | `custom_id` |
| 4 | DANGER | An action with irreversible consequences | `custom_id` |
| 5 | LINK | Navigates to a URL | `url` |
| 6 | PREMIUM | Purchase | `sku_id` |
###### Example Button
```json
{
"type": 1,
"components": [
{
"type": 2,
"label": "Click me!",
"style": 1,
"custom_id": "clicked_me"
}
]
}
```
#### Button Design Guidelines
###### General Button Content
- 34 characters max with icon or emoji.
- 38 characters max without icon or emoji.
###### Premium Buttons
Premium buttons will automatically have the following:
- Shop icon
- SKU name
- SKU price
### String Select
A String Select is an interactive component that allows users to select one or more provided `options` in a message.
String Selects can be configured for both single-select and multi-select behavior. When a user finishes making their choice(s) your app receives an [interaction](/interactions/receiving-and-responding#interaction-structure).
String Selects are available in messages and modals. They must be placed inside an [Action Row](#action-row) in messages and a [Label](#label) in modals.
###### String Select Structure
| Field | Type | Description |
| ------------- | ------------------------------------------------------- | ------------------------------------------------------------------- |
| type | integer | Always [`STRING_SELECT`](#component-type) |
| id? | integer | An optional identifier for the component |
| custom_id | string | Developer-defined identifier for the select menu (1-100 characters) |
| options | array[[select option](#select-option-structure) object] | Specified choices in a select menu (max 25) |
| placeholder? | string | Placeholder text if nothing is selected (max 150 characters) |
| min_values? | integer | Minimum number of items that must be chosen (max 25, default 1) |
| max_values? | integer | Maximum number of items that can be chosen (max 25, default 1) |
| required? ^1^ | boolean | Whether the component is required to be filled (default true) |
| disabled? ^2^ | boolean | Whether the select menu is disabled (default false) |
^1^ Only applicable within modals.
^2^ Cannot be set in modals.
###### Select Option Structure
| Field | Type | Description |
| ------------ | ----------------------------------------------------- | ------------------------------------------------------------------ |
| label | string | User-facing name of the option (max 100 characters) |
| value | string | Developer-defined value of the option (1-100 characters) |
| description? | string | Additional description of the option (max 100 characters) |
| emoji? | partial [emoji](/resources/emoji#emoji-object) object | Emoji to show next to the name |
| default? | boolean | Whether to show this option as selected by default (default false) |
###### Example String Select
```json
{
"type": 3,
"custom_id": "string_select",
"placeholder": "Favorite bug?",
"options": [
{
"label": "Ant",
"value": "ant",
"description": "(best option)",
"emoji": { "name": "🐜" }
},
{
"label": "Butterfly",
"value": "butterfly",
"emoji": { "name": "🦋" }
},
{
"label": "Catarpillar",
"value": "caterpillar",
"emoji": { "name": "🐛" }
}
]
}
```
### Text Input
Text Input is an interactive component that allows users to enter free-form text responses in modals. It supports both short, single-line inputs and longer, multi-line paragraph inputs.
Text Inputs can only be used within modals and must be placed inside an [Action Row](#action-row) or a [Label](#label).
Discord no longer recommends using Text Input within an [Action Row](#action-row) in modals. Going forward, all Text Inputs should be placed inside a [Label](#label) component.
###### Text Input Structure
| Field | Type | Description |
| -------------------------- | ------- | ------------------------------------------------------------------ |
| type | integer | Always [`TEXT_INPUT`](#component-type) |
| id? | integer | An optional identifier for the component |
| custom_id | string | Developer-defined identifier for the input (1-100 characters) |
| style | integer | The [text input style](#text-input-style) |
| label **(deprecated)** ^1^ | string | Label for this component (max 45 characters) |
| min_length? | integer | Minimum input length for a text input (max 4000) |
| max_length? | integer | Maximum input length for a text input (1-4000) |
| required? | boolean | Whether this component is required to be filled (default true) |
| value? | string | Prefilled value for the component (max 4000 characters) |
| placeholder? | string | Custom placeholder text if the input is empty (max 100 characters) |
^1^ Ignored within a [Label](#label) in favor of its `label` and `description` fields.
###### Text Input Style
| Value | Name | Description |
| ----- | --------- | ----------------- |
| 1 | SMALL | Single-line input |
| 2 | PARAGRAPH | Multi-line input |
###### Example Text Input
```json
{
"type": 1,
"components": [
{
"type": 4,
"custom_id": "name",
"label": "Name",
"style": 1,
"min_length": 1,
"max_length": 4000,
"placeholder": "John",
"required": true
}
]
}
```
### User Select
A User Select is an interactive component that allows users to select one or more users in a message. Options are automatically populated based on the guild's available users.
User Selects can be configured for both single-select and multi-select behavior. When a user finishes making their choice(s) your app receives an [interaction](/interactions/receiving-and-responding#interaction-structure).
User Selects are available in messages and modals. They must be placed inside an [Action Row](#action-row) in messages and a [Label](#label) in modals.
###### User Select Structure
| Field | Type | Description |
| --------------- | -------------------------------------------------------------- | ------------------------------------------------------------------- |
| type | integer | Always [`USER_SELECT`](#component-type) |
| id? | integer | An optional identifier for the component |
| custom_id | string | Developer-defined identifier for the select menu (1-100 characters) |
| placeholder? | string | Placeholder text if nothing is selected (max 150 characters) |
| default_values? | array[[default value](#select-default-value-structure) object] | Default values for auto-populated select menu components (max 25) |
| min_values? | integer | Minimum number of items that must be chosen (max 25, default 1) |
| max_values? | integer | Maximum number of items that can be chosen (max 25, default 1) |
| required? ^1^ | boolean | Whether the component is required to be filled (default true) |
| disabled? ^2^ | boolean | Whether the select menu is disabled (default false) |
^1^ Only applicable within modals.
^2^ Cannot be set in modals.
###### Select Default Value Structure
| Field | Type | Description |
| ----- | --------- | ------------------------------------ |
| id | snowflake | ID of a user, role, or channel |
| type | string | Type of value associated with the ID |
###### Example User Select
```json
{
"type": 1,
"components": [
{
"type": 5,
"custom_id": "user_select",
"placeholder": "Select a user"
}
]
}
```
### Role Select
A Role Select is an interactive component that allows users to select one or more roles in a message. Options are automatically populated based on the guild's available roles.
Role Selects can be configured for both single-select and multi-select behavior. When a user finishes making their choice(s) your app receives an [interaction](/interactions/receiving-and-responding#interaction-structure).
Role Selects are available in messages and modals. They must be placed inside an [Action Row](#action-row) in messages and a [Label](#label) in modals.
###### Role Select Structure
| Field | Type | Description |
| --------------- | -------------------------------------------------------------- | ------------------------------------------------------------------- |
| type | integer | Always [`ROLE_SELECT`](#component-type) |
| id? | integer | An optional identifier for the component |
| custom_id | string | Developer-defined identifier for the select menu (1-100 characters) |
| placeholder? | string | Placeholder text if nothing is selected (max 150 characters) |
| default_values? | array[[default value](#select-default-value-structure) object] | Default values for auto-populated select menu components (max 25) |
| min_values? | integer | Minimum number of items that must be chosen (max 25, default 1) |
| max_values? | integer | Maximum number of items that can be chosen (max 25, default 1) |
| required? ^1^ | boolean | Whether the component is required to be filled (default true) |
| disabled? ^2^ | boolean | Whether the select menu is disabled (default false) |
^1^ Only applicable within modals.
^2^ Cannot be set in modals.
###### Example Role Select
```json
{
"type": 1,
"components": [
{
"type": 6,
"custom_id": "role_select",
"placeholder": "Which roles?",
"min_values": 1,
"max_values": 3
}
]
}
```
### Mentionable Select
A Mentionable Select is an interactive component that allows users to select one or more mentionables in a message. Options are automatically populated based on available mentionables in the guild.
Mentionable Selects can be configured for both single-select and multi-select behavior. When a user finishes making their choice(s), your app receives an [interaction](/interactions/receiving-and-responding#interaction-structure).
Mentionable Selects are available in messages and modals. They must be placed inside an [Action Row](#action-row) in messages and a [Label](#label) in modals.
###### Mentionable Select Structure
| Field | Type | Description |
| --------------- | -------------------------------------------------------------- | ------------------------------------------------------------------- |
| type | integer | Always [`MENTIONABLE_SELECT`](#component-type) |
| id? | integer | An optional identifier for the component |
| custom_id | string | Developer-defined identifier for the select menu (1-100 characters) |
| placeholder? | string | Placeholder text if nothing is selected (max 150 characters) |
| default_values? | array[[default value](#select-default-value-structure) object] | Default values for auto-populated select menu components (max 25) |
| min_values? | integer | Minimum number of items that must be chosen (max 25, default 1) |
| max_values? | integer | Maximum number of items that can be chosen (max 25, default 1) |
| required? ^1^ | boolean | Whether the component is required to be filled (default true) |
| disabled? ^2^ | boolean | Whether the select menu is disabled (default false) |
^1^ Only applicable within modals.
^2^ Cannot be set in modals.
###### Example Mentionable Select
```json
{
"type": 1,
"components": [
{
"type": 7,
"custom_id": "mentionable_select",
"placeholder": "Who?"
}
]
}
```
### Channel Select
A Channel Select is an interactive component that allows users to select one or more channels in a message. Options are automatically populated based on available channels in the guild and can be filtered by channel types.
Channel Selects can be configured for both single-select and multi-select behavior. When a user finishes making their choice(s) your app receives an [interaction](/interactions/receiving-and-responding#interaction-structure).
Channel Selects are available in messages and modals. They must be placed inside an [Action Row](#action-row) in messages and a [Label](#label) in modals.
###### Channel Select Structure
| Field | Type | Description |
| --------------- | -------------------------------------------------------------- | ------------------------------------------------------------------------------------------- |
| type | integer | Always [`CHANNEL_SELECT`](#component-type) |
| id? | integer | An optional identifier for the component |
| custom_id | string | Developer-defined identifier for the select menu (1-100 characters) |
| channel_types? | array[integer] | [Channel types](/resources/channel#channel-type) to include in the channel select component |
| placeholder? | string | Placeholder text if nothing is selected (max 150 characters) |
| default_values? | array[[default value](#select-default-value-structure) object] | Default values for auto-populated select menu components (max 25) |
| min_values? | integer | Minimum number of items that must be chosen (max 25, default 1) |
| max_values? | integer | Maximum number of items that can be chosen (max 25, default 1) |
| required? ^1^ | boolean | Whether the component is required to be filled (default true) |
| disabled? ^2^ | boolean | Whether the select menu is disabled (default false) |
^1^ Only applicable within modals.
^2^ Cannot be set in modals.
###### Example Channel Select
```json
{
"type": 1,
"components": [
{
"type": 8,
"custom_id": "channel_select",
"channel_types": [0],
"placeholder": "Which text channel?"
}
]
}
```
### Section
A Section is a top-level layout component that allows you to join text contextually with an accessory.
Sections are only available in messages.
###### Section Structure
| Field | Type | Description |
| -------------- | ---------------------------------------------------------- | ---------------------------------------- |
| type | integer | Always [`SECTION`](#component-type) |
| id? | integer | An optional identifier for the component |
| components ^1^ | array[[text display component](#text-display) object] | Text components to display (1-3) |
| accessory ^1^ | [thumbnail](#thumbnail) object \| [button](#button) object | A thumbnail or a button component |
^1^ May be expanded to include other component types in the future.
###### Example Section
```json
{
"type": 9,
"components": [
{
"type": 10,
"content": "# Real Game v7.3"
},
{
"type": 10,
"content": "Hope you're excited, the update is finally here! Here are some of the changes:\n- Fixed a bug where certain treasure chests wouldn't open properly\n- Improved server stability during peak hours\n- Added a new type of gravity that will randomly apply when the moon is visible in-game\n- Every third thursday the furniture will scream your darkest secrets to nearby npcs"
},
{
"type": 10,
"content": "-# That last one wasn't real, but don't use voice chat near furniture just in case..."
}
],
"accessory": {
"type": 11,
"media": {
"url": "https://websitewithopensourceimages/gamepreview.png"
}
}
}
```
### Text Display
A Text Display is a top-level content component that allows you to add markdown formatted text, including mentions (users, roles, etc) and emoji.
The behavior of this component is extremely similar to the `content` field of a message, but allows you to add multiple text components, controlling the layout of your message.
When sent in a message, mentions (@user, @role, etc.) present in this component will ping and send notifications based on the value of [`allowed_mentions`](/resources/message#allowed-mentions-object) in the message.
###### Text Display Structure
| Field | Type | Description |
| ------- | ------- | -------------------------------------------------------------------- |
| type | integer | Always [`TEXT_DISPLAY`](#component-type) |
| id? | integer | An optional identifier for the component |
| content | string | Text that will be displayed similar to a message (1-4000 characters) |
### Thumbnail
A Thumbnail is a content component that is a small image only usable as an accessory in a [section](#section). The preview comes from an url or attachment through the [unfurled media item](#unfurled-media-item-object) structure.
Thumbnails are only available in messages as an accessory in a [section](#section).
###### Thumbnail Structure
| Field | Type | Description |
| ------------ | --------------------------------------------------------- | --------------------------------------------------------- |
| type | integer | Always [`THUMBNAIL`](#component-type) |
| id? | integer | An optional identifier for the component |
| media | [unfurled media item](#unfurled-media-item-object) object | A URL or attachment |
| description? | ?string | Alt text for the media (max 1024 characters) |
| spoiler? | boolean | Whether the thumbnail should be spoilered (default false) |
### Media Gallery
A Media Gallery is a top-level content component that allows you to display 1-10 media attachments in an organized gallery format. Each item can have optional descriptions and can be marked as spoilers.
Media Galleries are only available in messages.
###### Media Gallery Structure
| Field | Type | Description |
| ----- | ----------------------------------------------------------------- | ----------------------------------------- |
| type | integer | Always [`MEDIA_GALLERY`](#component-type) |
| id? | integer | Optional identifier for component |
| items | array[[media gallery item](#media-gallery-item-structure) object] | Items to display in the gallery (1-10) |
###### Media Gallery Item Structure
| Field | Type | Description |
| ------------ | --------------------------------------------------------- | ------------------------------------------------------- |
| media | [unfurled media item](#unfurled-media-item-object) object | A URL or attachment |
| description? | ?string | Alt text for the media (max 1024 characters) |
| spoiler? | boolean | Whether the media should be a spoilered (default false) |
###### Example Media Gallery
```json
{
"type": 12,
"items": [
{
"media": { "url": "https://livevideofeedconvertedtoimage/webcam1.png" },
"description": "An aerial view looking down on older industrial complex buildings. The main building is white with many windows and pipes running up the walls."
},
{
"media": { "url": "https://livevideofeedconvertedtoimage/webcam2.png" },
"description": "An aerial view of old broken buildings. Nature has begun to take root in the rooftops. A portion of the middle building's roof has collapsed inward. In the distant haze you can make out a far away city."
},
{
"media": { "url": "https://livevideofeedconvertedtoimage/webcam3.png" },
"description": "A street view of a downtown city. Prominently in photo are skyscrapers and a domed building"
}
]
}
```
### File
A File is a top-level component that allows you to display an uploaded file as an attachment to the message and reference it in the component. Each file component can only display 1 attached file, but you can upload multiple files and add them to different file components within your payload.
Files are only available in messages.
###### File Structure
| Field | Type | Description |
| -------- | --------------------------------------------------------- | ----------------------------------------------------- |
| type | integer | Always [`FILE`](#component-type) |
| id? | integer | An optional identifier for the component |
| file | [unfurled media item](#unfurled-media-item-object) object | The file attachment (does not support URLs) |
| spoiler? | boolean | Whether the media should be a spoiler (default false) |
| name ^1^ | string | The name of the file |
| size ^1^ | integer | The size of the file in bytes |
^1^ This field is received only and cannot be set.
###### Example File Component
```json
{
"type": 13,
"file": {
"url": "attachment://game.zip"
}
}
```
### Separator
A Separator is a top-level layout component that adds vertical padding and visual division between other components.
Separators are only available in messages.
###### Separator Structure
| Field | Type | Description |
| -------- | ------- | ---------------------------------------------------------------------------- |
| type | integer | Always [`SEPARATOR`](#component-type) |
| id? | integer | An optional identifier for the component |
| divider? | boolean | Whether a visual divider should be displayed in the component (default true) |
| spacing? | integer | [Size of separator padding](#separator-spacing-type) (default `SMALL`) |
###### Separator Spacing Type
| Value | Name | Description |
| ----- | ----- | --------------------------------------------------- |
| 1 | SMALL | 8px gap between elements, 16px with divider hidden |
| 2 | LARGE | 16px gap between elements, 32px with divider hidden |
###### Example Separator
```json
{
"type": 14,
"divider": true,
"spacing": 1
}
```
### Content Inventory Entry
A Content Inventory Entry is a top-level component that displays an activity feed entry.
Content Inventory Entries cannot be sent directly.
###### Content Inventory Entry Structure
| Field | Type | Description |
| ----------------------- | ----------------------------------------------------------------- | --------------------------------------------------- |
| type | integer | Always [`CONTENT_INVENTORY_ENTRY`](#component-type) |
| id? | integer | An optional identifier for the component |
| content_inventory_entry | [content inventory entry](#content-inventory-entry-object) object | Content inventory entry data |
###### Content Inventory Entry Object
| Field | Type | Description |
| ------------- | ------------------------------------------------------------------------- | -------------------------------------------------------------------------------------- |
| id | string | The ID of the entry as a snowflake when sent in guild or a string of numbers when DMed |
| author_id | snowflake | The ID of the user this entry is for |
| author_type | integer | The [type of author](#content-inventory-author-type) that created this entry |
| content_type | integer | [The type of content]](#content-inventory-content-type) |
| traits | array[[content inventory trait](#content-inventory-trait-object) object] | Contains info such as streak, marathon, and time |
| extra | [content inventory metadata](#content-inventory-metadata-object) object | Metadata, such as a game or song |
| participants? | array[snowflake] | The IDs of all users involved with this entry |
| expires_at? | ISO8601 timestamp | When this entry expires |
| ended_at? | ISO8601 timestamp | When this entry ended |
| started_at? | ISO8601 timestamp | When this entry started |
| original_id? | snowflake | ID of the entry |
| guild_id? | snowflake | Guild ID this entry happened in |
| channel_id? | snowflake | Channel ID this entry happened in |
| session_id? | snowflake | Session ID of this entry |
| signature | [content inventory signature](#content-inventory-signature-object) object | Signature metadata for validation |
###### Content Inventory Author Type
| Value | Name | Description |
| ----- | ----------------------- | ------------------------ |
| 0 | AUTHOR_TYPE_UNSPECIFIED | No author type specified |
| 1 | USER | A Discord user |
###### Content Inventory Content Type
| Value | Name | Description |
| ----- | ------------------------ | --------------------------------------------------- |
| 0 | CONTENT_TYPE_UNSPECIFIED | No content type specified |
| 1 | PLAYED_GAME | A game that was played |
| 2 | WATCHED_MEDIA | Media that was watched (e.g. Crunchyroll) |
| 3 | TOP_GAME | Top played game in the guild |
| 4 | LISTENED_MEDIA | Media that was listened to (e.g. Spotify) |
| 5 | LISTENED_SESSION | Media listening session (e.g. Spotify Listen Along) |
| 6 | TOP_ARTIST | Top listened artist in the guild |
| 7 | CUSTOM_STATUS | Custom status activity |
| 8 | LAUNCHED_ACTIVITY | Embedded activity |
| 9 | LEADERBOARD | Leaderboard entry (e.g. League of Legends) |
###### Content Inventory Trait Object
| Field | Type | Description |
| ------------------------ | ----------------- | ------------------------------------------------------------------------------------------- |
| type | integer | The [type of trait](#content-inventory-trait-type) |
| first_time? | boolean | Shows the "New player" text (only `FIRST_TIME`) |
| duration_seconds? | integer | Total time elapsed during the entry (only `DURATION_SECONDS`) |
| is_live? | boolean | Whether the entry is still ongoing (only `IS_LIVE`) |
| range? | integer | [Time range](#content-inventory-aggregate-range-type) (only `AGGREGATE_RANGE`) |
| resurrected_last_played? | ISO8601 timestamp | When the game for the entry was last played (only `RESURRECTED`) |
| marathon? | boolean | Shows the "#h marathon" text (only `MARATHON`) |
| streak_count_days? | integer | Number of days for the streak text (only `STREAK_DAYS`) |
| trending? | integer | The [trending type](#content-inventory-trending-type) (only `TRENDING_CONTENT`) |
| count? | integer | Total count (only `TOP_ITEM_TOTAL_COUNT`, `TOP_PARENT_ITEM_TOTAL_COUNT`, `AGGREGATE_COUNT`) |
###### Content Inventory Trait Type
| Value | Name | Description |
| ----- | --------------------------- | ------------------------------------------------------------------------------- |
| 0 | TRAIT_TYPE_UNSPECIFIED | No trait type specified |
| 1 | FIRST_TIME | First time the content was played |
| 2 | DURATION_SECONDS | Total duration in seconds |
| 3 | IS_LIVE | Whether the content is currently live |
| 4 | AGGREGATE_RANGE | Time range for the aggregated data |
| 5 | RESURRECTED | Whether the user is returning to content previously interacted with (e.g. game) |
| 6 | MARATHON | Whether the content is part of a marathon |
| 7 | NEW_RELEASE | Whether the content is a new release |
| 8 | STREAK_DAYS | Number of days in the streak |
| 9 | TRENDING_CONTENT | Whether the content is trending |
| 10 | TOP_ITEM_TOTAL_COUNT | Total count of the top item in the guild |
| 11 | TOP_PARENT_ITEM_TOTAL_COUNT | Total count of the top parent item in the guild |
| 12 | AGGREGATE_COUNT | Aggregate count of the content in the guild |
###### Content Inventory Aggregate Range Type
| Value | Name | Description |
| ----- | --------------------------- | ---------------------------- |
| 0 | AGGREGATE_RANGE_UNSPECIFIED | No aggregate range specified |
| 1 | WEEK | Last 7 days of data |
###### Content Inventory Trending Type
| Value | Name | Description |
| ----- | ------------------------- | -------------------------- |
| 0 | TRENDING_TYPE_UNSPECIFIED | No trending type specified |
| 1 | GLOBAL | Global trending content |
###### Content Inventory Metadata Object
| Field | Type | Description |
| ------------------------- | ------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------ |
| type | string | [Metadata type](#content-inventory-metadata-type) |
| game_name? | string | The name of the game (`played_game_extra` only) |
| application_id? | snowflake | The ID of the associated application |
| platform? | integer | The [type of platform](#content-inventory-platform-type) (only `played_game_extra`) |
| last_update? | ISO8601 timestamp | When the entry was last updated |
| entries? | array[[metadata entry](#content-inventory-metadata-entry-object) object] | Entries (only 1 for the component) |
| media? | [metadata entry](#content-inventory-metadata-entry-object) object | Metadata object of type `listened_media_extra` |
| provider? | integer | The [provider](#content-inventory-provider-type) of the media (only `listened_media_extra`) |
| media_type? | integer | The [type of media](#content-inventory-media-type) (only `listened_media_extra`) |
| parent_title? | string | The title of the media's parent (album title when `media_type` is `TRACK`) (only `listened_media_extra`) |
| title? | string | The title of the media (only `listened_media_extra`) |
| image_url? | string | Image for the media (e.g. album art) (only `listened_media_extra`) |
| artist? | [artist](#content-inventory-artist-object) object | Top listened artist (only `top_artist_extra`) |
| artists? | array[[artist](#content-inventory-artist-object) object] | Artists for the media (empty when `top_artist_extra`) (only `listened_media_extra`) |
| external_id? | string | The external platform ID for the media (e.g. Spotify track ID) (only `listened_media_extra`) |
| external_parent_id? | string | The external platform ID for the media's parent (e.g. Spotify album ID) (only `listened_media_extra`) |
| media_assets_large_image? | string | The large image for the media (e.g. movie poster) (only `watched_media_extra`) |
| media_assets_large_text? | string | Text displayed when hovering over the large image (e.g. season and episode of a show) (only `watched_media_extra`) |
| media_assets_small_image? | string | Small image for the media (e.g. platform logo) (only `watched_media_extra`) |
| media_assets_small_text? | string | Text displayed when hovering over the small image (e.g. platform name) (only `watched_media_extra`) |
| media_title? | string | The title of the media (only `watched_media_extra`) |
| media_subtitle? | string | The subtitle of the media (only `watched_media_extra`) |
| url? | string | The URL of the media (only `watched_media_extra`) |
| activity_name? | string | The name of the activity (only `launched_activity_extra`) |
###### Content Inventory Metadata Type
| Value | Description |
| ----------------------- | ----------------------------------- |
| played_game_extra | Game |
| listened_session_extra | Listened session (e.g. Spotify) |
| listened_media_extra | Listened media (e.g. Spotify track) |
| top_artist_extra | Top artist (e.g. Spotify) |
| watched_media_extra | Watched media (e.g. Crunchyroll) |
| launched_activity_extra | Embedded activity |
###### Content Inventory Provider Type
| Value | Name | Description |
| ----- | -------------------- | --------------------- |
| 0 | PROVIDER_UNSPECIFIED | No provider specified |
| 1 | SPOTIFY | Spotify |
###### Content Inventory Media Type
| Value | Name | Description |
| ----- | ---------- | ---------------------------------------- |
| 0 | TOP_ARTIST | Top artist in the guild |
| 1 | TRACK | Track in a media provider (e.g. Spotify) |
###### Content Inventory Metadata Entry Object
| Field | Type | Description |
| ------------------- | ----------------------------------------------------- | --------------------------------------------------- |
| media? | [metadata](#content-inventory-metadata-object) object | Metadata object of type `listened_media_extra` |
| verification_state? | integer | |
| repeat_count? | integer | How many times this track has been played on repeat |
###### Content Inventory Artist Object
| Field | Type | Description |
| ----------- | ------ | ----------------------------------------------------------------- |
| external_id | string | The external platform ID for this artist (e.g. Spotify artist ID) |
| name | string | The ame of the artist |
###### Content Inventory Platform Type
| Value | Name | Description |
| ----- | ----------- | ----------------------- |
| 0 | DESKTOP | Desktop |
| 1 | XBOX | Xbox integration |
| 2 | PLAYSTATION | PlayStation integration |
| 3 | IOS | iOS |
| 4 | ANDROID | Android |
| 5 | NINTENDO | Nintendo integration |
| 6 | LINUX | Linux |
| 7 | MACOS | macOS |
###### Content Inventory Signature Object
| Field | Type | Description |
| --------- | ------- | ------------------------------- |
| signature | string | SHA256 hash of the entry |
| kid | string | Key ID for the signature |
| version | integer | Signature version (currently 1) |
###### Example Content Inventory Entry
```json
{
"type": 16,
"id": "0",
"content_inventory_entry": {
"author_id": "150745989836308480",
"author_type": 1,
"content_type": 1,
"ended_at": "2025-04-23T02:13:18.123000+00:00",
"extra": {
"application_id": "356879032584896512",
"game_name": "Garry's Mod",
"platform": 0,
"type": "played_game_extra"
},
"id": "1364423860543557746",
"participants": ["150745989836308480"],
"signature": {
"kid": "AtDT4Kx25Wmu5cfllPxAiwZKgPbmLsaeHitpx/duvPY=",
"signature": "580e54d406bc466a936cbd9a1b8f19954997187d56638c84871cc5f3cd9c245b",
"version": 1
},
"started_at": "2025-04-23T02:11:24.123000+00:00",
"traits": [
{
"duration_seconds": 114,
"type": 2
},
{
"streak_count_days": 3,
"type": 8
}
]
}
}
```
### Container
A Container is a top-level layout component that holds up to 10 components. Containers are visually distinct from surrounding components and have an optional customizable color bar.
Containers are only available in messages.
###### Container Structure
| Field | Type | Description |
| ------------- | -------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| type | integer | Always [`CONTAINER`](#component-type) |
| id? | integer | An optional identifier for the component |
| components | array[[component](#component-object) object] | Components of the type [action row](#action-row), [text display](#text-display), [section](#section), [media gallery](#media-gallery), [separator](#separator), or [file](#file) (1-10) |
| accent_color? | ?integer | Color for the accent on the container encoded as an integer representation of a hexadecimal color code |
| spoiler? | boolean | Whether the container should be spoilered (default false) |
###### Example Container
```json
{
"type": 17,
"accent_color": 703487,
"components": [
{
"type": 10,
"content": "# You have encountered a wild coyote!"
},
{
"type": 12,
"items": [
{
"media": { "url": "https://websitewithopensourceimages/coyote.png" }
}
]
},
{
"type": 10,
"content": "What would you like to do?"
},
{
"type": 1,
"components": [
{
"type": 2,
"custom_id": "pet_coyote",
"label": "Pet it!",
"style": 1
},
{
"type": 2,
"custom_id": "feed_coyote",
"label": "Attempt to feed it",
"style": 2
},
{
"type": 2,
"custom_id": "run_away",
"label": "Run away!",
"style": 4
}
]
}
]
}
```
### Label
A Label is a top-level layout component. Labels wrap modal components with text as a label and optional description.
The description may display above or below the component depending on platform.
###### Label Structure
| Field | Type | Description |
| ------------ | ------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| type | integer | Always [`LABEL`](#component-type) |
| id? | integer | An optional identifier for the component |
| label | string | The label text (max 45 characters) |
| description? | string | An optional description text for the label (max 100 characters) |
| component | [component](#component-object) object | Inner component of the type [string select](#string-select), [text input](#text-input), [user select](#user-select), [role select](#role-select), [mentionable select](#mentionable-select), [channel select](#channel-select), [file upload](#file-upload), [radio group](#radio-group), [checkbox group](#checkbox-group), or [checkbox](#checkbox) |
### File Upload
File Upload is an interactive component that allows users to upload up to 10 files in modals.
File Uploads can only be used within modals and must be placed inside a [Label](#label).
###### File Upload Structure
| Field | Type | Description |
| --------------- | ----------------------------------------- | ------------------------------------------------------------------- |
| type | integer | Always [`FILE_UPLOAD`](#component-type) |
| id? | integer | An optional identifier for the component |
| custom_id | string | Developer-defined identifier for the file upload (1-100 characters) |
| min_values? | integer | Minimum number of items that must be uploaded (max 10, default 0) |
| max_values? | integer | Maximum number of items that can be chosen (max 10, default 10) |
| required? | boolean | Whether the user must upload a file (default false) |
| file_types? ^1^ | array[[file type](/reference#file-types)] | The file types permitted to be uploaded (max 10) |
^1^ This field can only be set and is not received.
### Checkpoint Card
A Checkpoint Card is a top-level component that displays a summary of the user's [checkpoint](/resources/checkpoint).
Checkpoint cards cannot be sent directly.
###### Checkpoint Card Structure
| Field | Type | Description |
| --------------- | ---------------------------------------------------- | ------------------------------------------- |
| type | integer | Always [`CHECKPOINT_CARD`](#component-type) |
| id? | integer | An optional identifier for the component |
| checkpoint_data | [checkpoint data](#checkpoint-data-structure) object | Checkpoint data |
###### Checkpoint Data Structure
| Field | Type | Description |
| ---------------------- | ---------------------------------------------------------------- | ---------------------------------------------------------------------------------- |
| version | integer | The version of checkpoint cards |
| card_id | integer | The [type of checkpoint card](/resources/checkpoint#checkpoint-card-type) |
| power_level | float | A power level representing how active the user was on Discord |
| power_level_percentile | float | The power level expressed as a percentile |
| num_messages_sent | integer | Number of messages that the user during the year |
| total_voice_minutes | float | Duration in seconds how much time the user spent in voice channels during the year |
| num_emojis_sent | integer | Number of emojis that the user during the year (includes messages and reactions) |
| top_guild? | [checkpoint card guild](#checkpoint-card-guild-structure) object | The guild that the user have been participating the most in |
| top_emoji? | [checkpoint card emoji](#checkpoint-card-emoji-structure) object | The emoji that the user used the most |
| top_game? | [checkpoint card game](#checkpoint-card-game-structure) object | The game that the user have been played the most |
###### Checkpoint Card Guild Structure
| Field | Type | Description |
| ---------- | --------- | -------------------------------------------------- |
| guild_id | snowflake | The ID of the guild |
| guild_name | string | The name of the guild |
| guild_icon | ?string | The guild's [icon hash](/reference#cdn-formatting) |
###### Checkpoint Card Emoji Structure
| Field | Type | Description |
| ---------- | ---------- | ------------------------------------------ |
| emoji_id | ?snowflake | The ID of the guild's custom emoji |
| emoji_name | string | The unicode character or name of the emoji |
###### Checkpoint Card Game Structure
| Field | Type | Description |
| -------------------- | --------- | -------------------------------------------------------- |
| application_id | snowflake | The ID of the application |
| application_name | string | The name of the application |
| application_image_id | ?string | The application's [icon hash](/reference#cdn-formatting) |
###### Example Checkpoint Card
```json
{
"type": 20,
"id": 1,
"checkpoint_data": {
"version": 0,
"num_messages_sent": 53146,
"total_voice_minutes": 6.3231166666666665,
"num_emojis_sent": 13096,
"top_emoji": {
"emoji_id": "1145727546747535412",
"emoji_name": "blobcatcozy"
},
"top_guild": {
"guild_id": "1046920999469330512",
"guild_name": "Alien Network",
"guild_icon": "66b0f4d96c145970fa9d96ada8afadf3"
},
"top_game": {
"application_id": "363445589247131668",
"application_name": "Roblox",
"application_image_id": "f2b60e350a2097289b3b0b877495e55f"
},
"card_id": 5,
"power_level": 83732.32311666667,
"power_level_percentile": 96.71
}
}
```
### Radio Group
Radio Group is an interactive component for selecting exactly one option from a defined list.
Radio Groups can only be used within modals and must be placed inside a [Label](#label).
###### Radio Group Structure
| Field | Type | Description |
| --------- | ----------------------------------------------------------------- | ------------------------------------------------------------------- |
| type | integer | Always [`RADIO_GROUP`](#component-type) |
| id? | integer | An optional identifier for the component |
| custom_id | string | Developer-defined identifier for the radio group (1-100 characters) |
| options | array[[radio group option](#radio-group-option-structure) object] | Options to render (min 2, max 10) |
| required? | boolean | Whether the user must select an option (default true) |
###### Radio Group Option Structure
| Field | Type | Description |
| ------------ | ------- | ------------------------------------------------------------------ |
| value | string | Developer-defined value of the option (1-100 characters) |
| label | string | User-facing name of the option (max 100 characters) |
| description? | string | Additional description of the option (max 100 characters) |
| default? | boolean | Whether to show this option as selected by default (default false) |
### Checkbox Group
Checkbox Group is an interactive component for selecting one or many options via checkboxes.
Checkbox Groups can only be used within modals and must be placed inside a [Label](#label).
###### Checkbox Group Structure
| Field | Type | Description |
| ----------- | ----------------------------------------------------------------------- | ---------------------------------------------------------------------- |
| type | integer | Always [`CHECKBOX_GROUP`](#component-type) |
| id? | integer | An optional identifier for the component |
| custom_id | string | Developer-defined identifier for the checkbox group (1-100 characters) |
| options | array[[checkbox group option](#checkbox-group-option-structure) object] | Options to render (min 2, max 10) |
| min_values? | integer | Minimum number of boxes that must be checked (max 10, default 1) |
| max_values? | integer | Maximum number of boxes that can be checked (1-10) |
| required? | boolean | Whether the user must select an option (default true) |
###### Checkbox Group Option Structure
| Field | Type | Description |
| ------------ | ------- | ----------------------------------------------------------------- |
| value | string | Developer-defined value of the option (1-100 characters) |
| label | string | User-facing name of the option (max 100 characters) |
| description? | string | Additional description of the option (max 100 characters) |
| default? | boolean | Whether to show this option as checked by default (default false) |
### Checkbox
Checkbox is a single interactive component for simple yes/no style questions.
Checkboxes can only be used within modals and must be placed inside a [Label](#label).
###### Checkbox Structure
| Field | Type | Description |
| --------- | ------- | ---------------------------------------------------------------- |
| type | integer | Always [`CHECKBOX`](#component-type) |
| id? | integer | An optional identifier for the component |
| custom_id | string | Developer-defined identifier for the checkbox (1-100 characters) |
| default? | boolean | Whether the box is checked by default (default false) |
## Unfurled Media Item Object
###### Unfurled Media Item Object Structure
| Field | Type | Description |
| -------------------------- | ---------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------- |
| id? ^1^ | snowflake | The ID of the media item |
| url | string | The URL of the media, supports arbitrary URLs and `attachment://` references (max 2048 characters) |
| proxy_url? ^1^ | string | The proxied URL of the media item |
| height? ^1^ | ?integer | The height of the media item |
| width? ^1^ | ?integer | The width of the media item |
| flags? ^1^ | integer | The [media's attachment flags](/resources/message#attachment-flags) |
| content_type? ^1^ | string | The [media type](https://en.wikipedia.org/wiki/Media_type) of the content |
| content_scan_metadata? ^1^ | [content scan metadata](/resources/message#content-scan-metadata-structure) object | The content scan metadata for the media |
| placeholder_version? ^1^ | integer | The attachment placeholder protocol version (currently 1) |
| placeholder? ^1^ | string | A low-resolution [thumbhash](https://github.com/evanw/thumbhash) of the media, to display before it is loaded |
| loading_state? ^1^ | integer | The [loading state](#unfurled-media-item-loading-state) of the media item |
| attachment_id? ^1^ | snowflake | The ID of the uploaded attachment, if any |
^1^ This field is received only and cannot be set.
###### Unfurled Media Item Loading State
| Value | Name | Description |
| ----- | ---------------- | --------------------------------------- |
| 0 | UNKNOWN | Loading state is unknown |
| 1 | LOADING | Media item is currently loading |
| 2 | LOADED_SUCCESS | Media item has loaded successfully |
| 3 | LOADED_NOT_FOUND | Media item has loaded but was not found |
---
# Safety Hub
Link: https://docs.discord.food/resources/safety-hub
Safety Hub is a feature that provides users with information about their account's standing, trust & safety violations, and actions taken against them.
### Safety Hub Object
###### Safety Hub Structure
| Field | Type | Description |
| --------------------- | ------------------------------------------------------ | --------------------------------------------------------------- |
| classifications | array[[classification](#classification-object) object] | User infractions |
| guild_classifications | array[[classification](#classification-object) object] | Guild infractions |
| account_standing | [account standing](#account-standing-structure) object | Current standing of the user's account |
| is_dsa_eligible | boolean | Indicates if the user is eligible for DSA appeal |
| is_appeal_eligible | boolean | Indicates if the user is eligible to appeal any classifications |
| username | string | The username of the user |
| appeal_eligibility | array[integer] | [Appeal types](#appeal-eligibility) the user is eligible for |
###### Account Standing Structure
| Field | Type | Description |
| ----- | ------- | --------------------------------------------------------- |
| state | integer | Current [account standing state](#account-standing-state) |
###### Account Standing State
| Value | Name | Description |
| ----- | ------------ | --------------------------- |
| 100 | ALL_GOOD | Account is in good standing |
| 200 | LIMITED | Account is limited |
| 300 | VERY_LIMITED | Account is very limited |
| 400 | AT_RISK | Account is at risk |
| 500 | SUSPENDED | Account is suspended |
###### Appeal Eligibility
| Value | Name | Description |
| ----- | ------------------- | -------------------------------------------- |
| 1 | DSA_ELIGIBLE | User is eligible for DSA appeal |
| 2 | IN_APP_ELIGIBLE | User is eligible for in-app appeal |
| 3 | AGE_VERIFY_ELIGIBLE | User is eligible for age verification appeal |
### Classification Object
###### Classification Structure
| Field | Type | Description |
| ------------------------- | ----------------------------------------------------------- | ------------------------------------------------------------------ |
| id | snowflake | The ID of the classification |
| classification_type | integer | The [classification type](#classification-type) |
| description | string | A brief description of the classification |
| explainer_link | string | URL to a detailed explanation of the classification |
| actions | array[[action](#action-structure) object] | Actions taken as part of the classification |
| max_expiration_time | ?ISO8601 timestamp | When the classification will expire |
| flagged_content | array[[flagged content](#flagged-content-structure) object] | Content that was flagged as part of the classification |
| appeal_status? | [appeal status](#appeal-status-structure) object | Status of an appeal related to the classification |
| is_coppa ^1^ | boolean | Whether the classification is a COPPA violation |
| is_spam ^1^ | boolean | Whether the classification is a spam violation |
| appeal_ingestion_type ^1^ | integer | [How a nominal appeal should be submitted](#appeal-ingestion-type) |
| guild_metadata? ^2^ | [guild metadata](#guild-metadata-structure) object | Metadata related to the guild where the classification was applied |
^1^ Classifications that are marked as spam or COPPA violations cannot be appealed in-app.
^2^ Only present on guild classifications.
###### Action Structure
| Field | Type | Description |
| ------------ | ------------- | ----------------------------------------- |
| id | snowflake | The ID of the action |
| action_type | integer | The [type of action](#action-type) taken |
| descriptions | array[string] | Human-friendly descriptions of the action |
###### Action Type
| Value | Name | Description |
| ----- | --------------------------- | ---------------------------------------- |
| 0 | BAN | Permanent ban from the platform |
| 1 | TEMP_BAN | Temporary ban from the platform |
| 2 | GLOBAL_QUARANTINE | Global quarantine of the user |
| 3 | REQUIRE_VERIFICATION | User must verify their account |
| 4 | USER_WARNING | Warning issued to the user |
| 5 | USER_SPAMMER | User marked as a spammer |
| 6 | CHANNEL_SPAM | Channel marked for spam |
| 7 | MESSAGE_SPAM | Message marked as spam |
| 8 | DISABLE_SUSPICIOUS_ACTIVITY | Account disabled for suspicious activity |
| 9 | LIMITED_ACCESS | User has limited access to features |
| 10 | CHANNEL_SCHEDULE_DELETE | Channel scheduled for deletion |
| 11 | MESSAGE_CONTENT_REMOVAL | Message content removed |
| 12 | GUILD_DISABLE_INVITE | Guild invites disabled |
| 13 | USER_CONTENT_REMOVAL | User content removed |
| 14 | USER_USERNAME_MANGLED | Offending username was cleared |
| 15 | GUILD_LIMITED_ACCESS | Guild has limited access to features |
| 16 | USER_MESSAGE_REMOVAL | User's message has been removed |
| 20 | GUILD_DELETE | Guild has been deleted |
| 22 | USER_PROFILE_MANGLED | Offending profile was cleared |
###### Flagged Content Structure
| Field | Type | Description |
| ----------- | ---------------------------------------------------------------- | ------------------------------------------------ |
| type | string | The type of content (currently always `message`) |
| id | snowflake | The ID of the message that was flagged |
| content | string | The content that was flagged |
| attachments | array[[attachment](/resources/message#attachment-object) object] | Attachments related to the flagged content |
###### Appeal Status Structure
| Field | Type | Description |
| ------ | ------- | ---------------------------------------------- |
| status | integer | Current [status of the appeal](#appeal-status) |
###### Appeal Status
| Value | Name | Description |
| ----- | -------------------------- | --------------------------------------- |
| 1 | REVIEW_PENDING | Appeal pending |
| 2 | CLASSIFICATION_UPHELD | Appeal denied, classification remains |
| 3 | CLASSIFICATION_INVALIDATED | Appeal accepted, classification removed |
###### Guild Metadata Structure
| Field | Type | Description |
| ----------- | ------- | ----------------------------------------------------------------------- |
| name | string | The name of the guild |
| icon | ?string | The guild's [icon hash](/reference#cdn-formatting) |
| member_type | integer | [Type of member](#guild-member-type) associated with the classification |
###### Guild Member Type
| Value | Name | Description |
| ----- | ------ | ------------------ |
| 1 | OWNER | Owner of the guild |
| 2 | MEMBER | Regular member |
###### Classification Type
| Value | Name | Description |
| ----- | ------------------------------------ | --------------------------------------------------- |
| 1 | UNKNOWN | Classification type is unknown |
| 100 | UNSOLICITED_PORNOGRAPHY | Unsolicited pornography content |
| 200 | NONCONSENSUAL_PORNOGRAPHY | Non-consensual pornography content |
| 210 | GLORIFYING_VIOLENCE | Content glorifying violence |
| 220 | HATE_SPEECH | Hate speech content |
| 230 | CRACKED_ACCOUNTS | Content related to cracked accounts |
| 240 | ILLICIT_GOODS | Content related to illicit goods |
| 250 | SOCIAL_ENGINEERING | Content related to social engineering |
| 280 | CHILD_SAFETY | Content related to child safety |
| 290 | HARRASMENT_AND_BULLYING | Harrasment and bullying content |
| 310 | HARRASMENT_AND_BULLYING_2 | Harassment and bullying content |
| 320 | HATEFUL_CONDUCT | Hateful conduct |
| 390 | HARRASMENT_AND_BULLYING_3 | Harassment and bullying content |
| 600 | CHILD_SAFETY_2 | Content related to child safety |
| 650 | CHILD_SAFETY_3 | Content related to child safety |
| 711 | IMPERSONATION | User has been impersonating a different user |
| 720 | BAN_EVASION | User has been evading an account suspension |
| 3010 | MALICIOUS_CONDUCT | User has tried phishing someone |
| 3030 | SPAM | Spam content |
| 4000 | NONCONSENSUAL_ADULT_CONTENT | Content related to non-consensual adult content |
| 4010 | FRAUD | Fraudulent content |
| 4130 | DOXXING_GUILD_OWNER | User owned a doxxing content guild |
| 4140 | COPYRIGHT_INFRINGEMENT_GUILD_OWNER | User owned a copyright infringement content guild |
| 5010 | CHILD_SAFETY_4 | Content related to child safety |
| 5090 | CHILD_SELF_ENDANGERMENT | Content related to child self-harm |
| 5245 | HARASSMENT_AND_BULLYING_GUILD_MEMBER | User was in a harassment and bullying content guild |
| 5305 | DOXXING_GUILD_MEMBER | User was in a doxxing content guild |
| 5411 | UNDERAGE | User was banned for being underage |
| 5440 | COPYRIGHT_INFRINGEMENT_GUILD_MEMBER | User was in a copyright infringement content guild |
| 5485 | COPYRIGHT_INFRINGEMENT_3 | Copyright infringement content |
###### Appeal Ingestion Type
| Value | Name | Description |
| ----- | ---------- | ----------------------------------------------- |
| 0 | WEBFORM | Appeal should be submitted via webform |
| 1 | AGE_VERIFY | Appeal should be submitted via age verification |
| 2 | IN_APP | Appeal should be submitted in-app |
###### Appeal Ingestion Signal
| Value | Name | Description |
| ----- | -------------------- | ------------------------------------------------- |
| 0 | DIDNT_VIOLATE_POLICY | User believes they did not violate policy |
| 1 | TOO_STRICT_UNFAIR | User believes the action was too strict or unfair |
| 2 | DONT_AGREE_PENALTY | User does not agree with the penalty |
| 3 | SOMETHING_ELSE | User is appealing for a different reason |
### Safety Hub System Messages
As [embed field values](/resources/message#embed-field-structure) are strings, all below fields are serialized as strings, even if the type is specified as otherwise.
#### Safety Policy Notice
Sent by the official Discord account to notify a user that they have violated Discord's community guidelines.
###### Safety Policy Notice Embed Structure
| Field | Type | Description |
| ---------------------- | --------- | --------------------------------------------------------- |
| client_version_message | string | The message that appears if the client is too old |
| classification_id | snowflake | The classification ID associated with the notice |
| incident_time | float | Unix timestamp (in seconds) of when the incident occurred |
###### Example Safety Policy Notice Embed
```json
{
"type": "safety_policy_notice",
"title": "You broke Discord’s community guidelines",
"fields": [
{
"name": "client_version_message",
"value": "To see the details of this violation, please update the app or open Discord in your browser.",
"inline": false
},
{
"name": "classification_id",
"value": "1411751868690075770",
"inline": false
},
{
"name": "incident_time",
"value": "1756658274.0",
"inline": false
}
]
}
```
#### Safety System Notification
Sent by the official Discord account to notify a user about a safety-related issue.
###### Safety System Notification Embed Structure
| Field | Type | Description |
| ---------------------- | --------- | ------------------------------------------------------------------------------- |
| client_version_message | string | The message that appears if the client is too old |
| classification_id | snowflake | The classification ID associated with the notice |
| body | string | The content of the embed |
| icon_type | string | The icon to use in the embed |
| header | string | The header of the embed |
| timestamp | float | The Unix timestamp (in seconds) of when the incident occurred |
| theme | string | The theme of the embed (currently always `default`) |
| ctas | string | Comma-separated list of [CTAs to display](#safety-system-notification-cta-type) |
| learn_more_link? | string | Link for the "Learn More" CTA |
###### Safety System Notification CTA Type
| Value | Description |
| ----------------------- | -------------------------------- |
| learn_more_link | Learn more button will be shown |
| policy_violation_detail | See Details button will be shown |
###### Example Safety System Notification Embed
```json
{
"type": "safety_system_notification",
"title": "Important message from Discord regarding your account",
"fields": [
{
"name": "client_version_message",
"value": "To see the details of this notification, please update the app or open Discord in your browser.",
"inline": false
},
{
"name": "body",
"value": "We reviewed a violation regarding our minimum age requirements policy and determined it does not violate our community guidelines. We have removed this violation from your account.",
"inline": false
},
{
"name": "icon_type",
"value": "default",
"inline": false
},
{
"name": "header",
"value": "We have removed a violation from your account",
"inline": false
},
{
"name": "timestamp",
"value": "1756658765.703625",
"inline": false
},
{
"name": "theme",
"value": "default",
"inline": false
},
{
"name": "ctas",
"value": "learn_more_link",
"inline": false
},
{
"name": "learn_more_link",
"value": "https://support.discord.com/hc/articles/18210965981847-Discord-Warning-System",
"inline": false
},
{
"name": "classification_id",
"value": "1411751868690075770",
"inline": false
}
]
}
```
## Endpoints
Get User Safety Hub
Returns a [safety hub](#safety-hub-object) object for the current user.
Get Suspended User Safety Hub
Returns a [safety hub](#safety-hub-object) object for a suspended user.
###### JSON Params
| Field | Type | Description |
| ----- | ------ | ------------------------ |
| token | string | The suspended user token |
Request Classification Review
Requests a review for a specific classification ID.
###### JSON Params
| Field | Type | Description |
| ---------- | ------- | ---------------------------------------------------------- |
| signal | integer | The [appeal ingestion signal](#appeal-ingestion-signal) |
| user_input | string | Additional user input for the appeal (max 1000 characters) |
###### Response Body
| Field | Type | Description |
| --------- | --------- | -------------------- |
| appeal_id | snowflake | The ID of the appeal |
Request Classification Review for Suspended User
Requests a review for a specific classification ID.
###### JSON Params
| Field | Type | Description |
| ---------- | ------- | ---------------------------------------------------------- |
| token | string | The suspended user token |
| signal | integer | The [appeal ingestion signal](#appeal-ingestion-signal) |
| user_input | string | Additional user input for the appeal (max 1000 characters) |
###### Response Body
| Field | Type | Description |
| --------- | --------- | -------------------- |
| appeal_id | snowflake | The ID of the appeal |
Check Age Verification for Suspended User
Checks if the suspended user has verified their age.
###### JSON Params
| Field | Type | Description |
| ----- | ------ | ------------------------ |
| token | string | The suspended user token |
###### Response Body
| Field | Type | Description |
| ------- | ------- | ------------------------------------------------ |
| success | boolean | Indicates if the age verification was successful |
Request Age Verification for Suspended User
Starts the age verification process using a third-party age verification provider. If the process is successful the user has their underage classifications invalidated.
###### JSON Params
| Field | Type | Description |
| ----------------------- | ---------- | ---------------------------------------------------- |
| token | string | The suspended user token |
| from_classification_id? | ?snowflake | The classification ID from which the request is made |
###### Response Body
| Field | Type | Description |
| ------------------------ | ------ | -------------------------------------------------------------------------- |
| verification_request_id | string | UUID generated by the server to track the current age verification request |
| verification_vendor_name | string | The third party age verification provider (currently always `K_ID`) |
| verification_webview_url | string | The webview URL to iframe into the client |
---
# Guild Analytics
Link: https://docs.discord.food/resources/guild-analytics
Insights are a data monitoring and analytics tool that Discord provides to help community managers understand their guild's performance and how their members are interacting with it.
For growth, activation, engagement, and channel following analytics, only data from the last 120 days are available for non-partner and non-verified guilds.
Audience and welcome screen analytics are based on members who visited the server in the last 28 days. Users who opted-out of analytics tracking will not show up in the data.
To protect user privacy, unless a given audience group has more than 50 members, it will not be shown as a distinct result and may be grouped into “Other.”
###### Query String Params
The following parameters are used in nearly all endpoints that return insights data.
| Field | Type | Description |
| -------- | ----------------- | ------------------------------------------------------ |
| start | ISO8601 timestamp | Start date for the insights data |
| end | ISO8601 timestamp | End date for the insights data |
| interval | integer | [The data aggregation interval](#aggregation-interval) |
###### Aggregation Interval
Certain data points may not be available for all aggregation intervals. If you request data for an interval that is not supported, the API will not return any data.
| Value | Name | Description |
| ----- | ------- | ----------------- |
| 0 | HOURLY | Aggregate hourly |
| 1 | DAILY | Aggregate daily |
| 2 | WEEKLY | Aggregate weekly |
| 3 | MONTHLY | Aggregate monthly |
## Endpoints
List Guild Growth Activation Overview
Returns a list of [growth activation overview](#growth-activation-overview-structure) objects representing general growth statistics per aggregation interval.
Accepts the [common query string parameters](#query-string-params) as described above.
###### Growth Activation Overview Structure
| Field | Type | Description |
| ----------------- | ----------------- | ------------------------------------------------------- |
| day_pt | ISO8601 timestamp | The interval the data represents |
| new_members | integer | The number of new members who joined the guild |
| new_communicators | integer | The number of new members who communicated in the guild |
List Guild Growth Activation Joins
Returns a list of [growth activation joins](#growth-activation-joins-structure) objects representing member join counts per aggregation interval.
Accepts the [common query string parameters](#query-string-params) as described above.
###### Growth Activation Joins Structure
| Field | Type | Description |
| --------------- | ----------------- | -------------------------------------------------------- |
| day_pt | ISO8601 timestamp | The interval the data represents |
| joins | integer | The number of users who joined the guild on this date |
| all_time_joins? | integer | The total number of users who have ever joined the guild |
List Guild Growth Activation Joins by Invite
Returns a list of [growth activation joins](#growth-activation-joins-by-invite-structure) objects representing specific invite join counts per aggregation interval.
Accepts the [common query string parameters](#query-string-params) as described above.
###### Growth Activation Joins by Invite Structure
| Field | Type | Description |
| ----------- | ----------------- | --------------------------------------------------------------- |
| day_pt | ISO8601 timestamp | The interval the data represents |
| invite_link | string | The invite link used to join the guild |
| joins | integer | The number of users who joined the guild using this invite link |
List Guild Growth Activation Joins by Referrer
Returns a list of [growth activation joins by referrer](#growth-activation-joins-by-referrer-structure) objects representing external referral join statistics per aggregation interval.
Accepts the [common query string parameters](#query-string-params) as described above.
###### Growth Activation Joins by Referrer Structure
| Field | Type | Description |
| ---------------- | ----------------- | ------------------------------------------------------------ |
| day_pt | ISO8601 timestamp | The interval the data represents |
| referring_domain | string | The domain that referred the user to join the guild |
| joins | integer | The number of users who joined the guild using this referral |
List Guild Growth Activation Joins by Sources
Returns a list of [growth activations joins by source](#growth-activation-joins-by-source-structure) objects representing detailed member join information per aggregation interval.
Accepts the [common query string parameters](#query-string-params) as described above.
###### Growth Activation Joins by Source Structure
| Field | Type | Description |
| ----------------- | ----------------- | -------------------------------------------------------------------------------------------------------------------------------- |
| day_pt | ISO8601 timestamp | The interval the data represents |
| discovery_joins | integer | The number of users who joined the guild through guild discovery |
| invites | integer | The number of users who joined the guild through an invite |
| vanity_joins | integer | The number of users who joined the guild through a vanity URL |
| hubs_joins | integer | The number of users who joined the guild through a student hub |
| bot_joins | integer | The number of users who were added to the guild by a bot using the [guilds.join OAuth2 scope](/resources/guild#add-guild-member) |
| integration_joins | integer | The number of users who were added to the guild by an integration (e.g. Twitch) |
| other_joins | integer | The number of users who joined the guild through an unknown source |
| total_joins | integer | The total number of users who joined the guild |
List Guild Growth Activation Leavers
Returns a list of [growth activation leavers](#growth-activation-leavers-structure) objects representing user leave statistics per aggregation interval.
Accepts the [common query string parameters](#query-string-params) as described above.
###### Growth Activation Leavers Structure
| Field | Type | Description |
| ------------- | ----------------- | ------------------------------------------------------------------------------- |
| day_pt | ISO8601 timestamp | The interval the data represents |
| days_in_guild | string | A label categorizing how long this set of users was in the guild before leaving |
| leavers | integer | The number of users who left the guild on this date |
List Guild Growth Activation Percentages
Returns a list of [growth activation percentage](#growth-activation-percentage-structure) objects representing user engagement statistics per aggregation interval.
Accepts the [common query string parameters](#query-string-params) as described above.
###### Growth Activation Percentage Structure
| Field | Type | Description |
| -------------------- | ----------------- | --------------------------------------------------------------------------- |
| day_pt | ISO8601 timestamp | The interval the data represents |
| new_members | integer | The number of new members who joined the guild on this date |
| pct_communicated? | float | Percentage of new members who sent 3 or more message or talked in the guild |
| pct_opened_channels? | float | Percentage of new members who opened 3 or more channels in the guild |
List Guild Growth Activation Retention
Returns a list of [growth activation retention](#growth-activation-retention-structure) objects representing user retention statistics per aggregation interval.
Accepts the [common query string parameters](#query-string-params) as described above.
###### Growth Activation Retention Structure
| Field | Type | Description |
| ------------- | ----------------- | ----------------------------------------------------------------------- |
| day_pt | ISO8601 timestamp | The interval the data represents |
| new_members | integer | The number of new members who joined the guild on this date |
| pct_retained? | float | Percentage of new members who stayed in the guild past their first week |
List Guild Growth Activation Membership
Returns a list of [growth activation membership](#growth-activation-membership-structure) objects representing the total number of members in the guild per aggregation interval.
Accepts the [common query string parameters](#query-string-params) as described above.
###### Growth Activation Membership Structure
| Field | Type | Description |
| ---------------- | ----------------- | ---------------------------------------- |
| day_pt | ISO8601 timestamp | The interval the data represents |
| total_membership | integer | The total number of members in the guild |
List Guild Engagement Base
Returns a list of [engagement base](#engagement-base-structure) objects representing guild engagement statistics per aggregation interval.
Accepts the [common query string parameters](#query-string-params) as described above.
###### Engagement Base Structure
| Field | Type | Description |
| ------------------------- | ----------------- | ----------------------------------------------------------------- |
| day_pt | ISO8601 timestamp | The interval the data represents |
| visitors | integer | The number of users who visited the guild |
| communicators | integer | The number of users who sent 3 or more messages in the guild |
| pct_communicators? | float | Percentage of users who communicated in the guild |
| messages | integer | The number of messages sent in the guild |
| messages_per_communicator | float | The average number of messages sent per communicator in the guild |
| speaking_minutes | integer | Amount of time (in minutes) users spent in voice in the guild |
List Guild Engagement Overview
Returns a list of [engagement overview](#engagement-overview-structure) objects representing general guild engagement statistics per aggregation interval.
Accepts the [common query string parameters](#query-string-params) as described above.
###### Engagement Overview Structure
| Field | Type | Description |
| ---------------- | ----------------- | ------------------------------------------------------------- |
| day_pt | ISO8601 timestamp | The interval the data represents |
| visitors | integer | The number of users who visited the guild |
| communicators | integer | The number of users who communicated in the guild |
| messages | integer | The number of messages sent in the guild |
| speaking_minutes | integer | Amount of time (in minutes) users spent in voice in the guild |
List Guild Engagement Muters
Returns a list of [engagement muters](#engagement-muters-structure) objects representing user mute statistics per aggregation interval.
Accepts the [common query string parameters](#query-string-params) as described above.
###### Engagement Muters Structure
| Field | Type | Description |
| ------------- | ----------------- | --------------------------------------------------------------------- |
| day_pt | ISO8601 timestamp | The interval the data represents |
| days_in_guild | string | A label categorizing how long this set of users has been in the guild |
| muters | integer | The number of users who have muted the guild |
List Guild Engagement Pruneable Members
Returns a list of [engagement pruneable members](#engagement-pruneable-members-structure) objects representing inactive user statistics per aggregation interval.
Accepts the [common query string parameters](#query-string-params) as described above.
###### Engagement Pruneable Members Structure
| Field | Type | Description |
| -------- | ----------------- | ------------------------------------------------ |
| day_pt | ISO8601 timestamp | The interval the data represents |
| inactive | integer | The number of users who are eligible for pruning |
List Guild Engagement Text Channels
Returns a list of [text channel engagement](#text-channel-engagement-structure) objects representing engagement statistics for messageable channels per aggregation interval.
Accepts the [common query string parameters](#query-string-params) as described above.
###### Text Channel Engagement Structure
| Field | Type | Description |
| ---------------------------- | ----------------- | ---------------------------------------------------- |
| day_pt | ISO8601 timestamp | The interval the data represents |
| channel_name? ^1^ | string | The name of the channel |
| channel_id | snowflake | The ID of the channel |
| participators | integer | The number of users who viewed the channel |
| communicators | integer | The number of sent 3 or more messages in the channel |
| messages_sent | integer | The number of messages sent in the channel |
| pct_participated_in_channel? | float | Percentage of users participated in the channel |
| pct_communicated_in_channel? | float | Percentage of users communicated in the channel |
^1^ Not present for voice channels.
List Guild Engagement Voice Channels
Returns a list of [voice channel engagement](#voice-channel-engagement-structure) objects representing engagement statistics for voice channels per aggregation interval.
Accepts the [common query string parameters](#query-string-params) as described above.
###### Voice Channel Engagement Structure
| Field | Type | Description |
| ---------------------------- | ----------------- | --------------------------------------------------------- |
| day_pt | ISO8601 timestamp | The interval the data represents |
| channel_name | string | The name of the voice channel |
| channel_id | snowflake | The ID of the voice channel |
| participators | integer | The number of users who joined the voice channel |
| communicators | integer | The number of users who talked in the voice channel |
| messages_sent | integer | The number of messages sent in the voice channel |
| pct_participated_in_channel? | float | Percentage of users who participated in the voice channel |
| pct_communicated_in_channel? | float | Percentage of users who communicated in the voice channel |
List Guild Audience New Members by Discord Tenure
Returns a list of [audience new members by Discord tenure](#audience-new-members-by-discord-tenure-structure) objects representing new member statistics categorized by account age per aggregation interval.
Accepts the [common query string parameters](#query-string-params) as described above.
###### Audience New Members by Discord Tenure Structure
| Field | Type | Description |
| ----------- | ------- | ----------------------------------------------------------- |
| day_pt | string | The interval the data represents |
| tenure | string | A label categorizing how long this set of users has existed |
| new_members | integer | The number of new members who joined the guild |
List Guild Audience Participators by Guild Tenure
Returns a list of [audience participators by guild tenure](#audience-participators-by-guild-tenure-structure) objects representing member statistics categorized by how long they have been in the guild per aggregation interval.
Accepts the [common query string parameters](#query-string-params) as described above.
###### Audience Participators by Guild Tenure Structure
| Field | Type | Description |
| ------------- | ------- | ----------------------------------------------------------- |
| day_pt | string | The interval the data represents |
| tenure | string | A label categorizing how long this set of users has existed |
| participators | integer | The number of users who participated in the guild |
List Guild Audience Participators by Platform
Returns a list of [audience participators by platform](#audience-participators-by-platform-structure) objects representing member statistics categorized by platform usage per aggregation interval.
Accepts the [common query string parameters](#query-string-params) as described above.
###### Audience Participators by Platform Structure
| Field | Type | Description |
| ------------- | ------- | ------------------------------------------------- |
| day_pt | string | The interval the data represents |
| platform | string | The platform the users are on |
| participators | integer | The number of users who participated in the guild |
List Guild Audience Participators by Registration Country
Returns a list of [audience participators by registration country](#audience-participators-by-registration-country-structure) objects representing member statistics categorized by their account registration country.
Accepts the [common query string parameters](#query-string-params) as described above.
###### Audience Participators by Registration Country Structure
| Field | Type | Description |
| ------------- | ------- | ----------------------------------------------------------------------------------------------------------------------------- |
| day_pt | string | The interval the data represents |
| country_code | string | The [ISO 3166-1 alpha-2](https://en.wikipedia.org/wiki/ISO_3166-1_alpha-2) country code the users registered their account in |
| participators | integer | The number of users who participated in the guild |
List Guild Channel Following Overview
Returns a list of [channel following overview](#channel-following-overview-structure) objects representing news channel following statistics per aggregation interval.
Accepts the [common query string parameters](#query-string-params) as described above.
###### Channel Following Overview Structure
| Field | Type | Description |
| ---------------------- | ----------------- | ---------------------------------------------------------- |
| day_pt | ISO8601 timestamp | The interval the data represents |
| total_guilds_following | integer | The total number of guilds following channels in the guild |
| new_guilds_following | integer | The number of new guilds following channels in the guild |
| guilds_unfollowed | integer | The number of guilds that unfollowed channels in the guild |
List Guild Channel Following by Channel
Returns a list of [channel following by channel](#channel-following-by-channel-structure) objects representing per-channel following statistics per channel per aggregation interval.
Accepts the [common query string parameters](#query-string-params) as described above.
###### Channel Following by Channel Structure
| Field | Type | Description |
| ---------------------- | ----------------- | ------------------------------------------------ |
| day_pt | ISO8601 timestamp | The interval the data represents |
| channel_id | snowflake | The ID of the followed channel |
| total_guilds_following | integer | The total number of guilds following the channel |
| new_guilds_following | integer | The number of new guilds following the channel |
| guilds_unfollowed | integer | The number of guilds that unfollowed the channel |
List Guild Channel Following Reach
Returns a list of [channel following reach](#channel-following-reach-structure) objects representing per-message reach statistics for followed channels per aggregation interval.
Accepts the [common query string parameters](#query-string-params) as described above.
###### Channel Following Reach Structure
| Field | Type | Description |
| -------------------- | ----------------- | --------------------------------------------------- |
| day_pt | ISO8601 timestamp | The interval the data represents |
| channel_id | snowflake | The ID of the followed channel |
| channel_name | string | The name of the followed channel |
| reference_message_id | snowflake | The ID of the announcement message |
| guilds_reached | integer | The number of guilds that received the announcement |
List Guild Channel Following Guild Size
Returns a list of [channel following guild size](#channel-following-guild-size-structure) objects representing followed channel statistics categorized by the size of the following guilds per aggregation interval.
Accepts the [common query string parameters](#query-string-params) as described above.
###### Channel Following Guild Size Structure
| Field | Type | Description |
| ---------------------- | ----------------- | ---------------------------------------------------- |
| day_pt | ISO8601 timestamp | The interval the data represents |
| guild_size | string | A label categorizing the size of the guilds |
| total_guilds_following | integer | The number of guilds following channels in the guild |
List Guild Channel Following Guild Size by Channel
Returns a list of [channel following guild size by channel](#channel-following-guild-size-by-channel-structure) objects representing per-channel followed channel statistics categorized by the size of the following guilds per aggregation interval.
###### Query String Params
| Field | Type | Description |
| ---------- | ----------------- | ------------------------------------------------------- |
| start | ISO8601 timestamp | Start date for the insights data |
| end | ISO8601 timestamp | End date for the insights data |
| interval | integer | [The data aggregation interval](#aggregation-interval) |
| channel_id | snowflake | The ID of the followed channel, or `0` for all channels |
###### Channel Following Guild Size by Channel Structure
| Field | Type | Description |
| ---------------------- | ----------------- | ------------------------------------------- |
| day_pt | ISO8601 timestamp | The interval the data represents |
| channel_id | snowflake | The ID of the followed channel |
| guild_size | string | A label categorizing the size of the guilds |
| total_guilds_following | integer | The number of guilds following the channel |
List Guild Welcome Screen Funnel
Returns a list of [welcome screen funnel](#welcome-screen-funnel-structure) objects representing welcome screen statistics per aggregation interval.
Accepts the [common query string parameters](#query-string-params) as described above.
###### Welcome Screen Funnel Structure
| Field | Type | Description |
| --------------------------- | ----------------- | -------------------------------------------------------------------- |
| day_pt | ISO8601 timestamp | The interval the data represents |
| option_channel_id | snowflake | The ID of the welcome channel option |
| option_selected | string | The description of the welcome channel option |
| users_viewed_welcome_screen | integer | The number of users who viewed the welcome screen |
| users_clicked_any_option | integer | The number of users who clicked any welcome channel option |
| users_clicked_option | integer | The number of users who clicked the welcome channel option |
| users_sent_message | integer | The number of users who sent a message in the welcome channel option |
| pct_clicked_option? | float | Percentage of users who clicked the welcome channel option |
| pct_sent_message? | float | Percentage of users who sent a message in the welcome channel option |
List Guild Welcome Screen Users
Returns a list of [welcome screen users](#welcome-screen-users-structure) objects representing user statistics for the welcome screen per aggregation interval.
Accepts the [common query string parameters](#query-string-params) as described above.
###### Welcome Screen Users Structure
| Field | Type | Description |
| --------------------------- | ----------------- | ------------------------------------------------- |
| day_pt | ISO8601 timestamp | The interval the data represents |
| users_viewed_welcome_screen | integer | The number of users who viewed the welcome screen |
---
# Widgets
Link: https://docs.discord.food/resources/widgets
Widgets are a way for users to showcase their gaming interests on their profile. They can display information about the user's favorite games, games they are currently playing, games they want to play, and more. Widgets can also be created by applications to display specific game details.
### Game Widget Object
A tile on a user's profile showcasing their gaming interests.
| Field | Type | Description |
| ---------- | ------------------------------------------------------ | -------------------------------- |
| data | [game widget data](#game-widget-data-structure) object | The data of the widget |
| id | snowflake | The ID of the widget |
| updated_at | ISO8601 timestamp | When the widget was last updated |
###### Game Widget Data Structure
| Field | Type | Description |
| --------------- | ------------------------------------------------------------- | ----------------------------------------------------------------------------------- |
| type | string | The [type of the game widget](#game-widget-type) |
| games? | array[[game widget game](#game-widget-game-structure) object] | The widget's games (not applicable for [`application` widgets](#game-widget-type)) |
| application_id? | snowflake | The application ID (only applicable for [`application` widgets](#game-widget-type)) |
###### Game Widget Type
| Value | Description |
| ------------------ | ------------------------- |
| favorite_games ^1^ | Favourite game (max 1) |
| played_games | Games I Like (max 20) |
| current_games ^1^ | Games in rotation (max 5) |
| want_to_play_games | Want to play (max 20) |
| application | Specific game details |
^1^ Rendered as a detailed game widget in the user profile.
###### Game Widget Game Structure
| Field | Type | Description |
| -------- | ------------- | -------------------------------------------------------------------------------- |
| game_id | snowflake | The application ID of the game |
| comment? | ?string | Optional comment to be displayed below the game in detailed game widgets |
| tags? | array[string] | [Tags](#game-widget-tag) to be displayed below the game in detailed game widgets |
###### Game Widget Tag
| Value | Description |
| ---------------------- | ------------------ |
| noob ^1^ | Noob |
| learning_the_ropes ^1^ | Learning The Ropes |
| casual ^1^ | Casual |
| getting_good ^1^ | Getting Good |
| intermediate ^1^ | Intermediate |
| expert ^1^ | Expert |
| better_than_you ^1^ | Better Than You |
| obsessed | Obsessed |
| love_it | Love It |
| kind_of_love_it | Kind of Love it |
| kind_of_hate_it | Kind of Hate it |
| rage_quitting | Rage Quitting |
| like_it | Like It |
| frustrated | Frustrated |
| too_easy | Too Easy |
| looking_for_group | Looking For Group |
| open_to_play | Open To Play |
| looking_for_tips | Looking For Tips |
| open_to_teach | Open To Teach |
| looking_to_discuss | Looking To Discuss |
^1^ Only one of these tags can be present in a game widget at a time.
###### Example Game Widget
```json
{
"id": "1455894303866880153",
"updated_at": "2025-12-31T12:04:11.252336+00:00",
"data": {
"type": "favorite_games",
"games": [
{
"game_id": "505134938354352128",
"comment": "Best game ever!",
"tags": ["expert", "open_to_teach"]
}
]
}
}
```
### User Application Identity Object
The user's external identity for a connected application.
###### User Application Identity Structure
| Field | Type | Description |
| ----------------------- | --------------------------------------------------------------------------------------------- | ---------------------------------------------------- |
| application_id | snowflake | The ID of the application |
| provider_issued_user_id | string | The ID of the user on the external identity provider |
| profile? | partial [user application profile](#partial-user-application-profile-structure) object | The primary user application profile of the user |
| profiles? | array[partial [user application profile](#partial-user-application-profile-structure) object] | The user application profile |
###### Partial User Application Profile Structure
| Field | Type | Description |
| ------------------ | -------------------------------------------------------------------------------- | ---------------------------------------------------- |
| username | ?string | The external username of the user |
| metadata | ?string | Custom metadata |
| data? | [user application profile data](#user-application-profile-data-structure) object | The user application data |
| data_trusted? | boolean | Whether the data is trusted (set by application bot) |
| connection_visible | boolean | Unknown |
###### User Application Profile Data Structure
| Field | Type | Description |
| -------- | --------------------------------------------------------------------------------------------------- | --------------------------------- |
| primary? | [user application profile primary data](#user-application-profile-primary-data-structure) object | The primary user application data |
| dynamic? | array[[user application profile dynamic data](#user-application-profile-dynamic-field-type) object] | The dynamic user application data |
###### User Application Profile Primary Data Structure
| Field | Type | Description |
| -------------------------------- | ------------------------------------------------------------------------------ | --------------------------------------------------------- |
| season? | string | The game season |
| rank_name? | string | The current rank the user has in-game |
| highest_rank? | string | The highest rank the user ever had in-game |
| featured_played_character? | string | The name of the featured played character |
| featured_played_character_image? | [unfurled media item](/resources/components#unfurled-media-item-object) object | The image of the featured played character |
| playtime_hours? | float | Duration (in hours) that the user has played the game for |
| total_wins? | integer | Number of total wins |
| current_period_wins? | integer | Number of wins in the current period |
| total_games? | integer | Number of total matches |
| current_period_games? | integer | Number of matches in the current period |
| total_kills? | integer | Number of total kills |
| current_period_kills? | integer | Number of kills in the current period |
| total_assists? | integer | Number of total assists |
| current_period_assists? | integer | Number of assists in the current period |
| total_deaths? | integer | Number of total deaths |
| current_period_deaths? | integer | Number of deaths in the current period |
| server_name? ^1^ | string | The name of the game server |
| user_id? ^1^ | string | The ID of the in-game account |
| union_level? ^1^ | string | The union level |
| total_resonators? ^1^ | integer | Number of total resonators |
| total_achievements? ^1^ | integer | Number of total achievements |
| total_echoes? ^1^ | integer | Number of total echoes |
| login_days? ^1^ | integer | Number of login days |
| data_bank_level? ^1^ | string | The data bank level |
^1^ Only applicable for the "Wuthering Waves" application.
###### User Application Profile Dynamic Field Type
| Value | Name | Data |
| ----- | ------ | -------------------------------------------------- |
| 1 | TEXT | [String structure](#dynamic-string-data-structure) |
| 2 | NUMBER | [Number structure](#dynamic-number-data-structure) |
| 3 | IMAGE | [Image structure](#dynamic-image-data-structure) |
###### Dynamic String Data Structure
| Field | Type | Description |
| ----- | ------- | ----------------------------- |
| name | string | The name of the dynamic data |
| value | string | The value of the dynamic data |
| type | integer | The type of the dynamic data |
###### Dynamic Number Data Structure
| Field | Type | Description |
| ----- | ------- | ----------------------------- |
| name | string | The name of the dynamic data |
| value | integer | The value of the dynamic data |
| type | integer | The type of the dynamic data |
###### Dynamic Image Data Structure
| Field | Type | Description |
| ----- | ------------------------------------------------------------------------------ | ----------------------------- |
| name | string | The name of the dynamic data |
| value | [unfurled media item](/resources/components#unfurled-media-item-object) object | The value of the dynamic data |
| type | integer | The type of the dynamic data |
###### Example User Application Profile Primary Data
```json
{
"season": "Season 5.0",
"rank_name": "No Season Data",
"highest_rank": "No Season Data",
"featured_played_character": "HulkBanner",
"featured_played_character_image": {
"id": "1443231705250136105",
"url": "https://x20na.gsf.easebar.com/nzgxowi1zdq3ztfmn2rhn2fiyjm2ndiznj.png",
"proxy_url": "https://images-ext-1.discordapp.net/external/kzlmI6xU3yzi4a-ipRusyF7IYGbHDgtjquG9jpGVDl0/https/x20na.gsf.easebar.com/nzgxowi1zdq3ztfmn2rhn2fiyjm2ndiznj.png",
"width": 300,
"height": 450,
"placeholder": "l+iFEwAryG8lphhnbmAS+RVnUHeRRlk=",
"placeholder_version": 1,
"content_type": "image/png",
"loading_state": 2,
"flags": 0
},
"playtime_hours": 2.29,
"total_wins": 12,
"current_period_wins": 0,
"total_games": 17,
"current_period_games": 0,
"total_kills": 245,
"current_period_kills": 0,
"total_assists": 27,
"current_period_assists": 0,
"total_deaths": 85,
"current_period_deaths": 0
}
```
### Widget Config Object
A config for a widget that is displayed on the user's profile.
###### Widget Config Structure
| Field | Type | Description |
| ---------------- | ---------------------------------------------------------------------------------- | -------------------------------------------------------- |
| application_id | snowflake | The ID of the application the widget config is for |
| config_id | snowflake | The ID of the widget config |
| display_name | string | The display name of the widget config |
| surfaces | map[string, [surface object](#widget-surface-structure)] | The surfaces the widget config is displayed on |
| status | string | The [status of the widget config](#widget-config-status) |
| resolved_assets? | array[[application asset](/resources/application#application-asset-object) object] | The resolved assets for the widget config |
| published_at | ?ISO8601 timestamp | When the widget config was published |
| updated_at | ISO8601 timestamp | When the widget config was last updated |
###### Widget Surface Structure
| Field | Type | Description |
| ---------- | --------------------------------------------------------------------------- | -------------------------------- |
| layout | string | The layout used for this surface |
| components | map[string, [widget component](#widget-surface-component-structure) object] | The components of the surface |
###### Widget Surface Component Structure
| Field | Type | Description |
| ------ | --------------------------------------------------------------------------------------- | --------------------------- |
| fields | map[string, [widget component field](#widget-surface-component-field-structure) object] | The fields of the component |
###### Widget Surface Component Field Structure
| Field | Type | Description |
| ----------------- | -------------------------------------------------------------------------- | -------------------------------------------------------- |
| value_type | string | The [type of the value](#widget-surface-value-type) |
| presentation_type | string | The [presentation type](#presentation-type) of the value |
| value | string | The actual value or reference key to the data |
| fallback? | [widget component field](#widget-surface-component-field-structure) object | The fallback value if the value is unavailable |
###### Widget Surface Value Type
| Value | Description |
| ---------------------------- | ------------------------------------------------------- |
| data | The value is taken from the user profile identity data |
| custom_string | The value is a custom string |
| application_asset | The value is taken from the resolved application assets |
| application_localized_string | Unknown |
###### Widget Layout Definition Structure
| Field | Type | Description |
| ------------ | --------------------------------------------------------------------------------- | --------------------------------------------------- |
| surface | string | The surface the layout applies to |
| components | map[string, [widget layout component](#widget-layout-component-structure) object] | The components of the layout |
| key | string | The [layout definition key](#layout-definition-key) |
| display_name | string | The display name of the layout definition |
###### Widget Layout Component Structure
| Field | Type | Description |
| ------------ | ------------------------------------------------------------------------- | --------------------------------- |
| display_name | string | The display name of the component |
| required | boolean | Whether the component is required |
| fields | map[string, [widget layout field](#widget-layout-field-structure) object] | The fields within the component |
###### Widget Layout Field Structure
| Field | Type | Description |
| -------------------------- | ------------- | -------------------------------------------------------------- |
| display_name | string | The display name of the field |
| required | boolean | Whether the field is required |
| allowed_presentation_types | array[string] | Allowed [presentation types](#presentation-type) for the field |
###### Widget Config Status
| Value | Description |
| --------- | ------------------------------ |
| published | The widget config is published |
| draft | The widget config is a draft |
###### Presentation Type
| Value | Description |
| -------- | ----------------------------- |
| image | The value is an image |
| number | The value is a number |
| text | The value is a string of text |
| duration | The value is a duration |
###### Surface Type
| Value | Description |
| ------------------ | ------------------------------------------------------------ |
| widget_top | The content displayed at the top of the widget |
| widget_bottom | The content displayed at the bottom of the widget |
| add_widget_preview | The content displayed when adding a widget |
| mini_profile | The content displayed in the mini profile |
| activity_accessory | The content displayed as an accessory to the user's activity |
###### Layout Definition Key
| Value | Description |
| ---------------------------- | --------------------------------------------------------------------------------------------------------- |
| activity_accessory_stat | The layout definition for the activity accessory surface |
| add_widget_preview_contained | The layout definition for the add widget preview surface with the avatar being contained in a box |
| add_widget_preview_hero | The layout definition for the add widget preview surface with the avatar being the main focus |
| mini_profile_contained_stat | The layout definition for the mini profile surface with the avatar being contained in a box |
| mini_profile_hero_stat | The layout definition for the mini profile surface with the avatar being the main focus |
| widget_bottom_collection | The layout definition for the widget bottom surface when the widget is part of a collection |
| widget_bottom_progress | The layout definition for the widget bottom surface when the widget is showcasing progress towards a goal |
| widget_bottom_stats | The layout definition for the widget bottom surface when the widget is showcasing stats |
| widget_top_contained | The layout definition for the widget top surface with the avatar being contained in a box |
| widget_top_hero | The layout definition for the widget top surface with the avatar being the main focus |
## Endpoints
Modify Profile Widgets
Replaces the user's profile widgets, and returns a list of [game widget](#game-widget-object) which has been put on the user's profile.
###### JSON Params
| Field | Type | Description |
| ------- | -------------------------------------------------------- | --------------------------------------------------------------------------------- |
| widgets | array[partial [game widget](#game-widget-object) object] | The user's game widgets (max 1 of each [game widget type](#game-widget-type)) ^1^ |
^1^ The `id` field is optional and `updated_at` is ignored.
Get Profile Widgets Suggested Games
Returns suggested applications for the current user's profile game widgets.
###### Response Body
| Field | Type | Description |
| ------------------------ | ---------------- | ------------------------------------------- |
| suggested_games | array[snowflake] | The suggested game application IDs |
| suggested_wishlist_games | array[snowflake] | The suggested wishlist game application IDs |
List Bulk Application Identities
Returns a list of partial [application identity](#partial-application-identity-structure) objects connected to the authorized application.
This endpoint is only usable with an OAuth2 access token.
###### JSON Params
| Field | Type | Description |
| ------------ | ---------------- | ------------------------------------------------------- |
| user_ids ^1^ | array[snowflake] | The IDs of the users to retrieve identities for (1-100) |
^1^ Invalid IDs are ignored.
###### Partial Application Identity Structure
| Field | Type | Description |
| ---------------- | --------- | ---------------------------------------------------- |
| user_id | snowflake | The ID of the user |
| external_user_id | string | The ID of the user on the external identity provider |
Get User Application Profile
Returns an [user application profile](/gateway/gateway-events#user-application-profile-structure) object for the given application, user, and external user IDs.
This endpoint is not usable by user accounts.
Modify User Application Profile
Modifies the user's application profile. Returns an [user application profile](/gateway/gateway-events#user-application-profile-structure) object on success.
This endpoint is not usable by user accounts.
###### JSON Params
| Field | Type | Description |
| --------- | -------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------- |
| username? | string | The username (max 1024) |
| metadata? | object | Custom metadata for the user application profile (max 25 keys, 1024 characters per key and value) |
| data? | [user application profile data](#user-application-profile-data-structure) object | The user application profile data to set |
List User Application Identities
Returns the user's external identities for connected applications.
###### Query String Params
| Field | Type | Description |
| -------------- | ------- | ------------------------------------------------------------------ |
| with_profiles? | boolean | Whether to include application profile information (default false) |
###### Response Body
| Field | Type | Description |
| ---------- | ------------------------------------------------------------------------------- | --------------------------- |
| identities | array[[user application identity](#user-application-identity-structure) object] | The identities for the user |
Modify User Application Profile Config
Modifies the user's application profile config. Returns a 204 empty response on success.
###### JSON Params
| Field | Type | Description |
| ------------------- | ------ | --------------------------------- |
| connection_visible? | string | Whether the connection is visible |
List Featured Application Widget Configs
Returns featured widget configs.
###### Response Body
| Field | Type | Description |
| --------------- | ----------------------------------------------------------------------- | ---------------------------------------------------- |
| application_ids | array[snowflake] | The application IDs of the featured widget configs |
| configs | map[snowflake, array[[widget config](#widget-config-structure) object]] | The featured widget configs mapped by application ID |
Get Developer Application Widget Configs
Returns widget configs of the apps the user has access to.
###### Response Body
| Field | Type | Description |
| ------- | ----------------------------------------------------------------------- | ---------------------------------------------------- |
| configs | map[snowflake, array[[widget config](#widget-config-structure) object]] | The featured widget configs mapped by application ID |
Get Layout Definitions
Returns a map of [widget layout definitions](#widget-layout-definition-structure) for widget configs.
###### Response Body
| Field | Type | Description |
| ------- | ----------------------------------------------------------------------- | ---------------------------------------------------- |
| configs | map[snowflake, array[[widget config](#widget-config-structure) object]] | The featured widget configs mapped by application ID |
List Application Widget Configs
Returns a list of [widget configs](#widget-config-structure) for the specified application.
Create Application Widget Config
Creates a new widget config for the specified application. Returns the created [widget config](#widget-config-structure) on success.
###### JSON Params
| Field | Type | Description |
| ------------ | --------------------------------------------------------------- | ---------------------------------------------------------- |
| display_name | string | The display name of the widget config (max 100 characters) |
| surfaces | map[string, [widget surface](#widget-surface-structure) object] | The surfaces mapped by [surface type](#surface-type) |
Delete Application Widget Config
Deletes the widget config. Returns a 204 empty response on success.
Modify Application Widget Config
Modifies the widget config. Returns the updated [widget config](#widget-config-structure) on success.
###### JSON Params
| Field | Type | Description |
| ------------- | -------------------------------------------------------- | ---------------------------------------------------------- |
| display_name? | string | The display name of the widget config (max 100 characters) |
| surfaces | map[string, [widget surface](#widget-surface-structure)] | The surfaces mapped by [surface type](#surface-type) |
Publish Application Widget Config
Publishes the widget config. Returns the [widget config](#widget-config-structure) on success.
Unpublish Application Widget Config
Unpublishes the widget config. Returns the [widget config](#widget-config-structure) on success.
---
# User Settings Proto
Link: https://docs.discord.food/resources/user-settings-proto
User settings are options that a user can configure to change the behavior of their account or client. These settings are now stored in a protocol buffer format, which is more efficient and allows for more flexibility.
Multiple user settings protos are supported, each with a different purpose.
Protobufs are a binary format, so you'll need to decode them before you can read them. If you want to learn more about them, a good start is Google's [official documentation](https://protobuf.dev/). All protobufs transmitted in the API are encoded in base64.
The types documented below follow standard protobuf types (e.g. `uint32`, `bool`, `fixed64`, etc.). Some values are wrapped in containers such as `StringValue` or `BoolValue`.
These are wrappers that allow the value to be `null` or unset, but must be unwrapped to access the value. They are provided by the `google.protobuf.wrappers` and `google.protobuf.timestamp` packages.
The order of the documented structures below is the same order used in the wire format.
All protobuf definitions used by Discord are available in [this repository](https://github.com/discord-userdoccers/discord-protos). They are also packaged on [PyPI](https://pypi.org/project/discord-protos) and [npm](https://www.npmjs.com/package/discord-protos) for easy installation.
### User Settings Proto Type
| Value | Name | Description | Object |
| ----- | ------------- | --------------------------------------------------------------------------------------- | ---------------------------------------------------------- |
| 1 | PRELOADED | General Discord user settings, sent in the [Ready](/gateway/gateway-events#ready) event | [Preloaded User Settings](#preloaded-user-settings-object) |
| 2 | FRECENCY | Frecency and favorites storage, used for low-priority, lazy-loaded settings | [Frecency User Settings](#frecency-user-settings-object) |
| 3 | TEST_SETTINGS | Unknown | Unknown |
###### Versions Structure
| Field | Type | Description |
| ------------------ | ------ | -------------------------------------------- |
| client_version | uint32 | The client migration version |
| server_version ^1^ | uint32 | The server migration version (currently `0`) |
| data_version ^1^ | uint32 | The incremental data version |
^1^ Should not be modified by clients. `data_version` is automatically incremented on every change.
### Preloaded User Settings Object
Serialized as `discord_protos.discord_users.v1.PreloadedUserSettings`.
###### Preloaded User Settings Structure
| Field | Type | Description |
| ------------------------ | ---------------------------------------------------------------------- | ------------------------------------------------------------------------------ |
| versions | [versions](#versions-structure) object | Version information for the protocol and data |
| inbox | [inbox settings](#inbox-settings-structure) object | Settings related to the user's inbox view |
| guilds | [all guild settings](#all-guild-settings-structure) object | Settings specific to guilds and channels |
| user_content | [user content settings](#user-content-settings-structure) object | Dismissal states for various types of upsells and promotions |
| voice_and_video | [voice and video settings](#voice-and-video-settings-structure) object | Voice and video call configuration |
| text_and_images | [text and images settings](#text-and-images-settings-structure) object | Chat and image rendering settings |
| notifications | [notification settings](#notification-settings-structure) object | Notification-related preferences |
| privacy | [privacy settings](#privacy-settings-structure) object | User privacy preferences |
| debug | [debug settings](#debug-settings-structure) object | Client debug settings |
| game_library | [game library settings](#game-library-settings-structure) object | Game library settings |
| status | [status settings](#status-settings-structure) object | User presence customization settings |
| localization | [localization settings](#localization-settings-structure) object | Client localization preferences |
| appearance | [appearance settings](#appearance-settings-structure) object | Client appearance settings |
| guild_folders | [guild folders](#guild-folders-structure) object | Organization settings for guilds |
| favorites | [favorites](#favorites-structure) object | The serialized client favorites pseudo-guild |
| audio_context_settings | [audio settings](#audio-settings-structure) object | RTC audio context settings |
| communities | [communities settings](#communities-settings-structure) object | Community guild settings |
| broadcast | [broadcast settings](#broadcast-settings-structure) object | Broadcast settings |
| clips | [clips settings](#clips-settings-structure) object | [Clips](https://support.discord.com/hc/en-us/articles/16861982215703) settings |
| for_later | [for later settings](#for-later-settings-structure) object | For Later section settings for bookmarks and reminders |
| safety_settings | [safety settings](#safety-settings-structure) object | User safety settings |
| icymi_settings | [ICYMI settings](#icymi-settings-structure) object | ICYMI (In Case You Missed It) feed settings |
| applications | [all application settings](#all-application-settings-structure) object | Application-specific settings |
| ads | [ads settings](#ads-settings-structure) object | Ads settings |
| in_app_feedback_settings | [in-app feedback settings](#in-app-feedback-settings-structure) object | In-app feedback settings |
| app_version_settings | [app version settings](#app-version-settings-structure) object | App version settings |
###### Inbox Settings Structure
| Field | Type | Description |
| --------------- | ---------------------------- | ---------------------------------------------- |
| current_tab | [inbox tab](#inbox-tab) enum | The currently selected tab in the inbox |
| viewed_tutorial | boolean | Whether the user has viewed the inbox tutorial |
###### Inbox Tab
| Value | Name | Description |
| ----- | ------------ | ---------------------- |
| 0 | UNSPECIFIED | Default unset value |
| 1 | MENTIONS | Mentions tab |
| 2 | UNREADS | Unreads tab |
| 3 | TODOS | Message reminders tab |
| 4 | FOR_YOU | Notification items tab |
| 5 | GAME_INVITES | Game invites tab |
| 6 | BOOKMARKS | Bookmarks tab |
| 7 | SCHEDULED | Scheduled messages tab |
###### All Guild Settings Structure
| Field | Type | Description |
| ------------------------- | ---------------------------------------------------------------- | ------------------------------------------- |
| guilds | map[fixed64, [guild settings](#guild-settings-structure) object] | Per-guild personalization settings |
| ~~leaderboards_disabled~~ | ~~boolean~~ | ~~Whether guild leaderboards are disabled~~ |
###### Guild Settings Structure
| Field | Type | Description |
| -------------------------------------- | ------------------------------------------------------------------------------------------------ | ----------------------------------------------------------------------------- |
| channels | map[fixed64, [channel settings](#channel-settings-structure) object] | Settings specific to channels within the guild |
| hub_progress | uint32 | [Hub progress flags](#hub-progress-flags) |
| guild_onboarding_progress | uint32 | [Guild onboarding progress flags](#guild-onboarding-progress-flags) |
| guild_recents_dismissed_at? | timestamp | When the guild recents were last dismissed |
| dismissed_guild_content | bytes | Per-guild dismissable content, encoded as a byte array of integer enum values |
| join_sound? | [custom call sound](#custom-call-sound-structure) object | Custom sound played when joining a call in this channel |
| mobile_redesign_channel_list_settings? | [channel list settings](#channel-list-settings-structure) object | Channel list settings |
| disable_raid_alert_push | boolean | Whether to disable raid alert push notifications |
| disable_raid_alert_nag | boolean | Whether to disable raid alert in-client nag screens |
| custom_notification_sound_config? | [custom notification sound config](#custom-notification-sound-config-structure) object | Custom notification sound configuration |
| leaderboards_disabled | boolean | Whether guild leaderboards are disabled |
| guild_dismissible_content_states | map[int32, [guild dismissible content state](#guild-dismissible-content-state-structure) object] | States of guild dismissible content entries |
| guild_theme_source_preference | [guild theme source preference](#guild-theme-source-preference) enum | Guild theme source preference override |
###### Channel Settings Structure
| Field | Type | Description |
| --------------------------------- | ------------------------------------------------------------------------------- | ------------------------------------------------------- |
| collapsed_in_inbox | boolean | Whether the channel is collapsed in the inbox |
| icon_emoji? | [channel icon emoji](#channel-icon-emoji-structure) | The custom emoji icon for the channel |
| custom_notification_sound_config? | [custom notification sound config](#custom-notification-sound-config-structure) | Custom notification sound configuration for the channel |
###### Channel Icon Emoji Structure
| Field | Type | Description |
| ------ | ----------- | --------------------- |
| id? | UInt64Value | The ID of the emoji |
| name? | StringValue | The name of the emoji |
| color? | UInt64Value | The color of the icon |
###### Custom Notification Sound Config Structure
| Field | Type | Description |
| --------------------------- | ----------- | ---------------------------------------------------------------------- |
| notification_sound_pack_id? | StringValue | The ID of the [notification sound pack](#notification-sound-pack) used |
###### Guild Dismissible Content State Structure
| Field | Type | Description |
| ------------------------ | ------- | ----------------------------------------------------------------------- |
| dismissed | boolean | Whether the content is dismissed |
| last_dismissed_version | uint32 | The version of the dismissal state |
| last_dismissed_at_ms | uint64 | Unix timestamp (in milliseconds) of when the content was last dismissed |
| last_dismissed_object_id | uint64 | The ID of the last dismissed object |
| num_times_dismissed | uint32 | Total number of times the content has been dismissed |
###### Hub Progress Flags
| Value | Name | Description |
| -------- | ------------ | ---------------------------------------- |
| 1 \<\< 0 | JOIN_GUILD | User has joined a guild in the hub |
| 1 \<\< 1 | INVITE_USER | User has sent an invite for the hub |
| 1 \<\< 2 | CONTACT_SYNC | User has accepted the contact sync modal |
###### Guild Onboarding Progress Flags
| Value | Name | Description |
| -------- | -------------- | ----------------------------------------- |
| 1 \<\< 0 | NOTICE_SHOWN | User has been shown the onboarding notice |
| 1 \<\< 1 | NOTICE_CLEARED | User has cleared the onboarding notice |
###### Custom Call Sound Structure
| Field | Type | Description |
| -------- | ------- | ------------------------------------------ |
| sound_id | fixed64 | The ID of the custom call soundboard sound |
| guild_id | fixed64 | The ID of the guild the sound is in |
###### Notification Sound Pack
| Value | Description |
| -------------- | ---------------------- |
| classic | Default Discord sounds |
| retro | Retro |
| bop | Bubble |
| ducky | Ducky |
| lofi | Lofi |
| asmr | ASMR |
| discodo | Discodo easter egg |
| halloween | Halloween |
| winter_holiday | Winter holiday |
###### Channel List Settings Structure
| Field | Type | Description |
| ----------------- | ----------- | --------------------------- |
| layout? | StringValue | Channel list layout setting |
| message_previews? | StringValue | Message preview setting |
###### User Content Settings Structure
| Field | Type | Description |
| --------------------------------------------------- | -------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------- |
| dismissed_contents | bytes | User dismissed content, encoded as a byte array of integer enum values |
| last_dismissed_outbound_promotion_start_date? | StringValue | When the last dismissed outbound promotion started |
| premium_tier_0_modal_dismissed_at? **(deprecated)** | Timestamp | When the Nitro Basic promotion modal was dismissed |
| guild_onboarding_upsell_dismissed_at? | Timestamp | When the guild onboarding upsell was dismissed |
| safety_user_sentiment_notice_dismissed_at? | Timestamp | When the safety user sentiment notice was dismissed |
| last_received_changelog_id | fixed64 | The ID of the last received changelog |
| recurring_dismissible_content_states | map[int32, [recurring dismissible content state](#recurring-dismissible-content-state-structure) object] | States of recurring dismissible content entries |
| last_gift_intent_dismissed_at_ms | fixed64 | Unix timestamp (in milliseconds) of when the gift intent was dismissed |
###### Recurring Dismissible Content State Structure
| Field | Type | Description |
| ------------------------ | ------ | ----------------------------------------------------------------------- |
| last_dismissed_version | uint32 | The version of the dismissal state |
| last_dismissed_at_ms | uint64 | Unix timestamp (in milliseconds) of when the content was last dismissed |
| last_dismissed_object_id | uint64 | The ID of the last dismissed object |
| num_times_dismissed | uint32 | Total number of times the content has been dismissed |
###### Voice And Video Settings Structure
| Field | Type | Description |
| --------------------------------- | ------------------------------------------------------------------------------ | ----------------------------------------------------------------------------------------------------- |
| blur | [video filter background blur](#video-filter-background-blur-structure) object | Video call background blur settings |
| preset_option | uint32 | The [selected video call background preset](#video-filter-background-preset) |
| custom_asset | [video filter asset](#video-filter-asset-structure) object | Custom video call background asset |
| always_preview_video? | BoolValue | Whether to always preview video before enabling it (default false) |
| afk_timeout? | UInt32Value | Duration (in seconds) the user needs to be inactive until clients update their AFK state (default 60) |
| stream_notifications_enabled? | BoolValue | Whether to receive stream notifications for friends (default true) |
| native_phone_integration_enabled? | BoolValue | Whether to enable the new Discord mobile phone number friend requesting feature (default true) |
| soundboard_settings? | [soundboard settings](#soundboard-settings-structure) object | Settings for the soundboard feature |
| disable_stream_previews? | BoolValue | Whether clients should disable sending stream previews (default false) |
| soundmoji_volume? | FloatValue | Volume level for soundmoji playback (0-100, default 100) |
###### Video Filter Background Blur Structure
| Field | Type | Description |
| -------- | ------- | ----------------------------------------------- |
| use_blur | boolean | Whether to apply background blur in video calls |
###### Video Filter Asset Structure
| Field | Type | Description |
| ---------- | ------- | ---------------------------------- |
| id | fixed64 | The ID of the video filter asset |
| asset_hash | string | The hash of the video filter asset |
###### Soundboard Settings Structure
| Field | Type | Description |
| ------ | ----- | -------------------------------------------- |
| volume | float | Volume level for soundboard playback (0-100) |
###### Video Filter Background Preset
| Value | Description |
| ----- | ----------------- |
| 0 | Unset |
| 1 | Cybercity |
| 2 | Discord the Movie |
| 3 | Wumpus Vacation |
| 4 | Vaporwave |
| 7 | Capernite Day |
| 8 | Capernite Night |
| 9 | Hacker Den |
| 10 | Wumpice |
###### Text And Images Settings Structure
| Field | Type | Description |
| ------------------------------------------ | -------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------- |
| diversity_surrogate? | StringValue | Unicode surrogate for diversity emoji |
| use_rich_chat_input? **(deprecated)** | BoolValue | Inverse of `use_legacy_chat_input` |
| use_thread_sidebar? | BoolValue | Whether to display threads in the sidebar (default true) |
| render_spoilers? | StringValue | [How spoilers should be rendered](#spoiler-render-options) |
| emoji_picker_collapsed_sections | array[string] | [Sections of the emoji picker](#emoji-picker-section) that are collapsed |
| sticker_picker_collapsed_sections | array[string] | [Sections of the sticker picker](#sticker-picker-section) that are collapsed |
| view_image_descriptions? | BoolValue | Whether to show image alt text (default false) |
| show_command_suggestions? | BoolValue | Whether to show command suggestions in chat (default true) |
| inline_attachment_media? | BoolValue | Whether to display attachments when they are uploaded in chat (default true) |
| inline_embed_media? | BoolValue | Whether to display videos and images from links posted in chat (default true) |
| gif_auto_play? | BoolValue | Whether GIFs are automatically played when the Discord client is in focus (default true) |
| render_embeds? | BoolValue | Whether to render message embeds (default true) |
| render_reactions? | BoolValue | Whether to render message reactions (default true) |
| animate_emoji? | BoolValue | Whether to play animated emoji in chat (default true) |
| animate_stickers? | UInt32Value | [When to animate stickers in chat](/resources/user-settings#sticker-animation-option) |
| enable_tts_command? | BoolValue | Whether to allow TTS messages to be sent and played (default true) |
| message_display_compact? | BoolValue | Whether to use the compact Discord display mode (default false) |
| explicit_content_filter? | UInt32Value | The [explicit content filter](/resources/user-settings#explicit-content-filter) for explicit content in all messages |
| view_nsfw_guilds? | BoolValue | Whether NSFW guilds are shown on iOS (default false) |
| convert_emoticons? | BoolValue | Whether to convert emoticons into emoji (e.g. `:)` -> `🙂`) (default true) |
| expression_suggestions_enabled? | BoolValue | Whether to show expression suggestions in chat (default true) |
| view_nsfw_commands? | BoolValue | Whether NSFW application commands are shown in DMs (default false) |
| use_legacy_chat_input? | BoolValue | Whether to use the legacy chat input UI (default false) |
| soundboard_picker_collapsed_sections | array[string] | [Sections of the soundboard picker](#soundboard-picker-section) that are collapsed |
| dm_spam_filter? **(deprecated)** | UInt32Value | DM spam filter setting |
| dm_spam_filter_v2 | [DM spam filter v2](#dm-spam-filter-v2) enum | DM spam filter setting |
| include_stickers_in_autocomplete? | BoolValue | Whether to autocomplete stickers in chat (default false) |
| explicit_content_settings? | [explicit content settings](#explicit-content-settings-structure) object | Explicit content settings |
| keyword_filter_settings? | [keyword filter settings](#keyword-filter-settings-structure) object | Client-side keyword filter settings |
| include_soundmoji_in_autocomplete? | BoolValue | Whether to autocomplete soundmoji in chat (default true) |
| gore_content_settings? | [gore content settings](#gore-content-settings-structure) object | Gore content settings |
| default_reaction_emoji? | [default reaction emoji](#default-reaction-emoji-structure) object | Default reaction emoji settings |
| show_mention_suggestions? **(deprecated)** | BoolValue | Whether to show mention suggestions in chat (default true) |
| self_harm_content_settings? | [self harm content settings](#self-harm-content-settings-structure) object | Self harm content settings |
| is_cross_dm_search_enabled? | BoolValue | Whether cross-DM search is enabled in the DM UI (default false) |
| search_provider | [search provider](#search-provider) enum | Search provider used when searching selected text from the context menu |
| custom_search_url? | StringValue | Custom search provider URL |
###### Spoiler Render Options
| Value | Description |
| ------------ | --------------------------------------------------- |
| ALWAYS | Always render spoilers |
| ON_CLICK | Render spoilers on click (default) |
| IF_MODERATOR | Always render spoilers in guilds the user moderates |
###### Emoji Picker Section
This may also be a snowflake to represent a specific guild in the emoji picker.
| Value | Description |
| --------------- | ------------------- |
| FAVORITES | Favorite emoji |
| TOP_GUILD_EMOJI | Top guild emoji |
| RECENT | Recently used emoji |
| people | People emoji |
| nature | Nature emoji |
| food | Food emoji |
| activity | Activity emoji |
| travel | Travel emoji |
| objects | Object emoji |
| symbols | Symbol emoji |
| flags | Flag emoji |
###### Sticker Picker Section
This may also be a snowflake to represent a specific guild in the sticker picker.
| Value | Description |
| -------- | ---------------------- |
| FAVORITE | Favorite stickers |
| RECENT | Recently used stickers |
###### Soundboard Picker Section
This may also be a snowflake to represent a specific guild in the soundboard sound picker.
| Value | Description |
| ----- | ---------------------- |
| 0 | Favorite sounds |
| 4 | Default Discord sounds |
###### DM Spam Filter
| Value | Name | Description |
| ----- | ----------------------- | ------------------------------------------------- |
| 0 | DISABLED | DM spam filter is disabled |
| 1 | NON_FRIENDS | Apply spam filter to non-friends |
| 2 | FRIENDS_AND_NON_FRIENDS | Apply spam filter to both friends and non-friends |
###### DM Spam Filter V2
| Value | Name | Description |
| ----- | ----------------------- | ------------------------------------------------- |
| 0 | UNSET | Default unset value (equates to `NON_FRIENDS`) |
| 1 | DISABLED | DM spam filter is disabled |
| 2 | NON_FRIENDS | Apply spam filter to non-friends |
| 3 | FRIENDS_AND_NON_FRIENDS | Apply spam filter to both friends and non-friends |
###### Search Provider
| Value | Name | Description |
| ----- | ---------- | ----------------------------------------- |
| 0 | UNSET | Default unset value (equates to `GOOGLE`) |
| 1 | GOOGLE | Google |
| 2 | BING | Bing |
| 3 | DUCKDUCKGO | DuckDuckGo |
| 4 | CUSTOM | Custom search provider |
###### Explicit Content Settings Structure
| Field | Type | Description |
| ------------------------------ | -------------------------------------------------------------- | ---------------------------------------------------- |
| explicit_content_guilds | [explicit content redaction](#explicit-content-redaction) enum | Redaction setting for explicit content in guilds |
| explicit_content_friend_dm | [explicit content redaction](#explicit-content-redaction) enum | Redaction setting for explicit content in friend DMs |
| explicit_content_non_friend_dm | [explicit content redaction](#explicit-content-redaction) enum | Redaction setting for explicit content in other DMs |
###### Explicit Content Redaction
| Value | Name | Description |
| ----- | ----- | ------------------------------------------------------------------------ |
| 0 | UNSET | Default unset value (equates to `BLOCK` for non-friend DMs, else `SHOW`) |
| 1 | SHOW | Disable explicit content filtering |
| 2 | BLUR | Blur explicit content |
| 3 | BLOCK | Block explicit content entirely |
###### Keyword Filter Settings Structure
| Field | Type | Description |
| --------------- | --------- | ------------------------------------------------ |
| profanity? | BoolValue | Whether to filter profanity (default false) |
| sexual_content? | BoolValue | Whether to filter sexual content (default false) |
| slurs? | BoolValue | Whether to filter slurs (default false) |
###### Gore Content Settings Structure
| Field | Type | Description |
| -------------------------- | -------------------------------------------------------------- | ------------------------------------------------ |
| gore_content_guilds | [explicit content redaction](#explicit-content-redaction) enum | Redaction setting for gore content in guilds |
| gore_content_friend_dm | [explicit content redaction](#explicit-content-redaction) enum | Redaction setting for gore content in friend DMs |
| gore_content_non_friend_dm | [explicit content redaction](#explicit-content-redaction) enum | Redaction setting for gore content in other DMs |
###### Default Reaction Emoji Structure
| Field | Type | Description |
| ------------------- | ----------- | ---------------------------------------------- |
| emoji_id? | UInt64Value | The ID of the default reaction emoji |
| emoji_name? | StringValue | The name of the default reaction emoji |
| animated? | BoolValue | Whether the default reaction emoji is animated |
| disable_double_tap? | BoolValue | Whether double tap to react is disabled |
###### Self Harm Content Settings Structure
| Field | Type | Description |
| ------------------------------- | -------------------------------------------------------------- | ----------------------------------------------------- |
| self_harm_content_guilds | [explicit content redaction](#explicit-content-redaction) enum | Redaction setting for self harm content in guilds |
| self_harm_content_friend_dm | [explicit content redaction](#explicit-content-redaction) enum | Redaction setting for self harm content in friend DMs |
| self_harm_content_non_friend_dm | [explicit content redaction](#explicit-content-redaction) enum | Redaction setting for self harm content in other DMs |
###### Notification Settings Structure
| Field | Type | Description |
| ----------------------------------------------------------- | ---------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------- |
| show_in_app_notifications? | BoolValue | Whether to show in-app notifications (default true) |
| notify_friends_on_go_live? | BoolValue | Whether to notify friends when streaming in eligible guilds (default false) |
| notification_center_acked_before_id | fixed64 | The notification center item ID before which items are considered acknowledged |
| enable_burst_reaction_notifications? **(deprecated)** | BoolValue | Whether to enable burst reaction notifications |
| quiet_mode? | BoolValue | Whether quiet mode is enabled (default false) |
| focus_mode_expires_at_ms | fixed64 | Unix timestamp (in milliseconds) of when focus mode expires |
| reaction_notifications | [reaction notification type](#reaction-notification-type) enum | Reaction notification settings |
| game_activity_notifications **(deprecated)** | [game activity notification type](#game-activity-notification-type) enum | Game activity notification settings |
| custom_status_push_notifications | [custom status push notification type](#custom-status-push-notification-type) enum | Custom status push notification settings |
| game_activity_exclude_steam_notifications? **(deprecated)** | BoolValue | Whether to exclude Steam from game activity notifications |
| enable_voice_activity_notifications? | BoolValue | Whether to enable voice activity notifications (default true) |
| enable_friend_online_notifications? | BoolValue | Whether to enable friend online notifications (default true) |
| enable_user_resurrection_notifications? **(deprecated)** | BoolValue | Whether to enable notifications for users becoming active again after a long hiatus (default true) |
| enable_friend_anniversary_notifications? | BoolValue | Whether to enable friend anniversary notifications (default true) |
| enable_game_update_notifications? | BoolValue | Whether to enable game update notifications (default true) |
| enable_profile_updates_notifications? | BoolValue | Whether to enable profile updates notifications (default true) |
| enable_server_trending_notifications? | BoolValue | Whether to enable guild trending notifications (default true) |
| enable_dm_reply_nudge_reminders? | BoolValue | Whether to enable DM reply nudge reminders (default true) |
| enable_summary_reminder_notifications? | BoolValue | Whether to enable summary reminder notifications (default true) |
| enable_gdm_all_reaction_notifications? **(deprecated)** | BoolValue | Whether to enable all reaction notifications in group DMs (default `reaction_notifications`) |
| enable_friend_gaming_activity_notifications? | BoolValue | Whether to enable friend gaming activity notifications (default true) |
| enable_upcoming_server_event_notifications? | BoolValue | Whether to enable upcoming guild event notifications (default true) |
| enable_screen_downtime_schedule_notifications? | BoolValue | Whether to enable screen downtime schedule notifications (default true) |
| notify_friends_on_profile_update? | BoolValue | Whether to notify friends when the user updates their profile (default true) |
| notify_friends_on_come_online? | BoolValue | Whether to notify friends when the user comes online (default true) |
###### Reaction Notification Type
| Value | Name | Description |
| ----- | ---------------------- | ----------------------------------------- |
| 0 | NOTIFICATIONS_ENABLED | Enable reaction notifications (default) |
| 1 | ONLY_DMS | Only enable reaction notifications in DMs |
| 2 | NOTIFICATIONS_DISABLED | Disable reaction notifications |
###### Game Activity Notification Type
| Value | Name | Description |
| ----- | ------------------------------- | ----------------------------------------------------------------- |
| 0 | ACTIVITY_NOTIFICATIONS_UNSET | Default unset value (equates to `ACTIVITY_NOTIFICATIONS_ENABLED`) |
| 1 | ACTIVITY_NOTIFICATIONS_DISABLED | Disable game activity notifications |
| 2 | ACTIVITY_NOTIFICATIONS_ENABLED | Enable game activity notifications |
| 3 | ONLY_GAMES_PLAYED | Only enable notifications for played games |
###### Custom Status Push Notification Type
| Value | Name | Description |
| ----- | -------------------- | ------------------------------------------------------ |
| 0 | STATUS_PUSH_UNSET | Default unset value (equates to `STATUS_PUSH_ENABLED`) |
| 1 | STATUS_PUSH_ENABLED | Enable custom status push notifications |
| 2 | STATUS_PUSH_DISABLED | Disable custom status push notifications |
###### Privacy Settings Structure
| Field | Type | Description |
| ---------------------------------------------------- | -------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------- |
| allow_activity_party_privacy_friends? | BoolValue | Whether to allow friends to join your activity without sending a request (default true) |
| allow_activity_party_privacy_voice_channel? ^1^ | BoolValue | Whether to allow people in the same voice channel as you to join your activity without sending a request (default true) |
| restricted_guild_ids | array[fixed64] | The IDs of guilds that you will not receive DMs from |
| default_guilds_restricted | boolean | Whether to automatically disable DMs between you and members of new guilds you join (default false) |
| allow_accessibility_detection | boolean | Whether to allow Discord to track screen reader usage (default false) |
| detect_platform_accounts? | BoolValue | Whether to automatically detect accounts from services like Steam and Blizzard when opening the Discord client (default true) |
| passwordless? **(deprecated)** | BoolValue | Whether to enable passwordless login (default true) |
| contact_sync_enabled? | BoolValue | Whether to enable contact sync on Discord mobile (default false) |
| friend_source_flags? | UInt32Value | The user's [friend source flags](#friend-source-flags) (default all) |
| friend_discovery_flags? | UInt32Value | The user's [friend discovery flags](/resources/user-settings#friend-discovery-flags) (default none) |
| activity_restricted_guild_ids | array[fixed64] | The IDs of guilds your activity presence will be hidden in |
| default_guilds_activity_restricted? **(deprecated)** | [guild activity status restriction default](#guild-activity-status-restriction-default) enum | Default activity presence restriction setting for new guilds |
| activity_joining_restricted_guild_ids | array[fixed64] | The IDs of guilds that will not be able to join your current activity |
| message_request_restricted_guild_ids | array[fixed64] | The IDs of guilds whose originating DMs will not be filtered into message requests |
| default_message_request_restricted? | BoolValue | Whether to automatically disable message requests in new guilds (default false) |
| drops_opted_out? **(deprecated)** | BoolValue | Whether to opt out of drops (default false) |
| non_spam_retraining_opt_in? | BoolValue | Whether to help improve Discord spam models when marking messages as non-spam |
| family_center_enabled? **(deprecated)** | BoolValue | Whether the family center sidebar is shown (default true) |
| family_center_enabled_v2? | BoolValue | Whether the family center sidebar is shown (default false) |
| hide_legacy_username? | BoolValue | Whether to hide the user's pre-pomelo username |
| inappropriate_conversation_warnings? | BoolValue | Whether to warn about inappropriate conversations in DMs (default true) |
| recent_games_enabled? | BoolValue | Whether to show recent games on your profile (default true) |
| guilds_leaderboard_opt_out_default | [guilds leaderboard opt out default](#guilds-leaderboard-opt-out-default) enum | Whether to opt out of leaderboards for new guilds by default |
| allow_game_friend_dms_in_discord? | BoolValue | Whether to allow game friend DMs in Discord (default true) |
| default_guilds_restricted_v2? | BoolValue | Whether new guilds are restricted by default (default false) |
| slayer_sdk_receive_dms_in_game | [slayer SDK receive in game DMs](#slayer-sdk-receive-in-game-dms) enum | Setting for receiving in-game DMs via the social layer SDK |
| default_guilds_activity_restricted_v2 | [guild activity status restriction default v2](#guild-activity-status-restriction-default-v2) enum | Default activity presence restriction setting for new guilds |
| quests_3p_data_opted_out? | BoolValue | Whether the user opted out of using third-party data to personalize quests (default false) |
| show_local_time? | BoolValue | Whether to show timestamps in local time (default true) |
| profile_visibility | [profile visibility](#profile-visibility) enum | Profile visibility setting |
| hide_friend_request_notes? | BoolValue | Whether friend request notes are hidden (default false) |
^1^ Does not apply to community guilds.
###### Friend Source Flags
| Value | Name | Description |
| -------- | --------------- | --------------------------------------------------------------- |
| 1 \<\< 1 | MUTUAL_FRIENDS | Whether mutual friends can add the user as friend |
| 1 \<\< 2 | MUTUAL_GUILDS | Whether members in the user's guilds can add the user as friend |
| 1 \<\< 3 | NO_RELATION ^3^ | Whether users with no relation can add the user as friend |
^3^ Requires `MUTUAL_FRIENDS` and `MUTUAL_GUILDS`.
###### Guild Activity Status Restriction Default
| Value | Name | Description |
| ----- | ------------------- | ---------------------------------------------------------- |
| 0 | OFF | Do not restrict activity presence for new guilds |
| 1 | ON_FOR_LARGE_GUILDS | Restrict activity presence for large new guilds by default |
| 2 | ON | Restrict activity presence for all new guilds by default |
###### Guilds Leaderboard Opt Out Default
| Value | Name | Description |
| ----- | ------------------ | ------------------------------------------------------------------ |
| 0 | OFF_FOR_NEW_GUILDS | Do not opt out of leaderboards for new guilds by default (default) |
| 1 | ON_FOR_NEW_GUILDS | Opt out of leaderboards for new guilds by default |
###### Slayer SDK Receive In Game DMs
| Value | Name | Description |
| ----- | --------------- | ---------------------------------------------- |
| 0 | UNSET | Default unset value (equates to `ALL`) |
| 1 | ALL | Receive all in-game DMs |
| 2 | USERS_WITH_GAME | Receive DMs only from users with the same game |
| 3 | NONE | Do not receive any in-game DMs |
###### Guild Activity Status Restriction Default V2
| Value | Name | Description |
| ----- | ----------------------------------- | ---------------------------------------------------------- |
| 0 | ACTIVITY_STATUS_UNSET | Default unset value (depends on regional feature config) |
| 1 | ACTIVITY_STATUS_OFF | Do not restrict activity presence for new guilds |
| 2 | ACTIVITY_STATUS_ON_FOR_LARGE_GUILDS | Restrict activity presence for large new guilds by default |
| 3 | ACTIVITY_STATUS_ON | Restrict activity presence for all new guilds by default |
###### Profile Visibility
| Value | Name | Description |
| ----- | ------------------------ | --------------------------------------------------------- |
| 0 | UNSET | Default unset value (equates to `FRIENDS_AND_ALL_GUILDS`) |
| 1 | FRIENDS_ONLY | Profile visible to friends only |
| 2 | FRIENDS_AND_SMALL_GUILDS | Profile visible to friends and small guilds |
| 3 | FRIENDS_AND_ALL_GUILDS | Profile visible to friends and all guilds |
###### Debug Settings Structure
| Field | Type | Description |
| ---------------------------- | --------- | ------------------------------------------------------------- |
| rtc_panel_show_voice_states? | BoolValue | Whether to show voice states in the RTC panel (default false) |
###### Game Library Settings Structure
| Field | Type | Description |
| ---------------------------- | --------- | ---------------------------------------------------------------- |
| install_shortcut_desktop? | BoolValue | Whether to install desktop shortcuts for games (default false) |
| install_shortcut_start_menu? | BoolValue | Whether to install start menu shortcuts for games (default true) |
| disable_games_tab? | BoolValue | Whether to disable the games tab (default false) |
###### Status Settings Structure
| Field | Type | Description |
| --------------------- | ----------------------------------------- | --------------------------------------------------------------------------------------------------------------------------- |
| status? | StringValue | The [overall status](/resources/presence#status-type) of the user, used to sync presence across clients (default `unknown`) |
| custom_status? | [Custom Status](#custom-status-structure) | The overall custom status of the user, used to sync presence across clients |
| show_current_game? | BoolValue | Whether to display the currently active game in user presence (default true) |
| status_expires_at_ms | fixed64 | Unix timestamp (in milliseconds) of when the status expires |
| status_created_at_ms? | UInt64Value | Unix timestamp (in milliseconds) of when the status was created |
###### Custom Status Structure
| Field | Type | Description |
| ------------- | ------- | ------------------------------------------------------------------------------- |
| text | string | The custom status text |
| emoji_id | fixed64 | The [ID of a guild's custom emoji](/resources/emoji#emoji-object) |
| emoji_name | string | The unicode character of the emoji |
| expires_at_ms | fixed64 | Timestamp (in milliseconds) of when the custom status expires |
| created_at_ms | fixed64 | Timestamp (in milliseconds) of when the custom status was created |
| label | string | The type of [custom status label](/resources/presence#custom-status-label-type) |
###### Localization Settings Structure
| Field | Type | Description |
| ---------------- | ----------- | ------------------------------------------------------------------------------ |
| locale? | StringValue | The [language option](/reference#locales) chosen by the user (default `en-US`) |
| timezone_offset? | Int32Value | The timezone offset from UTC to use (in minutes) |
| timezone_name? | StringValue | The timezone name (e.g. `America/Los_Angeles`) |
###### Appearance Settings Structure
| Field | Type | Description |
| ---------------------------------- | -------------------------------------------------------------------- | ------------------------------------------------------------------- |
| theme | [theme](#theme) enum | The user's [client theme](#theme) |
| developer_mode | boolean | Whether to enable developer mode in-client (default false) |
| client_theme_settings? | [client theme settings](#client-theme-settings-structure) object | Custom theme settings |
| mobile_redesign_disabled | boolean | Whether the mobile redesign is disabled (default false) |
| channel_list_layout? | StringValue | Channel list layout setting |
| message_previews? | StringValue | Message preview setting |
| search_result_exact_count_enabled? | BoolValue | Whether to show exact counts in tabs search results (default false) |
| timestamp_hour_cycle | [timestamp hour cycle](#timestamp-hour-cycle) enum | Timestamp clock cycle format setting |
| happening_now_cards_disabled? | BoolValue | Whether Happening Now cards are disabled (default false) |
| launch_pad_mode | [launch pad mode](#launch-pad-mode) enum | Mobile Launch Pad behavior |
| ui_density | [UI density](#ui-density) enum | UI density setting |
| swipe_right_to_left_mode | [swipe right to left mode](#swipe-right-to-left-mode) enum | Mobile swipe right-to-left behavior |
| default_guild_theme_preference | [guild theme source preference](#guild-theme-source-preference) enum | Default source for guild-specific themes |
| dark_sidebar | boolean | Whether to use a dark sidebar (default false) |
###### Theme
| Value | Name | Description |
| ----- | -------- | --------------------------------------- |
| 0 | UNSET | Default unset value (equates to `DARK`) |
| 1 | DARK | Dark theme |
| 2 | LIGHT | Light theme |
| 3 | DARKER | Darker theme |
| 4 | MIDNIGHT | Midnight theme |
###### Client Theme Settings Structure
| Field | Type | Description |
| ------------------------------ | -------------------------------------------------------------------------- | ----------------------------------------- |
| ~~primary_color?~~ | ~~UInt32Value~~ | ~~The primary color of the client theme~~ |
| background_gradient_preset_id? | UInt32Value | The ID of the background gradient preset |
| ~~background_gradient_angle?~~ | ~~FloatValue~~ | ~~The angle of the background gradient~~ |
| custom_user_theme_settings? | [custom user theme settings](#custom-user-theme-settings-structure) object | Custom user theme settings |
###### Custom User Theme Settings Structure
| Field | Type | Description |
| -------------------- | ------------- | --------------------------------- |
| colors | array[string] | The theme colors |
| gradient_color_stops | array[float] | The gradient color stop positions |
| gradient_angle | int32 | The gradient angle |
| base_mix | int32 | The base color mix |
###### Timestamp Hour Cycle
| Value | Name | Description |
| ----- | ---- | ------------------------------------------------------------ |
| 0 | AUTO | Automatically determine hour cycle based on locale (default) |
| 1 | H12 | Use 12-hour clock |
| 2 | H23 | Use 24-hour clock |
###### Launch Pad Mode
| Value | Name | Description |
| ----- | ------------------- | ------------------------------------- |
| 0 | DISABLED | Disable mobile launch pad (default) |
| 1 | GESTURE_FULL_SCREEN | Enable full-screen gesture launch pad |
| 2 | GESTURE_RIGHT_EDGE | Enable right-edge gesture launch pad |
| 3 | PULL_TAB | Enable pull-tab launch pad |
###### UI Density
| Value | Name | Description |
| ----- | ---------- | ------------------------------------------ |
| 0 | UNSET | Default unset value (equates to `DEFAULT`) |
| 1 | COMPACT | Compact UI density |
| 2 | COZY | Cozy UI density |
| 3 | RESPONSIVE | Responsive UI density |
| 4 | DEFAULT | Default UI density |
###### Swipe Right To Left Mode
| Value | Name | Description |
| ----- | --------------- | ---------------------------------------- |
| 0 | UNSET | Default unset value (equates to `REPLY`) |
| 1 | CHANNEL_DETAILS | Swipe to open channel details |
| 2 | REPLY | Swipe to reply to messages |
###### Guild Theme Source Preference
| Value | Name | Description |
| ----- | ----------- | -------------------------------------------------------------------------------------------------- |
| 0 | UNSPECIFIED | Guild overrides fall back to `default_guild_theme_preference`, which defaults to `GUILD` (default) |
| 1 | PERSONAL | Use the user's personal theme |
| 2 | GUILD | Use the guild's theme |
###### Guild Folders Structure
| Field | Type | Description |
| -------------------------------- | ----------------------------------------------------- | ---------------------------------- |
| folders ^1^ | array[[guild folder](#guild-folder-structure) object] | Guild folders |
| guild_positions **(deprecated)** | array[fixed64] | Positions of guilds in the sidebar |
^1^ This will include guilds that are not in a folder as an anonymous folder with a single entry.
###### Guild Folder Structure
| Field | Type | Description |
| --------- | -------------- | ----------------------------------- |
| guild_ids | array[fixed64] | The IDs of the guilds in the folder |
| id? | Int64Value | The ID of the folder |
| name? | StringValue | The name of the folder |
| color? | UInt64Value | Hex color of the folder |
###### Favorites Structure
| Field | Type | Description |
| ----------------- | -------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------- |
| favorite_channels | map[fixed64, [favorite channel](#favorite-channel-structure) object] | Map of favorite channels |
| muted | boolean | Whether favorites are muted |
| guild_visible? | BoolValue | Whether the favorites guild is visible in the UI (default enabled if `favorite_channels` exist) |
###### Favorite Channel Structure
| Field | Type | Description |
| ------------- | ----------------------------------------------- | --------------------------------------------------------------------- |
| nickname | string | Nickname of the favorite channel |
| type | [favorite channel type](#favorite-channel-type) | Type of the favorite channel |
| position | uint32 | Position of the favorite channel |
| parent_id | fixed64 | Parent ID of the favorite channel |
| channel_type? | UInt32Value | The [type](/resources/channel#channel-type) of the underlying channel |
| collapsed | boolean | Whether the favorite category is collapsed (default false) |
###### Favorite Channel Type
| Value | Description |
| ------------------ | -------------------------- |
| UNSET | Default unset value |
| REFERENCE_ORIGINAL | References a real channel |
| CATEGORY | Contains favorite channels |
###### Audio Settings Structure
| Field | Type | Description |
| ------ | -------------------------------------------------------------- | --------------------------------------- |
| user | map[fixed64, [audio context](#audio-context-structure) object] | Audio context settings for users |
| stream | map[fixed64, [audio context](#audio-context-structure) object] | Audio context settings for user streams |
###### Audio Context Structure
| Field | Type | Description |
| ---------------- | ------- | ---------------------------------------------------------------------- |
| muted | boolean | Whether the audio is muted |
| volume | float | Volume level of the user or stream (0-200) |
| modified_at | fixed64 | Unix timestamp (in milliseconds) of when the setting was last modified |
| soundboard_muted | boolean | Whether the soundboard is muted (user only) |
###### Communities Settings Structure
| Field | Type | Description |
| --------------------------------------- | --------- | --------------------------------------------------------------- |
| disable_home_auto_nav? **(deprecated)** | BoolValue | Whether to disable automatic navigation to Home (default false) |
###### Broadcast Settings Structure
| Field | Type | Description |
| ----------------- | -------------- | ---------------------------------------------------------- |
| allow_friends? | BoolValue | Whether friends are allowed to broadcast to you |
| allowed_guild_ids | array[fixed64] | The IDs of guilds where broadcasting is allowed |
| allowed_user_ids | array[fixed64] | The IDs of users who are allowed to broadcast |
| auto_broadcast? | BoolValue | Whether to automatically start broadcasting upon streaming |
###### Clips Settings Structure
| Field | Type | Description |
| ---------------------- | --------- | ------------------------------------------------------------------ |
| allow_voice_recording? | BoolValue | Whether to allow your voice to be recorded in Clips (default true) |
###### For Later Settings Structure
| Field | Type | Description |
| ----------- | ------------------------------------ | --------------------- |
| current_tab | [for later tab](#for-later-tab) enum | For later tab setting |
###### For Later Tab
| Value | Name | Description |
| ----- | ----------- | -------------------------------------------- |
| 0 | UNSPECIFIED | Default unset value (equates to `ALL`) |
| 1 | ALL | Show all items in the For Later section |
| 2 | BOOKMARKS | Show only bookmarks in the For Later section |
| 3 | REMINDERS | Show only reminders in the For Later section |
###### Safety Settings Structure
| Field | Type | Description |
| --------------------------------- | -------------------------------------------------------------------- | ----------------------------------------------------------------------------------------- |
| safety_settings_preset | [safety settings preset type](#safety-settings-preset-type) | Preset type for safety settings |
| ignore_profile_speedbump_disabled | boolean | Whether to hide the warning shown when viewing a profile you have blocked (default false) |
| spending_limit_settings? | [spending limit settings](#spending-limit-settings-structure) object | User spending limit settings |
###### Safety Settings Preset Type
| Value | Name | Description |
| ----- | -------- | ------------------------ |
| 0 | UNSET | Default unset value |
| 1 | BALANCED | Balanced safety settings |
| 2 | STRICT | Strict safety settings |
| 3 | RELAXED | Relaxed safety settings |
| 4 | CUSTOM | Custom safety settings |
###### Spending Limit Settings Structure
| Field | Type | Description |
| ------------------------ | -------------------------------------------------- | ----------------------- |
| one_time_purchase_limit? | [spending limit](#spending-limit-structure) object | One-time purchase limit |
###### Spending Limit Structure
| Field | Type | Description |
| -------- | ------ | -------------------------------------------------------------------------------- |
| amount | uint64 | The limit amount in the smallest currency unit |
| currency | string | The lower-cased [ISO 4217](https://en.wikipedia.org/wiki/ISO_4217) currency code |
###### ICYMI Settings Structure
| Field | Type | Description |
| ----------------- | ------- | --------------------------------------------------- |
| feed_generated_at | fixed64 | Unix timestamp (in milliseconds) of feed generation |
###### All Application Settings Structure
| Field | Type | Description |
| ------------ | ---------------------------------------------------------------------------- | ------------------------------------------------ |
| app_settings | map[fixed64, [application settings](#application-settings-structure) object] | Application-specific settings per application ID |
###### Application Settings Structure
| Field | Type | Description |
| --------------------- | ------------------------------------------------------------------------------ | ------------------------- |
| app_dm_settings? | [application DM settings](#application-dm-settings-structure) object | DM settings |
| app_sharing_settings? | [application sharing settings](#application-sharing-settings-structure) object | Activity sharing settings |
###### Application DM Settings Structure
| Field | Type | Description |
| ----------------- | ----------- | -------------------------------------------------------------------- |
| ~~dm_disabled~~ | ~~boolean~~ | ~~Whether DMs are disabled for the application (default false)~~ |
| allow_mobile_push | boolean | Whether to allow mobile push notifications for the application's DMs |
###### Application Sharing Settings Structure
| Field | Type | Description |
| ------------------------------------ | ------- | -------------------------------------------------------- |
| disable_application_activity_sharing | boolean | Whether activity sharing is disabled for the application |
###### Ads Settings Structure
| Field | Type | Description |
| -------------- | ------- | ----------------------------- |
| always_deliver | boolean | Whether to always deliver ads |
###### In-App Feedback Settings Structure
| Field | Type | Description |
| ---------------------- | ---------------------------------------------------------------------------- | --------------------------------------------------- |
| in_app_feedback_states | map[int32, [in-app feedback state](#in-app-feedback-state-structure) object] | States of in-app feedback prompts per feedback type |
###### In-App Feedback State Structure
| Field | Type | Description |
| --------------------- | ----------- | --------------------------------------------------------------------- |
| last_impression_time? | UInt64Value | Unix timestamp (in milliseconds) of when the feedback was last shown |
| opt_out_expiry_time? | UInt64Value | Unix timestamp (in milliseconds) of when the feedback opt-out expires |
###### App Version Settings Structure
| Field | Type | Description |
| -------------------------------- | ------- | ---------------------------------------------------------------- |
| is_using_outdated_mobile_version | boolean | Whether the user is using an outdated mobile app (default false) |
### Frecency User Settings Object
Serialized as `discord_protos.discord_users.v1.FrecencyUserSettings`.
###### Frecency User Settings Structure
| Field | Type | Description |
| ---------------------------- | ------------------------------------------------------------------------------ | --------------------------------------------- |
| versions | [versions](#versions-structure) object | Version information for the protocol and data |
| favorite_gifs | [favorite gifs](#favorite-gifs-structure) object | Favorite GIFs storage |
| favorite_stickers | [favorite stickers](#favorite-stickers-structure) object | Favorite stickers storage |
| sticker_frecency | [sticker frecency](#sticker-frecency-structure) object | Sticker frecency storage |
| favorite_emojis | [favorite emojis](#favorite-emojis-structure) object | Favorite emojis settings |
| emoji_frecency | [emoji frecency](#emoji-frecency-structure) object | Emoji frecency storage |
| application_command_frecency | [application command frecency](#application-command-frecency-structure) object | Application command frecency storage |
| favorite_soundboard_sounds | [favorite soundboard sounds](#favorite-soundboard-sounds-structure) object | Favorite soundboard sounds storage |
| application_frecency | [application frecency](#application-frecency-structure) object | Application frecency storage |
| heard_sound_frecency | [heard sound frecency](#heard-sound-frecency-structure) object | Heard soundboard sound frecency storage |
| played_sound_frecency | [played sound frecency](#played-sound-frecency-structure) object | Played soundboard sound frecency storage |
| guild_and_channel_frecency | [guild and channel frecency](#guild-and-channel-frecency-structure) object | Guild and channel frecency storage |
| emoji_reaction_frecency | [emoji reaction frecency](#emoji-reaction-frecency-structure) object | Emoji reaction frecency storage |
###### Frecency Item Structure
| Field | Type | Description |
| ----------- | ------------- | ---------------------------------------------------------------------- |
| total_uses | uint32 | Total uses of the item |
| recent_uses | array[uint64] | Unix timestamps (in milliseconds) representing recent uses of the item |
| frecency | int32 | Frecency score of the item, or `-1` if not applicable |
| score | int32 | Weighted score of the item |
###### Favorite GIFs Structure
| Field | Type | Description |
| ------------ | ----------------------------------------------------------- | --------------------------------------------- |
| gifs | map[string, [favorite GIF](#favorite-gif-structure) object] | Map of GIF URLs to favorite GIFs |
| hide_tooltip | boolean | Whether to hide the tooltip for favorite GIFs |
###### Favorite GIF Structure
| Field | Type | Description |
| ------ | -------------------------- | ---------------------------------------- |
| format | [GIF type](#gif-type) enum | The type of the GIF (`IMAGE` or `VIDEO`) |
| src | string | The media URL of the GIF |
| width | uint32 | The width of the GIF |
| height | uint32 | The height of the GIF |
| order | uint32 | Order of the GIF in the list |
###### GIF Type
| Value | Name | Description |
| ----- | ----- | ------------------- |
| 0 | NONE | Default unset value |
| 1 | IMAGE | Image GIF |
| 2 | VIDEO | Video GIF |
###### Favorite Stickers Structure
| Field | Type | Description |
| ----------- | -------------- | --------------------------------------- |
| sticker_ids | array[fixed64] | The IDs of the user's favorite stickers |
###### Sticker Frecency Structure
| Field | Type | Description |
| -------- | -------------------------------------------------------------- | ----------------------------- |
| stickers | map[fixed64, [frecency item](#frecency-item-structure) object] | Map of sticker frecency items |
###### Favorite Emojis Structure
| Field | Type | Description |
| ------ | ------------- | --------------------------------------------------------------------------------------------------- |
| emojis | array[string] | The user's favorite emoji, represented as snowflake IDs or friendly names (e.g. `skull_crossbones`) |
###### Emoji Frecency Structure
| Field | Type | Description |
| ------ | ------------------------------------------------------------- | --------------------------------------------------------------------------------------------- |
| emojis | map[string, [frecency item](#frecency-item-structure) object] | Frecenct used emoji, represented as snowflake IDs or friendly names (e.g. `skull_crossbones`) |
###### Application Command Frecency Structure
| Field | Type | Description |
| -------------------- | ------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| application_commands | map[string, [frecency item](#frecency-item-structure) object] | Frecent application commands, represented as snowflake command IDs with optional null-joined command names and colon-joined guild IDs (e.g. `1221148400637050941\u0000set:550327071407079444`) |
###### Favorite Soundboard Sounds Structure
| Field | Type | Description |
| --------- | -------------- | ------------------------------------------------ |
| sound_ids | array[fixed64] | The IDs of the user's favorite soundboard sounds |
###### Application Frecency Structure
| Field | Type | Description |
| ------------ | ------------------------------------------------------------- | -------------------------------------------------- |
| applications | map[string, [frecency item](#frecency-item-structure) object] | Frecent applications, represented as snowflake IDs |
###### Heard Sound Frecency Structure
| Field | Type | Description |
| ------------ | ------------------------------------------------------------- | ------------------------------------------------------------- |
| heard_sounds | map[string, [frecency item](#frecency-item-structure) object] | Frecent heard soundboard sounds, represented as snowflake IDs |
###### Played Sound Frecency Structure
| Field | Type | Description |
| ------------- | ------------------------------------------------------------- | -------------------------------------------------------------- |
| played_sounds | map[string, [frecency item](#frecency-item-structure) object] | Frecent played soundboard sounds, represented as snowflake IDs |
###### Guild and Channel Frecency Structure
| Field | Type | Description |
| ------------------ | -------------------------------------------------------------- | ---------------------- |
| guild_and_channels | map[fixed64, [frecency item](#frecency-item-structure) object] | Frecent guild channels |
###### Emoji Reaction Frecency Structure
| Field | Type | Description |
| ------ | ------------------------------------------------------------- | ------------------------------------------------------------------------------------------------ |
| emojis | map[string, [frecency item](#frecency-item-structure) object] | Frecent used reactions, represented as snowflake IDs or friendly names (e.g. `skull_crossbones`) |
## Endpoints
Get User Settings Proto
Returns the requester's [user settings protobuf](#user-settings-proto-type) for the specified type.
###### Response Body
| Field | Type | Description |
| -------- | ------ | ---------------------------------------------------- |
| settings | string | The base64-encoded serialized user settings protobuf |
Modify User Settings Proto
Modifies the requester's user settings protobuf for the specified type. Fires a [User Settings Proto Update](/gateway/gateway-events#user-settings-proto-update) and [User Settings Update](/gateway/gateway-events#user-settings-update) Gateway event.
When updating protobuf user settings, the entire top-level field being modified must be sent, or any subfields not sent will be reset to their default values.
For example, if updating `PreloadedUserSettings.AppearanceSettings.developer_mode`, the entire `PreloadedUserSettings.AppearanceSettings` field must be sent, or everything in it will be reset.
Unchanged top-level fields can be omitted from the request.
This endpoint is ratelimited heavily. Updates should be batched together and sent at intervals.
Infrequent actions do not need a delay. Frequent actions should be delayed by 10 seconds and batched.
Automated actions (such as migrations or frecency updates) should be delayed by 30 seconds and batched.
Daily actions (things that change often and are not meaningful, such as emoji frencency) should be delayed by 1 day and batched.
###### JSON Params
| Field | Type | Description |
| -------------------------- | ------- | -------------------------------------------------------------------------------------------- |
| settings | string | The base-64 encoded serialized user settings protobuf modifications (max 5242880 characters) |
| required_data_version? ^1^ | integer | The required data version of the proto |
^1^ When making offline edits, the required data version of the proto should be set to the last known version. This ensures that the client doesn't overwrite newer edits made on a different client on edit.
###### Response Body
| Field | Type | Description |
| ------------ | ------- | ----------------------------------------------------------------------------------------- |
| settings | string | The base-64 encoded serialized user settings protobuf |
| out_of_date? | boolean | Whether the user settings update was discarded due to an outdated `required_data_version` |
---
# Emoji
Link: https://docs.discord.food/resources/emoji
Emoji are small images that can be used to convey an idea or emotion. Discord allows users to upload custom emoji to guilds and use them like normal emoji in-chat and when reacting to messages.
### Emoji Object
###### Emoji Structure
| Field | Type | Description |
| --------------- | -------------------------------------------------- | ------------------------------------------------------------------------------------------ |
| id | ?snowflake | The [ID of the emoji](/reference#cdn-formatting) |
| name ^2^ | string | The name of the emoji (2-32 characters) |
| roles? | array[snowflake] | The roles allowed to use the emoji |
| user? ^1^ | partial [user](/resources/user#user-object) object | The user that uploaded the emoji |
| require_colons? | boolean | Whether this emoji must be wrapped in colons |
| managed? | boolean | Whether this emoji is managed |
| animated? | boolean | Whether this emoji is animated |
| available? | boolean | Whether this emoji can be used; may be false due to loss of premium subscriptions (boosts) |
| version? ^3^ | string | The version of the guild, serialized as a stringified integer |
^1^ Only included for emoji when fetched through the [List Guild Emojis](#list-guild-emojis) or [Get Guild Emoji](#get-guild-emoji) endpoints by a user with the `MANAGE_EXPRESSIONS` permission. Always included when fetched from [List Application Emojis](#list-application-emojis) or [Get Application Emoji](#get-application-emoji).
^2^ This may be `null` in the case of a custom emoji that has been deleted.
^3^ Only included within the [Guild Emojis Update](/gateway/gateway-events#guild-emojis-update) Gateway events.
###### Emoji Formats
Emoji can be uploaded as JPEG, PNG, GIF, WebP, and AVIF formats. WebP and AVIF formats are only served as WebP since they don’t convert well to other formats. All emoji (regardless of original format) can be served as WebP.
Discord recommends that developers use the `.webp` extension when fetching emoji so they’re rendered as WebP for maximum performance and compatibility. The Discord client uses WebP for all emoji displayed in-app.
Static WebP emoji can be requested using the `.webp` file extension. For animated WebP emoji, use the `.webp` extension with the `?animated=true` query parameter.
###### Premium Emoji
Roles with the `integration_id` tag being the guild's `guild_subscription` integration are considered subscription roles.
An emoji cannot have both subscription roles and non-subscription roles.
Emoji with subscription roles are considered premium emoji, and count toward a separate limit of 25.
Emoji cannot be converted between normal and premium after creation.
###### Application Emoji
An application can own up to 2,000 emoji that can only be used by the app.
The `USE_EXTERNAL_EMOJIS` permission is not required to use these emoji.
These emoji do not support role-locking and always require colons. They are never managed or unavailable.
###### Emoji Example
```json
{
"id": "41771983429993937",
"name": "LUL",
"roles": ["41771983429993000", "41771983429993111"],
"user": {
"id": "306810730055729152",
"username": "owoer",
"avatar": "b3028be18dc56db5722bd750cf69df4e",
"discriminator": "0",
"public_flags": 4194816,
"banner": null,
"accent_color": null,
"global_name": "Eon",
"avatar_decoration_data": null,
"primary_guild": null
},
"require_colons": true,
"managed": false,
"animated": false
}
```
###### Gateway Reaction Standard Emoji Example
```json
{
"id": null,
"name": "🔥"
}
```
###### Gateway Reaction Custom Emoji Examples
In [Message Reaction Add](/gateway/gateway-events#message-reaction-add) events `animated` will be returned for animated emoji.
```json
{
"id": "41771983429993937",
"name": "LUL",
"animated": true
}
```
```json
{
"id": "41771983429993937",
"name": null
}
```
## Endpoints
List Guild Emojis
Returns a list of [emoji](#emoji-object) objects for the given guild. Includes the `user` field if the user has the `CREATE_EXPRESSIONS` or `MANAGE_EXPRESSIONS` permission.
Get Guild Emoji
Returns an [emoji](#emoji-object) object for the given guild and emoji IDs. Includes the `user` field if the user has the `CREATE_EXPRESSIONS` or `MANAGE_EXPRESSIONS` permission.
List Guild Top Emojis
Returns the most-used emojis for the given guild.
###### Response Body
| Field | Type | Description |
| ----- | ----------------------------------------------- | ---------------------------------- |
| items | array[[top emoji](#top-emoji-structure) object] | The most-used emojis for the guild |
###### Top Emoji Structure
| Field | Type | Description |
| ---------- | --------- | ----------------------------- |
| emoji_id | snowflake | The ID of the emoji |
| emoji_rank | integer | The overall rank of the emoji |
###### Example Response
```json
{
"items": [
{
"emoji_id": "1145727546747535412",
"emoji_rank": 1
},
{
"emoji_id": "1174435954090594505",
"emoji_rank": 2
},
{
"emoji_id": "1029462631163117629",
"emoji_rank": 3
},
{
"emoji_id": "1030570693903011921",
"emoji_rank": 4
},
{
"emoji_id": "1077714345825407067",
"emoji_rank": 5
}
]
}
```
Get Emoji Guild
Returns a [discoverable guild](/resources/discovery#discoverable-guild-object) object for the guild that owns the given emoji. This endpoint requires the guild to be discoverable, not be [auto-removed](/resources/discovery#discoverable-guild-object), and have [guild expression discoverability](/resources/discovery#discovery-metadata-object) enabled.
Get Emoji Source
Returns an object containing information on the guild or application that owns the given emoji. If the source is a guild, this endpoint requires the guild to be discoverable, not be [auto-removed](/resources/discovery#discoverable-guild-object), and have [guild expression discoverability](/resources/discovery#discovery-metadata-object) enabled.
###### Response Body
| Field | Type | Description |
| ----------- | --------------------------------------------------------- | ---------------------------------------------- |
| type | string | The [type of emoji source](#emoji-source-type) |
| guild | ?[emoji guild](#emoji-guild-structure) object | The guild that owns the given emoji |
| application | ?[emoji application](#emoji-application-structure) object | The application that owns the given emoji |
###### Emoji Source Type
| Value | Description |
| ----------- | --------------------------------------- |
| GUILD | The emoji is uploaded to a guild |
| APPLICATION | The emoji is uploaded to an application |
###### Emoji Guild Structure
| Field | Type | Description |
| -------------------------- | ---------------------------------------------------- | ----------------------------------------------------------------------- |
| id | snowflake | The ID of the guild |
| name | string | The name of the guild (2-100 characters) |
| icon | ?string | The guild's [icon hash](/reference#cdn-formatting) |
| description | ?string | The description for the guild (max 300 characters) |
| features | array[string] | Enabled [guild features](/resources/guild#guild-features) |
| emojis | array[[emoji](/resources/emoji#emoji-object) object] | Custom guild emoji |
| premium_tier | integer | The guild's [premium tier](/resources/guild#premium-tier) (boost level) |
| premium_subscription_count | integer | The number of premium subscriptions (boosts) the guild currently has |
| approximate_member_count | integer | Approximate number of total members in the guild |
| approximate_presence_count | integer | Approximate number of non-offline members in the guild |
###### Emoji Application Structure
| Field | Type | Description |
| ----- | --------- | --------------------------- |
| id | snowflake | The ID of the application |
| name | string | The name of the application |
###### Example Response
```json
{
"guild": {
"id": "322850917248663552",
"name": "Official Fortnite",
"icon": "39e9f70c87a3d20dfe02e5f013b417f4",
"emojis": [],
"approximate_member_count": 1068003,
"approximate_presence_count": 163598,
"description": "The Official Fortnite Discord Server! Join to follow news & updates, LFG, and chat about Fortnite Battle Royale.",
"features": [],
"premium_subscription_count": 378,
"premium_tier": 3
},
"application": null,
"type": "GUILD"
}
```
Create Guild Emoji
Creates a new emoji for the guild. Requires the `CREATE_EXPRESSIONS` permission. Returns the new [emoji](#emoji-object) object on success. Fires a [Guild Emojis Update](/gateway/gateway-events#guild-emojis-update) Gateway event.
Emoji have a maximum file size of **256 KiB**. Attempting to upload an emoji larger than this limit will fail with a 400 bad request.
Each guild has limits for each type of emoji. The types, or buckets, are:
- **Normal emoji**: Default non-animated emoji
- **Animated emoji**: Animated emoji
- **Premium emoji**: Emoji that is locked to role subscriptions
The default emoji limit is 50. For normal and animated emoji, the maximum is applied individually, and depends on the guild's [premium tier](https://support.discord.com/hc/en-us/articles/360028038352) and [features](/resources/guild#guild-features). Therefore, the maximum number of emoji is calculated as follows:
- **Normal emoji**: `max(50 * (premium_tier + 1), features.has("MORE_EMOJI") ? 200 : premium_tier == 3 ? 250 : 50)`
- **Animated emoji**: `max(50 * (premium_tier + 1), features.has("MORE_EMOJI") ? 200 : premium_tier == 3 ? 250 : 50)`
- **Premium emoji**: `25` (constant)
If this is confusing, the limits are also summarized in the following table by [premium tier](/resources/guild#premium-tier). Note that if the guild has the [`MORE_EMOJI` feature](/resources/guild#guild-features), the normal and animated limit is instead 200.
| Premium Tier | Normal Emoji | Animated Emoji | Premium Emoji |
| ------------ | ------------ | -------------- | ------------- |
| `NONE` | 50 | 50 | 25 |
| `TIER_1` | 100 | 100 | 25 |
| `TIER_2` | 150 | 150 | 25 |
| `TIER_3` | 250 | 250 | 25 |
###### JSON Params
| Field | Type | Description |
| ------ | --------------------------------- | --------------------------------------- |
| name | string | The name of the emoji (2-32 characters) |
| image | [image data](/reference#cdn-data) | 128x128 emoji image |
| roles? | array[snowflake] | The roles allowed to use this emoji |
Modify Guild Emoji
Modifies the given emoji. For emoji created by the current user, requires either the `CREATE_EXPRESSIONS` or `MANAGE_EXPRESSIONS` permission. For other emojis, requires the `MANAGE_EXPRESSIONS` permission. Returns the updated [emoji](#emoji-object) object on success. Fires a [Guild Emojis Update](/gateway/gateway-events#guild-emojis-update) Gateway event.
###### JSON Params
| Field | Type | Description |
| ------ | ----------------- | --------------------------------------- |
| name? | string | The name of the emoji (2-32 characters) |
| roles? | ?array[snowflake] | The roles allowed to use this emoji |
Delete Guild Emoji
Deletes the given emoji. For emoji created by the current user, requires either the `CREATE_EXPRESSIONS` or `MANAGE_EXPRESSIONS` permission. For other emojis, requires the `MANAGE_EXPRESSIONS` permission. Returns a 204 empty response on success. Fires a [Guild Emojis Update](/gateway/gateway-events#guild-emojis-update) Gateway event.
List Application Emojis
Returns an object containing a list of [emoji](#emoji-object) objects for the given application under the `items` key. Includes the `user` field.
###### Response Body
| Field | Type | Description |
| ----- | ------------------------------------ | ------------------------------------- |
| items | array[[emoji](#emoji-object) object] | The emoji uploaded to the application |
Get Application Emoji
Returns an [emoji](#emoji-object) object for the given application and emoji IDs. Includes the `user` field.
Create Application Emoji
Creates a new emoji for the application. Returns the new [emoji](#emoji-object) object on success.
The names of application emoji must be unique.
Emoji have a maximum file size of **256 KiB**. Attempting to upload an emoji larger than this limit will fail with a 400 bad request.
Applications may have a maximum of 2,000 emoji.
###### JSON Params
| Field | Type | Description |
| -------- | --------------------------------- | --------------------------------------- |
| name ^1^ | string | The name of the emoji (2-32 characters) |
| image | [image data](/reference#cdn-data) | 128x128 emoji image |
^1^ The names of application emoji must be unique.
Modify Application Emoji
Modifies the given emoji. Returns the updated [emoji](#emoji-object) object on success.
The names of application emoji must be unique.
###### JSON Params
| Field | Type | Description |
| --------- | ------ | --------------------------------------- |
| name? ^1^ | string | The name of the emoji (2-32 characters) |
Delete Application Emoji
Deletes the given emoji. Returns a 204 empty response on success.
---
# Stickers
Link: https://docs.discord.food/resources/sticker
Stickers are embedded images that can be sent along with messages. They can be either standard stickers, which are official, first-party stickers, or guild stickers, which are custom stickers uploaded by users in a guild.
### Sticker Pack Object
A pack of standard stickers.
###### Sticker Pack Structure
| Field | Type | Description |
| ----------------- | ---------------------------------------- | ---------------------------------------------------------------------- |
| id | snowflake | The ID of the sticker pack |
| stickers | array[[sticker](#sticker-object) object] | The stickers in the pack |
| name | string | The name of the sticker pack |
| sku_id | snowflake | The ID of the pack's SKU |
| cover_sticker_id? | snowflake | The ID of a sticker in the pack which is shown as the pack's icon |
| description | string | The description for the sticker pack |
| banner_asset_id? | snowflake | The ID of the sticker pack's [banner image](/reference#cdn-formatting) |
###### Example Sticker Pack
```json
{
"id": "847199849233514549",
"stickers": [],
"name": "Wumpus Beyond",
"sku_id": "847199849233514547",
"cover_sticker_id": "749053689419006003",
"description": "Say hello to Wumpus!",
"banner_asset_id": "761773777976819732"
}
```
### Sticker Object
A sticker that can be sent in messages.
###### Sticker Structure
| Field | Type | Description |
| ------------ | -------------------------------------------------- | -------------------------------------------------------------------------------------------------- |
| id | snowflake | The [ID of the sticker](/reference#cdn-formatting) |
| pack_id? | snowflake | For standard stickers, ID of the pack the sticker is from |
| name | string | The name of the sticker (2-30 characters) |
| description | ?string | The description for the sticker (max 100 characters) |
| tags ^2^ | string | Autocomplete/suggestion tags for the sticker (1-200 characters) |
| type | integer | The [type of sticker](#sticker-types) |
| format_type | integer | The [type of format](#sticker-format-types) for the sticker |
| available? | boolean | Whether this guild sticker can be used; may be false due to loss of premium subscriptions (boosts) |
| guild_id? | snowflake | The ID of the guild the sticker is attached to |
| user? ^1^ | partial [user](/resources/user#user-object) object | The user that uploaded the guild sticker |
| sort_value? | integer | The standard sticker's sort order within its pack |
| version? ^3^ | string | The version of the guild, serialized as a stringified integer |
^1^ Only included for guild stickers when fetched through the [List Guild Stickers](#list-guild-stickers) or [Get Guild Sticker](#get-guild-sticker) endpoints by a user with the `MANAGE_EXPRESSIONS` permission.
^2^ A comma separated list of keywords is the format used in this field by standard stickers, but this is just a convention.
Incidentally, official clients will always use a name generated from an emoji as the value of this field when creating or modifying a guild sticker.
^3^ Only included within the [Guild Stickers Update](/gateway/gateway-events#guild-stickers-update) Gateway events.
###### Sticker Types
| Value | Name | Description |
| ----- | -------- | ----------------------------------------------------------- |
| 1 | STANDARD | An official sticker in a current or legacy purchasable pack |
| 2 | GUILD | A sticker uploaded to a guild for the guild's members |
###### Sticker Format Types
GIF stickers are not available through the [CDN](/reference#cdn-formatting), and must be accessed at `https://media.discordapp.net/stickers/{sticker_id}.gif`.
| Value | Name | Description |
| ----- | ------ | ------------------------------------------------------------------------------------------------------------------------------------------------ |
| 1 | PNG | A PNG image |
| 2 | APNG | An animated PNG image, using the APNG format |
| 3 | LOTTIE | A [lottie](https://airbnb.design/lottie/) animation; requires the `VERIFIED` and/or `PARTNERED` [guild feature](/resources/guild#guild-features) |
| 4 | GIF | An animated GIF image |
###### Example Sticker
```json
{
"id": "749054660769218631",
"name": "Wave",
"tags": "wumpus, hello, sup, hi, oi, heyo, heya, yo, greetings, greet, welcome, wave, :wave, :hello, :hi, :hey, hey, \ud83d\udc4b, \ud83d\udc4b\ud83c\udffb, \ud83d\udc4b\ud83c\udffc, \ud83d\udc4b\ud83c\udffd, \ud83d\udc4b\ud83c\udffe, \ud83d\udc4b\ud83c\udfff, goodbye, bye, see ya, later, laterz, cya",
"type": 1,
"format_type": 3,
"description": "Wumpus waves hello",
"asset": "",
"pack_id": "847199849233514549",
"sort_value": 12
}
```
### Sticker Item Object
The smallest amount of data required to render a sticker. A partial sticker object.
###### Sticker Item Structure
| Field | Type | Description |
| ----------- | --------- | ----------------------------------------------------------- |
| id | snowflake | The [ID of the sticker](/reference#cdn-formatting) |
| name | string | The name of the sticker |
| format_type | integer | The [type of format](#sticker-format-types) for the sticker |
## Endpoints
List Sticker Packs
Returns the list of [sticker packs](#sticker-pack-object) available to use.
###### Response Body
| Field | Type | Description |
| ------------- | -------------------------------------------------- | --------------------------- |
| sticker_packs | array[[sticker pack](#sticker-pack-object) object] | The sticker packs available |
Get Sticker Pack
Returns a [sticker pack](#sticker-pack-object) object for the given pack ID.
Get Sticker
Returns a [sticker](#sticker-object) object for the given sticker ID.
Get Sticker Guild
Returns a [discoverable guild](/resources/discovery#discoverable-guild-object) object for the guild that owns the given sticker. This endpoint requires the guild to be discoverable, not be [auto-removed](/resources/discovery#discoverable-guild-object), and have [guild expression discoverability](/resources/discovery#discovery-metadata-object) enabled.
List Guild Stickers
Returns an array of [sticker](#sticker-object) objects for the given guild. Includes the `user` field if the user has the `CREATE_EXPRESSIONS` or `MANAGE_EXPRESSIONS` permission.
Get Guild Sticker
Returns a [sticker](#sticker-object) object for the given guild and sticker IDs. Includes the `user` field if the user has the `CREATE_EXPRESSIONS` or `MANAGE_EXPRESSIONS` permission.
Create Guild Sticker
Creates a new sticker for the guild. Must be a `multipart/form-data` body. Requires the `CREATE_EXPRESSIONS` permission. Returns the new [sticker](#sticker-object) object on success. Fires a [Guild Stickers Update](/gateway/gateway-events#guild-stickers-update) Gateway event.
Every guilds has five free sticker slots by default, and each premium tier (boost level) will grant access to more slots.
Lottie stickers can only be uploaded on guilds that have either the `VERIFIED` and/or `PARTNERED` [guild feature](/resources/guild#guild-features).
Stickers have a maximum file size of **500 KiB** (**1.5 MiB** for employees). Attempting to upload a sticker larger than this limit will fail with a 400 bad request.
Sticker limits are applied to the total amount of stickers in the guild, making them a lot simpler than emoji limits. The default sticker limit is 50.
The real limit depends on the guild's [premium tier](https://support.discord.com/hc/en-us/articles/360028038352) and [features](/resources/guild#guild-features).
These limits are summarized in the following table by [premium tier](/resources/guild#premium-tier). Note that if the guild has the [`MORE_STICKERS` feature](/resources/guild#guild-features), the applied limit is always the tier 3 one (60).
| Premium Tier | Sticker Limit |
| ------------ | ------------- |
| `NONE` | 5 |
| `TIER_1` | 15 |
| `TIER_2` | 30 |
| `TIER_3` | 60 |
###### Form Params
| Field | Type | Description |
| ----------- | ------------- | ------------------------------------------------------------------------- |
| name | string | The name of the sticker (2-30 characters) |
| description | string | The description for the sticker (max 100 characters) |
| tags | string | Autocomplete/suggestion tags for the sticker (1-200 characters) |
| file | file contents | The sticker file to upload, must be a PNG, APNG, GIF, or Lottie JSON file |
Modify Guild Sticker
Modifies the given sticker. For stickers created by the current user, requires either the `CREATE_EXPRESSIONS` or `MANAGE_EXPRESSIONS` permission. For other stickers, requires the `MANAGE_EXPRESSIONS` permission. Returns the updated [sticker](#sticker-object) object on success. Fires a [Guild Stickers Update](/gateway/gateway-events#guild-stickers-update) Gateway event.
###### JSON Params
| Field | Type | Description |
| ------------ | ------- | --------------------------------------------------------------- |
| name? | string | The name of the sticker (2-30 characters) |
| description? | ?string | The description for the sticker (max 100 characters) |
| tags? | string | Autocomplete/suggestion tags for the sticker (1-200 characters) |
Delete Guild Sticker
Deletes the given sticker. For stickers created by the current user, requires either the `CREATE_EXPRESSIONS` or `MANAGE_EXPRESSIONS` permission. For other stickers, requires the `MANAGE_EXPRESSIONS` permission. Returns a 204 empty response on success. Fires a [Guild Stickers Update](/gateway/gateway-events#guild-stickers-update) Gateway event.
---
# Billing
Link: https://docs.discord.food/resources/billing
Discord supports a variety of payment providers to enable billing for first-party and third-party monetization.
### Payment Source Object
###### Payment Source Structure
| Field | Type | Description |
| -------------------------- | --------------------------------------------- | ----------------------------------------------------------------------------- |
| id | snowflake | The ID of the payment source |
| brand? | string | The brand of the payment source (only applicable for credit cards) |
| country? | string | The country of the payment source |
| last_4? | string | The last four digits of the payment source (only applicable for credit cards) |
| billing_address ^1^ | [billing address](#billing-address-structure) | The billing address of the payment source |
| type | integer | The [type of the payment source](#payment-source-type) |
| payment_gateway | integer | The [payment gateway](#payment-gateway) of the payment source |
| payment_gateway_source_id? | string | The ID of the payment source in the payment gateway |
| default ^1^ | boolean | Whether the payment source is the default payment source |
| invalid | boolean | Whether the payment source is invalid |
| flags | integer | The [payment source's flags](#payment-source-flags) |
| deleted_at | ?ISO8601 timestamp | When the payment source was deleted at |
| expires_month? | integer | The month the credit card expires at |
| expires_year? | integer | The year the credit card expires at |
| email? | string | The email address associated with the payment source |
| bank? | string | The bank associated with the payment source |
| username? | string | The username associated with the payment source (only applicable for Venmo) |
^1^ Not available in payment objects.
###### Example Payment Source
```json
{
"id": "1422548914485198869",
"type": 1,
"invalid": false,
"flags": 0,
"deleted_at": null,
"brand": "visa",
"last_4": "4242",
"expires_month": 9,
"expires_year": 2077,
"billing_address": {
"name": "John Doe",
"line_1": "123 Main Street",
"line_2": "Apt 4B",
"city": "San Francisco",
"state": "CA",
"country": "US",
"postal_code": "94105"
},
"country": "US",
"payment_gateway": 1,
"payment_gateway_source_id": "pm_DwiVlGlYwe1qxLzy4QWChQeo",
"default": false
}
```
###### Billing Address Structure
| Field | Type | Description |
| ------------ | ------- | ------------------------------------- |
| line_1 | string | The address of the location |
| line_2? | ?string | The secondary address of the location |
| name | string | The name of the payment source |
| postal_code? | string | The postal code of the location |
| city | string | The city of the location |
| state? | string | The state or province of the location |
| country | string | The country of the location |
###### PIX Payment Metadata Structure
| Field | Type | Description |
| ------- | ------ | ---------------------------- |
| tax_id? | string | The PIX tax ID for the payer |
###### Payment Source Type
| Value | Name | Description |
| ----- | ----------------------- | ------------------ |
| 1 | CARD | Credit card |
| 2 | PAYPAL | PayPal |
| 3 | GIROPAY | Giropay |
| 4 | SOFORT **(deprecated)** | Sofort |
| 5 | PRZELEWY24 | Przelewy24 |
| 6 | SEPA_DEBIT | SEPA debit |
| 7 | PAYSAFE_CARD | Paysafe |
| 8 | GCASH | GCash |
| 9 | GRABPAY_MY | GrabPay (Malaysia) |
| 10 | MOMO_WALLET | MoMo Wallet |
| 11 | VENMO | Venmo |
| 12 | GOPAY_WALLET | GoPay Wallet |
| 13 | KAKAOPAY | KakaoPay |
| 14 | BANCONTACT | Bancontact |
| 15 | EPS | EPS |
| 16 | IDEAL | iDEAL |
| 17 | CASH_APP | Cash App |
| 18 | APPLE | Apple Pay |
| 19 | TDS_WALLET | TDS Wallet |
###### Payment Gateway
| Value | Name | Description |
| ----- | ----------------------- | ----------------------- |
| 1 | STRIPE | Stripe |
| 2 | BRAINTREE | Braintree |
| 3 | APPLE | Apple |
| 4 | GOOGLE | Google |
| 5 | ADYEN | Adyen |
| 6 | APPLE_PARTNER | Apple Pay |
| 7 | AMAZON | Amazon Pay |
| 8 | VIRTUAL_CURRENCY ^1^ | Orbs |
| 9 | APPLE_ADVANCED_COMMERCE | Apple Advanced Commerce |
| 10 | TDS | TDS |
^1^ Payment gateway is internal and cannot be used directly.
###### Payment Source Flags
| Value | Name | Description |
| -------- | ------------------ | ------------------------------------------------------- |
| 1 \<\< 0 | NEW | Payment source is new |
| 1 \<\< 1 | SUCCESSFUL_PAYMENT | Payment source has been successfully used at least once |
### Gateway Checkout Context Object
###### Gateway Checkout Context Structure
| Field | Type | Description |
| ---------------------- | ------- | --------------------------------------------------- |
| braintree_device_data? | ?string | The Braintree device data collected during checkout |
### User Trial Offer Object
###### User Trial Offer Structure
| Field | Type | Description |
| ------------------ | ------------------------------------------------------------------------------ | ---------------------------------------------------------- |
| id | snowflake | The ID of the user trial offer |
| user_id | snowflake | The ID of the user the offer is for |
| trial_id | snowflake | The ID of the subscription trial associated with the offer |
| expires_at ^1^ | ?ISO8601 timestamp | When the trial offer expires |
| subscription_trial | [subscription trial](/resources/subscription#subscription-trial-object) object | The subscription trial associated with the offer |
^1^ Trial offers only gain an expiration date when they are [acknowledged](#acknowledge-user-offer).
###### Example User Trial Offer
```json
{
"id": "1433666591022645361",
"user_id": "852892297661906993",
"trial_id": "1073698058383917056",
"subscription_trial": {
"id": "1073698058383917056",
"interval": 3,
"interval_count": 14,
"sku_id": "521847234246082599"
},
"expires_at": "2025-11-04T07:26:18.125782+00:00"
}
```
### User Discount Offer Object
###### User Discount Offer Structure
| Field | Type | Description |
| --------------- | -------------------------------------- | ------------------------------------------------ |
| id | snowflake | The ID of the user discount offer |
| discount_id | snowflake | The ID of the discount associated with the offer |
| user_id | snowflake | The ID of the user the offer is for |
| invoice_id? ^1^ | ?snowflake | The ID of the invoice the offer was applied to |
| created_at? ^1^ | ?ISO8601 timestamp | When the offer was created |
| applied_at | ?ISO8601 timestamp | When the offer was applied |
| deleted_at? ^1^ | ?ISO8601 timestamp | When the offer was deleted |
| expires_at ^2^ | ?ISO8601 timestamp | When the offer expires |
| discount | [discount](#discount-structure) object | The discount associated with the offer |
^1^ These fields are only present for applied offers.
^2^ Discount offers only gain an expiration date when they are [acknowledged](#acknowledge-user-offer).
###### Discount Structure
| Field | Type | Description |
| ------------------------------- | ------------------ | -------------------------------------------------------------------------- |
| id | snowflake | The ID of the discount |
| amount | integer | The discount amount in the smallest currency unit |
| starts_at? | ?ISO8601 timestamp | When the discount starts |
| ends_at? | ?ISO8601 timestamp | When the discount ends |
| status | integer | The [status of the discount](#discount-status) |
| created_at | ISO8601 timestamp | When the discount was created |
| sku_ids | ?array[snowflake] | The IDs of the subscription SKUs the discount applies to |
| sku_group_ids | ?array[snowflake] | The IDs of the subscription SKU groups the discount applies to |
| plan_ids | array[snowflake] | The IDs of the plans the discount applies to |
| user_usage_limit_interval | integer | The [interval](/resources/store#subscription-interval) for the usage limit |
| user_usage_limit_interval_count | integer | The number of intervals before the usage limit resets |
| user_usage_limit | integer | The maximum number of times a user can use the discount |
###### Discount Status
The values of this enum are currently unknown. Help us by figuring them out and [submitting a pull request](https://github.com/discord-userdoccers/discord-userdoccers/edit/master/pages/resources/billing.mdx)!
###### Example User Discount Offer
```json
{
"id": "1433666591022645360",
"user_id": "852892297661906993",
"discount_id": "1204865493622587392",
"applied_at": null,
"expires_at": "2025-11-04T07:26:18.125782+00:00",
"discount": {
"id": "1204865493622587392",
"amount": 30,
"starts_at": null,
"ends_at": null,
"status": 2,
"created_at": "2024-02-08T16:44:28.903181+00:00",
"sku_ids": null,
"sku_group_ids": null,
"plan_ids": ["511651880837840896"],
"user_usage_limit_interval": 3,
"user_usage_limit_interval_count": 1,
"user_usage_limit": 1
}
}
```
## Endpoints
Get Billing Country Code
Returns the user's country code based on requesting IP address.
###### Response Body
| Field | Type | Description |
| ------------ | ------ | --------------------------------------------------------------------------------------- |
| country_code | string | The [ISO 3166-1 alpha-2](https://en.wikipedia.org/wiki/ISO_3166-1_alpha-2) country code |
Get Billing Location Info
Returns the user's country and subdivision code based on requesting IP address.
###### Response Body
| Field | Type | Description |
| ---------------- | ------- | --------------------------------------------------------------------------------------- |
| country_code | string | The [ISO 3166-1 alpha-2](https://en.wikipedia.org/wiki/ISO_3166-1_alpha-2) country code |
| subdivision_code | ?string | The [ISO 3166-2](https://en.wikipedia.org/wiki/ISO_3166-2) subdivision code |
List Payment Sources
Returns a list of [payment source](#payment-source-object) objects. Note that the `billing_address` fields within these objects will be partial for security reasons, containing only `name` and `country`.
Get Payment Source
Returns a [payment source](#payment-source-object) object for a given payment source ID.
Get Payment Source Creation Context
Returns information about which payment source types and billing address countries are available to the current user.
###### Response Body
| Field | Type | Description |
| --------------------------------- | -------------- | ------------------------------------------------------------------------------------------------------------------------------------ |
| store_country | ?string | The user's store country, as an [ISO 3166-1 alpha-2](https://en.wikipedia.org/wiki/ISO_3166-1_alpha-2) country code |
| allowed_payment_source_types | array[integer] | The creatable [payment source types](#payment-source-type) |
| allowed_billing_address_countries | array[string] | The countries allowed for billing addresses, as [ISO 3166-1 alpha-2](https://en.wikipedia.org/wiki/ISO_3166-1_alpha-2) country codes |
Create Payment Source
Creates a payment source. Returns a [payment source](#payment-source-object) object on success. Fires a [User Payment Sources Update](/gateway/gateway-events#user-payment-sources-update) Gateway event.
###### Query String Params
| Field | Type | Description |
| --------- | ------ | ---------------------------------------------------------------------- |
| location? | string | The analytics location the request initiated from (max 100 characters) |
###### JSON Params
| Field | Type | Description |
| ---------------------- | -------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------- |
| token | string | The payment source token retrieved from the payment gateway |
| payment_gateway | integer | The [payment gateway](#payment-gateway) of the payment source |
| billing_address | [billing address](#billing-address-structure) object | The billing address of the payment source |
| billing_address_token? | string | The validation token obtained from the [Validate Billing Address](#validate-billing-address) endpoint |
| return_url? | string | The URL to return to after the payment source is created |
| bank? | string | The bank information for the payment source |
| default? | boolean | Whether the payment source is the default payment source (default false) |
| pix? | [PIX payment metadata](#pix-payment-metadata-structure) object | PIX payment metadata |
Modify Payment Source
Modifies a payment source. Returns an updated [payment source](#payment-source-object) object on success. Fires a [User Payment Sources Update](/gateway/gateway-events#user-payment-sources-update) Gateway event.
###### JSON Params
| Field | Type | Description |
| ---------------- | ---------------------------------------------------- | -------------------------------------------------------- |
| billing_address? | [billing address](#billing-address-structure) object | The billing address of the payment source |
| default? | boolean | Whether the payment source is the default payment source |
| expires_month? | integer | The month the credit card expires at |
| expires_year? | integer | The year the credit card expires at |
Delete Payment Source
Deletes a payment source. Returns a 204 empty response on success. Fires a [User Payment Sources Update](/gateway/gateway-events#user-payment-sources-update) Gateway event.
Validate Billing Address
Validates a billing address.
| Field | Type | Description |
| --------------- | ---------------------------------------------------- | ------------------------------- |
| billing_address | [billing address](#billing-address-structure) object | The billing address to validate |
###### Response Body
| Field | Type | Description |
| ----- | ------ | -------------------------------------- |
| token | string | The token of validated billing address |
Get Stripe Setup Intent Secret
Creates a Stripe SetupIntent and returns the client secret. See the [Stripe documentation](https://docs.stripe.com/api/setup_intents) for more information.
###### JSON Params
| Field | Type | Description |
| -------------------------------------- | -------------- | --------------------------------------------------------------------------------- |
| regional_payment_element_source_types? | array[integer] | [Payment source types](#payment-source-type) to use via Stripe's Payment Elements |
###### Response Body
| Field | Type | Description |
| ------------- | ------ | ------------------------------------ |
| client_secret | string | The client secret of the SetupIntent |
Create PayPal Billing Agreement Token
Creates a PayPal billing agreement and returns its token. See the [PayPal documentation](https://developer.paypal.com/docs/api/payments.billing-agreements/v1/#billing-agreements_create-agreement-token) for more information.
This token is used to redirect the user to PayPal to approve the billing agreement through a URL: `https://www.paypal.com/agreements/approve?nolegacy=1&ba_token={token}`
###### JSON Params
| Field | Type | Description |
| -------------- | ------ | --------------------------------------------------------------- |
| return_url ^1^ | string | The URL to redirect to after approval (max 2048 characters) |
| cancel_url ^1^ | string | The URL to redirect to after cancellation (max 2048 characters) |
^1^ These URLs are typically set to the [Create Billing Popup Bridge Redirect](#create-billing-popup-bridge-redirect) endpoint (with a `response_type` of `return` and `cancel`, respectively), which redirects the user back to the Discord client for handling.
###### Response Body
| Field | Type | Description |
| ----- | ------ | ----------------------------------------- |
| token | string | The token of the PayPal billing agreement |
List Available Adyen Payment Methods
Returns available payment methods for the [`ADYEN` payment gateway](#payment-gateway). This endpoint is a proxy for getting available payment methods for transactions using the Adyen API. See the [Adyen documentation](https://docs.adyen.com/api-explorer/Checkout/71/post/paymentMethods) for more information.
Create Billing Popup Bridge
Creates a billing popup bridge to handle third-party payment flows.
###### Response Body
| Field | Type | Description |
| ----- | ------ | ---------------------------------------- |
| state | string | A unique identifier for the request flow |
Create Billing Popup Bridge Redirect
Redirects the user back to the Discord client after completing a third-party payment flow. The client uses [Create Billing Popup Bridge Callback](#create-billing-popup-bridge-callback) to complete the flow.
Create Billing Popup Bridge Callback
Completes a third-party payment flow after being redirected back from the payment provider. Returns a 204 empty response on success. Fires a [Billing Popup Bridge Callback](/gateway/gateway-events#billing-popup-bridge-callback) Gateway event.
###### JSON Params
| Field | Type | Description |
| --------- | ------------------- | ------------------------------------------------ |
| state | string | The unique identifier for the request flow |
| path | string | The redirect API path |
| query? | map[string, string] | Redirect query parameters |
| insecure? | boolean | Whether the callback is insecure (default false) |
Get Localized Pricing Promo
Returns localized pricing promo information for the user based on their country.
###### Response Body
| Field | Type | Description |
| ----------------------- | --------------------------------------------------------------------- | --------------------------------------------------------------------------------------- |
| country_code | string | The [ISO 3166-1 alpha-2](https://en.wikipedia.org/wiki/ISO_3166-1_alpha-2) country code |
| localized_pricing_promo | ?[localized pricing promo](#localized-pricing-promo-structure) object | The localized pricing promo information |
###### Localized Pricing Promo Structure
| Field | Type | Description |
| -------------------- | ---------------------------------------------------- | --------------------------------------------------------------------------------------- |
| plan_id | snowflake | The ID of the discounted subscription plan |
| country_code | string | The [ISO 3166-1 alpha-2](https://en.wikipedia.org/wiki/ISO_3166-1_alpha-2) country code |
| payment_source_types | array[integer] | The allowed [payment source types](#payment-source-type) for the promotion |
| price | [localized price](#localized-price-structure) object | The promotional price information |
###### Localized Price Structure
| Field | Type | Description |
| -------- | ------- | -------------------------------------------------------------------------------- |
| currency | string | The lower-cased [ISO 4217](https://en.wikipedia.org/wiki/ISO_4217) currency code |
| amount | integer | The price amount in the smallest currency unit |
Get User Offer
Returns the current trial and discount offers for the user, if any.
###### JSON Params
| Field | Type | Description |
| ---------------- | --------- | -------------------------------------------------------------- |
| payment_gateway? | integer | The [payment gateway](#payment-gateway) to retrieve offers for |
| offer_id? | snowflake | The specific discount ID to fetch the offer of |
###### Response Body
| Field | Type | Description |
| ------------------- | ---------------------------------------------------------- | ------------------------------------ |
| user_trial_offer | ?[user trial offer](#user-trial-offer-object) object | The user's trial offer |
| user_discount_offer | ?[user discount offer](#user-discount-offer-object) object | The user's discount offer |
| user_discount | ?[user discount offer](#user-discount-offer-object) object | The currently applied discount offer |
Acknowledge User Offer
Acknowledges that the user has seen a trial or discount offer.
###### JSON Params
| Field | Type | Description |
| ----------------------- | --------- | ------------------------------------------- |
| user_trial_offer_id? | snowflake | The ID of the trial offer to acknowledge |
| user_discount_offer_id? | snowflake | The ID of the discount offer to acknowledge |
###### Response Body
| Field | Type | Description |
| -------------------- | ---------------------------------------------------------- | --------------------------------------- |
| user_trial_offer | ?[user trial offer](#user-trial-offer-object) object | The acknowledged trial offer |
| user_discount_offer? | ?[user discount offer](#user-discount-offer-object) object | The acknowledged discount offer |
| user_discount? | ?[user discount offer](#user-discount-offer-object) object | The acknowledged applied discount offer |
Create Churn User Offer
Creates a discount offer as a retention attempt for a user in a non-renewing state, if allowed.
###### Response Body
| Field | Type | Description |
| ----- | --------------------------------------------------------- | -------------------------- |
| offer | [user discount offer](#user-discount-offer-object) object | The created discount offer |
Get Churn User Offer
Returns the current retention discount offer for a user in a non-renewing state, if any.
###### Response Body
| Field | Type | Description |
| ----- | --------------------------------------------------------- | ------------------------------------ |
| offer | [user discount offer](#user-discount-offer-object) object | The current retention discount offer |
Get User Trial Offer
Returns a [user trial offer](#user-trial-offer-object) object for the user, if any.
This endpoint is deprecated. It is replaced by [Get User Offer](#get-user-offer).
Acknowledge User Trial Offer
Acknowledges that the user has seen a trial offer. Returns the acknowledged [user trial offer](#user-trial-offer-object) object on success.
This endpoint is deprecated. It is replaced by [Acknowledge User Offer](#acknowledge-user-offer).
Redeem User Offer
Redeems a discount offer for the user. Returns a list of applied [user discount offer](#user-discount-offer-object) objects on success.
###### JSON Params
| Field | Type | Description |
| ---------------------- | --------- | -------------------------------------- |
| user_discount_offer_id | snowflake | The ID of the discount offer to redeem |
Get Checkout Recovery
Returns whether the client should prompt the user to continue their premium purchase.
###### Response Body
| Field | Type | Description |
| ------------ | ------- | --------------------------------------------------------------- |
| is_eligible? | boolean | Whether the client should prompt the user for checkout recovery |
List Premium User Affinities
Returns a list of up to 3 partial [user](/resources/user#partial-user-structure) objects representing friends with a premium subscription, used to entice the user to subscribe.
List Eligible Application Subscription Guilds
Returns a list of guild IDs eligible for an application guild subscription.
###### Query String Params
| Field | Type | Description |
| -------------- | --------- | ------------------------------------------------------- |
| application_id | snowflake | The ID of the application the subscription belongs to |
| sku_id? | snowflake | The ID of the application subscription SKU to check for |
---
# Lobbies
Link: https://docs.discord.food/resources/lobby
Lobbies are groups of users that can communicate with each other via text and voice. Users can be in multiple lobbies at once. A lobby can also have metadata (an arbitrary JSON blob) associated with the lobby and each user.
Lobbies have a text chat channel that all members can use to communicate. Messages are sent to all members of the lobby.
Lobbies support also voice calls. Although a lobby is allowed to have 1,000 members, you should not start voice calls in lobbies that large (around 25 is a good number).
### Lobby Object
A game lobby within Discord.
###### Lobby Structure
| Field | Type | Description |
| --------------- | --------------------------------------------------- | -------------------------------------------------------------------------- |
| id | snowflake | The ID of the lobby |
| application_id | snowflake | The ID of the application that created the lobby |
| metadata | ?map[string, string] | The metadata of the lobby (max 25 keys, 1024 characters per key and value) |
| members | array[[lobby member](#lobby-member-object) object] | The members of the lobby (max 1000) |
| flags | integer | The [lobby flags](#lobby-flags) |
| linked_channel? | [channel](/resources/channel#channel-object) object | The guild channel linked to the lobby |
###### Lobby Flags
| Value | Name | Description |
| -------- | --------------------------------- | --------------------------------------------------------------------------- |
| 1 \<\< 0 | REQUIRE_APPLICATION_AUTHORIZATION | Users must authorize the application to send messages in the linked channel |
###### Example Lobby Object
```json
{
"id": "1350184413060661332",
"application_id": "891436243903728565",
"metadata": {
"topic": "balls"
},
"members": [
{
"id": "852892297661906993",
"metadata": null,
"flags": 1
}
]
}
```
### Lobby Member Object
Represents a member of a lobby.
###### Lobby Member Structure
| Field | Type | Description |
| ------------- | -------------------- | --------------------------------------------------------------------------------- |
| id ^1^ | snowflake | The ID of the user |
| metadata? | ?map[string, string] | The metadata of the lobby member (max 25 keys, 1024 characters per key and value) |
| flags? | integer | The [lobby member's flags](#lobby-member-flags) |
| connected ^2^ | boolean | Whether the member is connected to a call in lobby |
^1^ Not included when returned [over the Gateway](/gateway/gateway-events#lobbies).
^2^ Only included in lobby objects returned [over the Gateway](/gateway/gateway-events#lobbies).
###### Lobby Member Flags
| Value | Name | Description |
| -------- | -------------- | ------------------------------------------------- |
| 1 \<\< 0 | CAN_LINK_LOBBY | Lobby member can link a text channel to the lobby |
## Endpoints
Create Lobby
Creates a new lobby. Returns a [lobby](#lobby-object) object on success. Fires a [Lobby Create](/gateway/gateway-events#lobby-create) Gateway event.
Clients will not be able to join or leave a lobby created using this API.
This endpoint is not usable by user accounts.
###### JSON Params
| Field | Type | Description |
| --------------------- | ---------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------- |
| metadata? | ?map[string, string] | The metadata of the lobby (max 25 keys, 1024 characters per key and value) |
| members? | array[partial [lobby member](#lobby-member-object) object] | The members of the lobby (max 25) |
| idle_timeout_seconds? | integer | How long to wait (in seconds) before shutting down a lobby after it becomes idle (min 5, max 604800, default 300) |
| flags? | integer | The [lobby flags](#lobby-flags) |
Join or Create Lobby
Joins an existing lobby or creates a new lobby. Returns a [lobby](#lobby-object) object on success. May fire a [Lobby Create](/gateway/gateway-events#lobby-create) or [Lobby Member Add](/gateway/gateway-events#lobby-member-add) Gateway event.
This endpoint is not usable by user accounts.
###### JSON Params
| Field | Type | Description |
| --------------------- | -------------------- | ----------------------------------------------------------------------------------------------------------------- |
| secret ^1^ | string | The lobby secret (max 250 characters) |
| lobby_metadata? | ?map[string, string] | The metadata of the lobby (max 25 keys, 1024 characters per key and value) |
| member_metadata? | ?map[string, string] | The metadata of the lobby member (max 25 keys, 1024 characters per key and value) |
| idle_timeout_seconds? | integer | How long to wait (in seconds) before shutting down a lobby after it becomes idle (min 5, max 604800, default 300) |
| flags? | integer | The [lobby flags](#lobby-flags) |
^1^ Secret values expire after 30 days. After this time period, the lobby will still exist, but new users won't be able to join.
Get Lobby
Returns a [lobby](#lobby-object) object for the given lobby ID. User must be a member of the lobby.
This endpoint is not usable by user accounts.
Modify Lobby
Modifies a lobby's settings. Application must be the creator of the lobby. Returns the updated [lobby](#lobby-object) object on success. Fires a [Lobby Update](/gateway/gateway-events#lobby-update) Gateway event.
This endpoint is not usable by user accounts.
###### JSON Params
| Field | Type | Description |
| --------------------- | -------------------------------------------------- | ---------------------------------------------------------------------------------------------------- |
| metadata? | ?map[string, string] | The metadata of the lobby (max 25 keys, 1024 characters per key and value) |
| members? | array[[lobby member](#lobby-member-object) object] | The members of the lobby (max 25) |
| idle_timeout_seconds? | integer | How long to wait (in seconds) before shutting down a lobby after it becomes idle (min 5, max 604800) |
| flags? | integer | The [lobby flags](#lobby-flags) |
Delete Lobby
Deletes a lobby. Application must be the creator of the lobby. Returns a 204 empty response on success. Fires a [Lobby Delete](/gateway/gateway-events#lobby-delete) Gateway event.
This endpoint is not usable by user accounts.
Add Lobby Member
Adds a member to the lobby. Returns the [lobby member](#lobby-member-object) object. Fires a [Lobby Member Add](/gateway/gateway-events#lobby-member-add) or [Lobby Member Update](/gateway/gateway-events#lobby-member-update) Gateway event.
This endpoint is not usable by user accounts.
All parameters to this endpoint are optional and nullable. Omitting or setting a `null` value will set it to default. If the user is already a member of the lobby, this will update the member and fire a [Lobby Member Update](/gateway/gateway-events#lobby-member-update) Gateway event instead.
###### JSON Params
| Field | Type | Description |
| --------- | -------------------- | --------------------------------------------------------------------------------- |
| metadata? | ?map[string, string] | The metadata of the lobby member (max 25 keys, 1024 characters per key and value) |
| flags? | integer | The [lobby member's flags](#lobby-member-flags) |
Remove Lobby Member
Removes a member from the lobby. Returns a 204 empty response on success. Fires a [Lobby Member Remove](/gateway/gateway-events#lobby-member-remove) Gateway event.
This endpoint is not usable by user accounts.
Leave Lobby
Removes the current user from the lobby. Returns a 204 empty response on success. Fires a [Lobby Delete](/gateway/gateway-events#lobby-delete) and [Lobby Member Remove](/gateway/gateway-events#lobby-member-remove) Gateway event.
This endpoint is only usable with an OAuth2 access token with the `lobbies.write` scope.
Bulk Update Lobby Members
Modifies multiple members in a lobby in a single request. Accepts a list of 1 to 25 [update lobby member](#update-lobby-member-structure) objects. Returns a list of [lobby member](#lobby-member-object) objects on success. May fire multiple [Lobby Member Add](/gateway/gateway-events#lobby-member-add), and/or [Lobby Member Remove](/gateway/gateway-events#lobby-member-remove) Gateway events.
This endpoint is not usable by user accounts.
All fields in lobby member objects passed to this endpoint are optional and nullable. Omitting or setting a `null` value will set it to default (except for `remove_member`).
If the user is already a member of the lobby, this will update the member and fire a [Lobby Member Update](/gateway/gateway-events#lobby-member-update) Gateway event instead.
###### Update Lobby Member Structure
| Field | Type | Description |
| -------------- | -------------------- | --------------------------------------------------------------------------------- |
| id | snowflake | The ID of the lobby member |
| metadata? | ?map[string, string] | The metadata of the lobby member (max 25 keys, 1024 characters per key and value) |
| flags? | integer | The [lobby member's flags](#lobby-member-flags) |
| remove_member? | boolean | Whether to remove the member from the lobby |
Create Lobby Invite for Current User
Creates an invite for the channel linked to the lobby that can only be accepted by the current user. Fires an [Invite Create](/gateway/gateway-events#invite-create) Gateway event.
This endpoint is only usable with an OAuth2 access token with the `lobbies.write` scope.
###### Response Body
| Field | Type | Description |
| ----- | ------ | ---------------------- |
| code | string | The code of the invite |
Create Lobby Invite
Creates an invite for the channel linked to the lobby that can only be accepted by the specified user. Fires an [Invite Create](/gateway/gateway-events#invite-create) Gateway event.
This endpoint is only usable with an OAuth2 access token with the `lobbies.write` scope.
###### Response Body
| Field | Type | Description |
| ----- | ------ | ---------------------- |
| code | string | The code of the invite |
Modify Lobby Linked Channel
Links or unlinks a channel to the lobby. Returns a [lobby](#lobby-object) object on success. Fires a [Lobby Update](/gateway/gateway-events#lobby-update) and [Channel Update](/gateway/gateway-events#channel-update) Gateway event.
The application must be the creator of the lobby or the member must have the [`CAN_LINK_LOBBY` flag](#lobby-member-flags). Requires the `MANAGE_CHANNELS` permission in the target channel.
This endpoint is only usable with an OAuth2 access token with the `lobbies.write` scope.
###### JSON Params
| Field | Type | Description |
| ----------- | ---------- | ------------------------------------------ |
| channel_id? | ?snowflake | The ID of the channel to link to the lobby |
List Lobby Messages
Returns a list of partial [message](/resources/message#message-object) objects in the lobby in reverse chronological order.
This endpoint is only usable with an OAuth2 access token with the `lobbies.write` scope.
###### Query String Params
| Field | Type | Description |
| ------ | ------- | ---------------------------------------------------- |
| limit? | integer | Max number of messages to return (1-200, default 50) |
Create Lobby Message
Posts a message to a lobby. Returns a partial [message](/resources/message#message-object) object on success. Fires a [Lobby Message Create](/gateway/gateway-events#lobby-message-create) and [Message Create](/gateway/gateway-events#message-create) Gateway event.
Functionally identical to the [Create Message](/resources/message#create-message) endpoint, but is used for lobbies in an OAuth2 context and has some additional parameters. Check there for more information.
This endpoint is only usable with an OAuth2 access token with the `lobbies.write` scope.
###### Extra JSON Params
| Field | Type | Description |
| --------- | ------ | -------------------------------------------------------------------------------- |
| metadata? | object | Custom metadata for the message (max 25 keys, 1024 characters per key and value) |
Update Lobby Message Moderation Metadata
Updates a lobby message's moderation metadata. Accepts a moderation metadata mapping, up to 5 keys, max 2000 characters per value. Returns a 204 empty response. Fires a [Lobby Message Update](/gateway/gateway-events#lobby-message-update) or [Message Update](/gateway/gateway-events#message-update) Gateway event.
This endpoint is not usable by user accounts.
---
# Premium Referrals
Link: https://docs.discord.food/resources/premium-referral
Premium referrals, or Nitro trials, allow Nitro subscribers to share up to three 2-week Nitro subscriptions with friends who haven't had an active Nitro subscription in the past 12 months.
### Premium Referral Object
###### Premium Referral Structure
| Field | Type | Description |
| ------------------ | ------------------------------------------------------------------------------ | ------------------------------------------------------------- |
| id | snowflake | The ID of the referral |
| user_id | snowflake | The user who the referral was sent to |
| trial_id | snowflake | The ID of the subscription trial associated with the referral |
| subscription_trial | [subscription trial](/resources/subscription#subscription-trial-object) object | The subscription trial associated with the referral |
| expires_at | ISO8601 timestamp | When the referral link expires |
| referrer_id | snowflake | The ID of the user who created the referral |
| referrer | partial [user](/resources/user#user-object) object | The user who created the referral |
| redeemed_at? | ISO8601 timestamp | When the referral was redeemed |
###### Example Premium Referral
```json
{
"id": "1107800271637200936",
"user_id": "563434444321587202",
"trial_id": "1073698058383917056",
"subscription_trial": {
"id": "1073698058383917056",
"interval": 3,
"interval_count": 14,
"sku_id": "521847234246082599"
},
"expires_at": "2023-05-17T22:42:46.690847+00:00",
"referrer_id": "1044657759066525777",
"referer": {
"id": "1044657759066525777",
"username": "hackermon",
"global_name": "daniel",
"avatar": null,
"avatar_decoration_data": null,
"discriminator": "0",
"public_flags": 16384,
"primary_guild": null
},
"redeemed_at": "2023-05-16T18:22:21.777456+00:00"
}
```
### Premium Referral Eligibility Object
###### Premium Referral Eligibility Structure
| Field | Type | Description |
| -------------------------- | ----------------------- | ------------------------------------------------------------------------------------ |
| referrals_remaining | integer | The amount of referrals remaining |
| sent_user_ids | array[snowflake] | The IDs of users that have been referred |
| refresh_at | ?ISO8601 timestamp | When the referral count will refresh |
| has_eligible_friends | boolean | Whether the user has friends that are eligible for a referral |
| recipient_status | map[snowflake, integer] | The [redemption status](#premium-referral-recipient-status) of each referred user ID |
| is_eligible_for_incentive | boolean | Whether the user is eligible for a personal discount upon referral redemption |
| is_qualified_for_incentive | boolean | Whether the user will receive an incentivized discount on their next Nitro purchase |
| referral_incentive_status | integer | The [incentive status](#premium-referral-incentive-status) of the user |
###### Premium Referral Recipient Status
| Value | Name | Description |
| ----- | -------- | -------------------------------------------- |
| 1 | REDEEMED | The recipient has redeemed the referral |
| 2 | PENDING | The recipient has yet to redeem the referral |
###### Premium Referral Incentive Status
| Value | Name | Description |
| ----- | ------------ | --------------------------------------------------------------------------- |
| 0 | NOT_ELIGIBLE | The user is not eligible for an incentive |
| 1 | ELIGIBLE | The user is eligible for an incentive |
| 2 | QUALIFIED | The user will receive an incentivized discount on their next Nitro purchase |
| 3 | COOLDOWN | The user is on cooldown and cannot receive an incentive |
| 4 | UNAPPLIED | The user has not applied their incentive yet |
###### Example Premium Referral Eligibility
```json
{
"referrals_remaining": 0,
"sent_user_ids": ["159985870458322944", "563434444321587202", "296776625432035328"],
"refresh_at": null,
"has_eligible_friends": true,
"recipient_status": {
"159985870458322944": 2,
"563434444321587202": 2,
"296776625432035328": 2
},
"is_eligible_for_incentive": false,
"is_qualified_for_incentive": false,
"referral_incentive_status": 0
}
```
## Endpoints
Get Premium Referral
Returns a [premium referral](#premium-referral-object) object for the given referral ID.
Only the referrer and referred user can retrieve a premium referral.
Get Premium Referral Eligibility
Returns a [premium referral eligibility](#premium-referral-eligibility-object) object for the user.
Only users with an applicable premium (Nitro) plan can create referrals.
Get Premium Referral Incentive Eligibility
Returns a subset of the [premium referral eligibility](#premium-referral-eligibility-object) object for the user with their eligibility for a personal discount upon referral redemption.
###### Response Body
| Field | Type | Description |
| ------------------------- | ------- | ----------------------------------------------------------------------------- |
| is_eligible_for_incentive | boolean | Whether the user is eligible for a personal discount upon referral redemption |
List Premium Referral Eligible Users
Returns an object containing a list of users who are eligible to receive a referral from the user.
###### JSON Params
| Field | Type | Description |
| ------------- | ------- | ------------------------------------------------------ |
| index | integer | The current search index (0-1000) |
| limit? | integer | Max number of users to return (max 50, default 30) |
| search_query? | string | Query to match usernames against (max 1024 characters) |
###### Response Body
| Field | Type | Description |
| ----------- | --------------------------------------------------------- | ------------------------------- |
| users | array[partial [user](/resources/user#user-object) object] | The eligible users |
| next_index? | integer | The next index to paginate from |
Create Premium Referral
Creates a new premium referral. Returns a [premium referral](#premium-referral-object) object. Fires a [Message Create](/gateway/gateway-events#message-create) Gateway event. The referral is sent to the user specified. Referrals expire after 48 hours.
Only users with an applicable premium (Nitro) plan can create referrals.
---
# Auto Moderation
Link: https://docs.discord.food/resources/auto-moderation
Auto Moderation, or AutoMod, is a feature which allows each [guild](/resources/guild) to set up rules that trigger based on some criteria. For example, a rule can trigger whenever a message contains a specific keyword.
Rules can be configured to automatically execute actions whenever they trigger. For example, if a user tries to send a message which contains a certain keyword, a rule can trigger and block the message before it is sent.
Users are required to have the `MANAGE_GUILD` permission to access all AutoMod resources.
Some [action types](#automod-action-type) and [alert action types](#automod-alert-action-type) require additional permissions (i.e. the `TIMEOUT_USER` [action type](#automod-action-type) requires an additional `MODERATE_MEMBERS` permission and the `DELETE_USER_MESSAGE` [alert action type](#automod-alert-action-type) requires an additional `MANAGE_MESSAGES` permission).
### AutoMod System Messages
AutoMod system messages are sent as standard [messages](/resources/message#message-object) in the guild with the `AUTO_MODERATION_ACTION` [message type](/resources/message#message-type).
If no user is associated with the system message, the author is the AutoMod system account (`1008776202191634432`).
These messages have a special [embed](/resources/message#embed-object) structure which contains information about the action that was taken.
The custom embed fields below are collapsed as a list of key-value pairs into the `fields` array on the [embed object](/resources/message#embed-object).
As [embed field values](/resources/message#embed-field-structure) are strings, all below fields are serialized as strings, even if the type is specified as otherwise.
#### AutoMod Alert
Sent when a [`SEND_ALERT_MESSAGE` action type](#automod-action-type) is triggered.
The author of the message is the user which generated the content that triggered the rule.
The [embed description](/resources/message#embed-object) contains the user message content that triggered the rule, if applicable.
###### AutoMod Alert Embed Structure
| Field | Type | Description |
| ----------------------------- | ---------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------- |
| rule_name | string | The name of the [automod rule](#automod-rule-object) that was triggered |
| decision_id | string | The ID of the decision that was executed |
| decision_reason? | string | The reason for the decision that was executed |
| decision_outcome | string | The [outcome of the decision](#automod-decision-outcome) that triggered the rule |
| channel_id? | snowflake | The ID of the channel in which the user content was posted |
| flagged_message_id? | snowflake | The ID of the message that triggered the rule |
| keyword | string | The word or phrase configured that triggered the rule |
| keyword_matched_content | string | The substring in content that triggered the rule |
| block_profile_update_type? | string | The [type of profile update](#automod-profile-update-type) that was blocked |
| quarantine_user? | string | The [reason for quarantining the user](#automod-quarantine-user-reason) |
| quarantine_user_action? | string | The [action taken on the quarantined user](#automod-quarantine-user-action) |
| quarantine_event? | string | The [user action](#automod-quarantine-event-type) that triggered the rule |
| voice_channel_status_outcome? | string | The [outcome of the voice channel status update](#automod-decision-outcome) that triggered the rule |
| application_name? | string | The name of the user application that triggered the rule |
| interaction_user_id? | snowflake | The ID of the user that triggered the rule, if the author is a user application |
| interaction_callback_type? | string | The [type of interaction callback](#automod-interaction-callback-type) that triggered the rule |
| timeout_duration? | integer | Duration (in seconds) after which the timeout expires |
| alert_actions_execution? | [alert actions execution](#automod-alert-actions-execution-structure) object | The actions that were executed on the AutoMod alert |
###### AutoMod Decision Outcome
| Value | Description |
| ------- | --------------------------------- |
| flagged | The action was flagged by AutoMod |
| blocked | The action was blocked by AutoMod |
###### AutoMod Profile Update Type
| Value | Description |
| --------------- | ----------------------------------------------- |
| nickname_update | When a user updates their nickname in the guild |
| nickname_reset | When a user resets their nickname in the guild |
###### AutoMod Quarantine User Reason
| Value | Description |
| ------------ | -------------------------------------------- |
| username | The user's username triggered the rule |
| display_name | The user's display name triggered the rule |
| ~~bio~~ | ~~The user's bio triggered the rule~~ |
| nickname | The user's guild nickname triggered the rule |
| clan_tag | The user's guild tag triggered the rule |
###### AutoMod Quarantine User Action
| Value | Description |
| -------------------- | --------------------------------------------------------------------------------------------------------------------------------- |
| block_guest_join | The guest was prevented from joining the guild |
| block_profile_update | The user was prevented from updating their profile in the guild |
| quarantine_user | The user was quarantined; quarantined users, similar to timed out users, are prevented from interacting with the guild in any way |
###### AutoMod Quarantine Event Type
| Value | Description |
| --------------- | ---------------------------------------- |
| guild_join | When a user joins the guild |
| message_send | When a user sends a message in the guild |
| username_update | When a user updates their username |
| clan_tag_update | When a user updates their guild tag |
###### AutoMod Interaction Callback Type
| Value | Description |
| ----- | ----------------------------------------------- |
| modal | A modal interaction callback triggered the rule |
###### AutoMod Alert Actions Execution Structure
| Field | Type | Description |
| ------- | ------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------- |
| v | integer | The alert actions execution protocol version (currently 0) |
| actions | map[string, [alert action](#automod-alert-action-structure) object] | The actions that were executed on the AutoMod alert, keyed by [action type](#automod-alert-action-type) |
###### AutoMod Alert Action Type
| Value | Name | Description |
| ----- | ------------------- | ------------------------------------------------- |
| 1 | SET_COMPLETED | Marks the alert as completed |
| 2 | UNSET_COMPLETED | Marks the alert as not completed |
| 3 | DELETE_USER_MESSAGE | Deletes the user message that triggered the alert |
| 4 | SUBMIT_FEEDBACK | Reports an issue with the alert to Discord |
###### AutoMod Alert Action Structure
| Field | Type | Description |
| ----- | ----------------- | ------------------------------------------- |
| actor | snowflake | The ID of the user that executed the action |
| ts | ISO8601 timestamp | When the action was executed |
###### Example AutoMod Alert Embed
```json
{
"type": "auto_moderation_message",
"description": "can i say alien 🥺",
"fields": [
{
"name": "rule_name",
"value": "No aliens",
"inline": false
},
{
"name": "channel_id",
"value": "1121695809839308901",
"inline": false
},
{
"name": "decision_id",
"value": "22a2df4cf7904b81a17faa3e3930af7d",
"inline": false
},
{
"name": "keyword",
"value": "alien",
"inline": false
},
{
"name": "keyword_matched_content",
"value": "alien",
"inline": false
},
{
"name": "flagged_message_id",
"value": "1200705269110411274",
"inline": false
},
{
"name": "timeout_duration",
"value": "600",
"inline": false
},
{
"name": "decision_outcome",
"value": "blocked",
"inline": false
},
{
"name": "alert_actions_execution",
"value": "{\"v\": 0, \"actions\": {\"3\": {\"actor\": \"852892297661906993\", \"ts\": \"2024-01-27T07:34:12.145393+00:00\"}, \"1\": {\"actor\": \"852892297661906993\", \"ts\": \"2024-01-27T07:38:29.292345+00:00\"}}}",
"inline": false
}
]
}
```
#### AutoMod Incident Notification
Sent when a guild incident activity alert is triggered.
###### AutoMod Incident Notification Embed Structure
| Field | Type | Description |
| ---------------------------------- | ----------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------- |
| notification_type? | string | The [type of notification](#automod-incident-notification-type) that was triggered (default `raid`) |
| decision_id? | string | The ID of the decision that was executed |
| action_by_user_id? | snowflake | The ID of the user that executed the action (only applicable to `activity_alerts_enabled` [notification types](#automod-incident-notification-type)) |
| raid_type? | string | The [type of raid](#automod-raid-type) that was detected |
| raid_datetime? | ISO8601 timestamp | When the raid was detected |
| join_attempts? | integer | The approximate number of join attempts as part of the raid |
| dms_sent? | integer | The approximate number of sent DMs as part of the raid |
| suspicious_mention_activity_until? | ISO8601 timestamp | When the mention activity restrictions will end (only applicable to `mention_raid` [notification types](#automod-incident-notification-type)) |
| resolved_reason? | string | The [reason for resolving the notification](#automod-raid-resolution-reason) |
###### AutoMod Incident Notification Type
| Value | Description |
| ----------------------- | --------------------------------------------- |
| activity_alerts_enabled | Activity alerts were enabled in the guild |
| raid | A raid was detected |
| mention_raid | A mention raid was detected |
| interaction_blocked | An anonymous interaction response was blocked |
###### AutoMod Raid Type
| Value | Description |
| ------------ | --------------------------- |
| JOIN_RAID | A join raid was detected |
| MENTION_RAID | A mention raid was detected |
###### AutoMod Raid Resolution Reason
| Value | Description |
| ------------------- | ----------------------------------------------------------------------------- |
| LEGITIMATE_ACTIVITY | The increased activity was expected |
| LEGITIMATE_ACCOUNTS | The increased activity was caused by legitimate accounts |
| LEGITIMATE_DMS | The increased activity was caused by legitimate DMs |
| DM_SPAM | The increased activity was caused by DM spam and the spammers were removed |
| JOIN_RAID | The increased activity was caused by a join raid and the raiders were removed |
| OTHER | The increased activity was caused by another reason |
###### Example AutoMod Incident Notification Embed
```json
{
"type": "auto_moderation_notification",
"fields": [
{
"name": "notification_type",
"value": "raid",
"inline": false
},
{
"name": "raid_datetime",
"value": "2023-08-15 22:25:33.184657+00:00",
"inline": false
},
{
"name": "raid_type",
"value": "JOIN_RAID",
"inline": false
},
{
"name": "join_attempts",
"value": "25",
"inline": false
},
{
"name": "dms_sent",
"value": "0",
"inline": false
},
{
"name": "resolved_reason",
"value": "LEGITIMATE_ACTIVITY",
"inline": false
}
]
}
```
### AutoMod Rule Object
###### AutoMod Rule Structure
| Field | Type | Description |
| ---------------- | ---------------------------------------------------- | ------------------------------------------------------------------- |
| id | snowflake | The ID of the rule |
| guild_id | snowflake | The ID of the guild which this rule belongs to |
| name | string | The name of the rule |
| creator_id | snowflake | The ID of the user that created the rule |
| event_type | integer | The [type of event](#automod-event-type) that triggers the rule |
| trigger_type | integer | The [type of trigger](#automod-trigger-type) that invokes the rule |
| trigger_metadata | [trigger metadata](#automod-trigger-metadata) object | Metadata used to determine whether the rule should be triggered |
| actions | array[[action](#automod-action-object) object] | The actions that will execute when the rule is triggered |
| enabled | boolean | Whether the rule is enabled |
| exempt_roles | array[snowflake] | The IDs of the roles that won't be affected by the rule (max 20) |
| exempt_channels | array[snowflake] | The IDs of the channels that won't be affected by the rule (max 50) |
###### Example AutoMod Rule
```json
{
"id": "969707018069872670",
"guild_id": "613425648685547541",
"name": "Keyword Filter 1",
"creator_id": "423457898095789043",
"trigger_type": 1,
"event_type": 1,
"actions": [
{
"type": 1,
"metadata": { "custom_message": "Please keep financial discussions limited to the #finance channel" }
},
{
"type": 2,
"metadata": { "channel_id": "123456789123456789" }
},
{
"type": 3,
"metadata": { "duration_seconds": 60 }
}
],
"trigger_metadata": {
"keyword_filter": ["cat*", "*dog", "*ana*", "i like c++"],
"regex_patterns": ["(b|c)at", "^(?:[0-9]{1,3}\\.){3}[0-9]{1,3}$"]
},
"enabled": true,
"exempt_roles": ["323456789123456789", "423456789123456789"],
"exempt_channels": ["523456789123456789"]
}
```
###### AutoMod Trigger Type
Characterizes the type of content which can trigger the rule.
| Value | Name | Description |
| ----- | ---------------- | --------------------------------------------------------------------------------- |
| 1 | KEYWORD | When message content contains words from a user defined list of keywords (max 6) |
| ~~2~~ | ~~HARMFUL_LINK~~ | ~~When message content contains any harmful links (max 1)~~ |
| 3 | SPAM | When message content represents generic spam (max 1) |
| 4 | KEYWORD_PRESET | When message content contains words from internal predefined wordsets (max 1) |
| 5 | MENTION_SPAM | When message content contains more unique mentions than allowed (max 1) |
| 6 | USER_PROFILE | When a user's profile contains words from a user defined list of keywords (max 1) |
| 7 | GUILD_POLICY | When a user violates the guild rules (max 1) |
###### AutoMod Trigger Metadata
Additional data used to determine whether a rule should be triggered. Different fields are relevant based on the [trigger type](#automod-trigger-type).
| Field | Type | Description | Trigger Type |
| ------------------------------- | -------------- | -------------------------------------------------------------------------------------------------------- | ------------------------------------------- |
| keyword_filter ^1^ | array[string] | Substrings which will be searched for in content (1-60 characters, max 1000) | `KEYWORD`, `USER_PROFILE` |
| regex_patterns ^2^ | array[string] | Regular expression patterns which will be matched against content (1-260 characters, max 10) | `KEYWORD`, `USER_PROFILE` |
| presets | array[integer] | The [internally predefined wordsets](#automod-keyword-preset-type) which will be searched for in content | `KEYWORD_PRESET` |
| allow_list ^3^ | array[string] | Substrings which should not trigger the rule (1-60 characters, max 100 or 1000 respectively) | `KEYWORD`, `KEYWORD_PRESET`, `USER_PROFILE` |
| mention_total_limit | integer | Number of unique role and user mentions allowed per message (max 50) | `MENTION_SPAM` |
| mention_raid_protection_enabled | boolean | Whether to automatically detect mention raids | `MENTION_SPAM` |
^1^ A keyword can be a phrase which contains multiple words. [Wildcard symbols](#automod-keyword-matching-strategies) can be used to customize how each keyword will be matched. Each keyword must be 60 characters or less.
^2^ Only Rust flavored regex is currently supported, which can be tested in online editors such as [Rustexp](https://rustexp.lpil.uk/). Each regex pattern must be 260 characters or less.
^3^ Each `allow_list` keyword can be a phrase which contains multiple words. [Wildcard symbols](#automod-keyword-matching-strategies) can be used to customize how each keyword will be matched. Rules with `KEYWORD` [trigger types](#automod-trigger-type) accept a maximum of 100 keywords. Rules with `KEYWORD_PRESET` [trigger types](#automod-trigger-type) accept a maximum of 1000 keywords.
###### AutoMod Keyword Preset Type
| Value | Name | Description |
| ----- | -------------- | ------------------------------------------------------------ |
| 1 | PROFANITY | Words that may be considered forms of swearing or cursing |
| 2 | SEXUAL_CONTENT | Words that refer to sexually explicit behavior or activity |
| 3 | SLURS | Personal insults or words that may be considered hate speech |
###### AutoMod Event Type
Indicates in what event context a rule should be checked.
| Value | Name | Description | Trigger Type |
| ----- | ------------------ | --------------------------------------------------- | ------------------------------------------------------------------- |
| 1 | MESSAGE_SEND | When a member sends or edits a message in the guild | `KEYWORD`, `SPAM`, `KEYWORD_PRESET`, `MENTION_SPAM`, `GUILD_POLICY` |
| 2 | GUILD_MEMBER_EVENT | When a member joins or updates their profile | `USER_PROFILE` |
###### AutoMod Keyword Matching Strategies
Use the wildcard symbol (`*`) at the beginning or end of a keyword to define how it should be matched. All keywords are case insensitive.
**Prefix** - Word must start with the keyword
| Keyword | Matches |
| --------- | ------------------------------------- |
| cat\* | **cat**ch, **Cat**apult, **CAt**tLE |
| tra\* | **tra**in, **tra**de, **TRA**ditional |
| the mat\* | **the mat**rix |
**Suffix** - Word must end with the keyword
| Keyword | Matches |
| --------- | ----------------------------------- |
| \*cat | wild**cat**, copy**Cat** |
| \*tra | ex**tra**, ul**tra**, orches**TRA** |
| \*the mat | brea**the mat** |
**Anywhere** - Keyword can appear anywhere in the content
| Keyword | Matches |
| ----------- | --------------------------- |
| \*cat\* | lo**cat**ion, edu**Cat**ion |
| \*tra\* | abs**tra**cted, ou**tra**ge |
| \*the mat\* | brea**the mat**ter |
**Whole Word** - Keyword is a full word or phrase and must be surrounded by whitespace
| Keyword | Matches |
| ------- | ----------- |
| cat | **cat** |
| train | **train** |
| the mat | **the mat** |
### AutoMod Action Object
An action which will execute whenever a rule is triggered.
###### AutoMod Action Structure
| Field | Type | Description |
| ------------- | -------------------------------------------------- | ------------------------------------------------------------------------- |
| type | integer | The [type of action](#automod-action-type) |
| metadata? ^1^ | [action metadata](#automod-action-metadata) object | Additional metadata needed during execution for this specific action type |
^1^ See the "Action Type" column in [action metadata](#automod-action-metadata) to understand which `type` values require `metadata` to be set.
###### AutoMod Action Type
| Value | Name | Description |
| ----- | ---------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| 1 | BLOCK_MESSAGE | Block a member's message and prevent it from being posted; a custom explanation can be specified and shown to members whenever their message is blocked |
| 2 | SEND_ALERT_MESSAGE ^1^ | Log user content to a specified channel |
| 3 | TIMEOUT_USER ^2^ | Timeout user for a specified duration |
| 4 | QUARANTINE_USER ^3^ | Block guild join, profile update, or quarantine user indefinitely; quarantined users, similar to timed out users, are prevented from interacting with the guild in any way |
^1^ Only a `SEND_ALERT_MESSAGE` action can be set up for `GUILD_POLICY` [trigger types](#automod-trigger-type).
^2^ A `TIMEOUT_USER` action can only be set up for `KEYWORD` and `MENTION_SPAM` [trigger types](#automod-trigger-type). The `MODERATE_MEMBERS` permission is required to use the `TIMEOUT_USER` action type.
^3^ A `QUARANTINE_USER` action can only be set up for `USER_PROFILE` [trigger types](#automod-trigger-type). The `MODERATE_MEMBERS` permission is required to use the `QUARANTINE_USER` action type.
###### AutoMod Action Metadata
Additional data used when an action is executed. Different fields are relevant based on the [action type](#automod-action-type).
| Field | Type | Description | Action Type |
| ---------------- | --------- | -------------------------------------------------------------------------------------- | ------------------ |
| channel_id | snowflake | The channel where user content should be logged | SEND_ALERT_MESSAGE |
| duration_seconds | integer | Duration (in seconds) after which the timeout expires (max 2419200) | TIMEOUT_USER |
| custom_message? | string | Additional explanation that will be shown to members whenever their message is blocked | BLOCK_MESSAGE |
## AutoMod Incidents Data Object
###### AutoMod Incidents Data Structure
| Field | Type | Description |
| ---------------------- | ------------------ | ------------------------------------------------------- |
| raid_detected_at | ?ISO8601 timestamp | When the last raid was detected |
| dm_spam_detected_at | ?ISO8601 timestamp | When the last DM spam was detected |
| invites_disabled_until | ?ISO8601 timestamp | When invites will be re-enabled (max 24 hours from now) |
| dms_disabled_until | ?ISO8601 timestamp | When DMs will be re-enabled (max 24 hours from now) |
###### Example AutoMod Incidents Data
```json
{
"raid_detected_at": "2024-01-01T18:00:00.000000+00:00",
"dm_spam_detected_at": "2024-01-01T18:00:00.000000+00:00",
"invites_disabled_until": "2024-01-01T18:00:00.000000+00:00",
"dms_disabled_until": "2024-01-01T18:00:00.000000+00:00"
}
```
## Endpoints
List Guild AutoMod Rules
Returns a list of [automod rule](#automod-rule-object) objects for the configured rules in the guild. Requires the `MANAGE_GUILD` permission.
Get Guild AutoMod Rule
Returns an [automod rule](#automod-rule-object) object for the given rule ID in the guild. Requires the `MANAGE_GUILD` permission.
Create Guild AutoMod Rule
Creates a new automod rule in the guild. Requires the `MANAGE_GUILD` permission. Returns an [automod rule](#automod-rule-object) on success. Fires an [Auto Moderation Rule Create](/gateway/gateway-events#auto-moderation-rule-create) Gateway event.
See [trigger types](#automod-trigger-type) for limits on how many rules of each trigger type can be created per guild.
###### JSON Params
| Field | Type | Description |
| --------------------- | ------------------------------------------------------ | ------------------------------------------------------------------- |
| name | string | The name of the rule |
| event_type | integer | The [type of event](#automod-event-type) that triggers the rule |
| trigger_type | integer | The [type of trigger](#automod-trigger-type) that invokes the rule |
| trigger_metadata? ^1^ | [trigger metadata](#automod-trigger-metadata) | Metadata used to determine whether the rule should be triggered |
| actions | array[[automod action](#automod-action-object) object] | The actions that will execute when the rule is triggered |
| enabled? | boolean | Whether the rule is enabled (default false) |
| exempt_roles? | array[snowflake] | The IDs of the roles that won't be affected by the rule (max 20) |
| exempt_channels? ^2^ | array[snowflake] | The IDs of the channels that won't be affected by the rule (max 50) |
^1^ See the "Trigger Types" column in [trigger metadata](#automod-trigger-metadata) to understand which [trigger types](#automod-trigger-type) require `trigger_metadata` to be set.
^2^ Only applicable to `KEYWORD`, `SPAM`, `KEYWORD_PRESET`, `MENTION_SPAM`, and `GUILD_POLICY` [trigger types](#automod-trigger-type).
Validate Guild AutoMod Rule
Validates a potential rule request's schema for the guild. Requires the `MANAGE_GUILD` permission.
###### JSON Params
| Field | Type | Description |
| -------------------- | ---------------------------------------------------- | -------------------------------- |
| trigger_metadata ^1^ | [trigger metadata](#automod-trigger-metadata) object | The trigger metadata to validate |
^1^ See the "Trigger Types" column in [trigger metadata](#automod-trigger-metadata) to understand which [trigger types](#automod-trigger-type) require `trigger_metadata` to be set.
###### Response Body
| Field | Type | Description |
| ---------------- | ---------------------------------------------------- | ------------------------------ |
| trigger_metadata | [trigger metadata](#automod-trigger-metadata) object | The validated trigger metadata |
Modify Guild AutoMod Rule
Modifies an existing rule in the guild. Requires the `MANAGE_GUILD` permission. Returns an [automod rule](#automod-rule-object) on success. Fires an [Auto Moderation Rule Update](/gateway/gateway-events#auto-moderation-rule-update) Gateway event.
###### JSON Params
| Field | Type | Description |
| --------------------- | ------------------------------------------------------ | ------------------------------------------------------------------- |
| name? | string | The name of the rule |
| event_type? | integer | The [type of event](#automod-event-type) that triggers the rule |
| trigger_metadata? ^1^ | [trigger metadata](#automod-trigger-metadata) object | Metadata used to determine whether the rule should be triggered |
| actions? | array[[automod action](#automod-action-object) object] | The actions that will execute when the rule is triggered |
| enabled? | boolean | Whether the rule is enabled (default false) |
| exempt_roles? | array[snowflake] | The IDs of the roles that won't be affected by the rule (max 20) |
| exempt_channels? ^2^ | array[snowflake] | The IDs of the channels that won't be affected by the rule (max 50) |
^1^ See the "Trigger Types" column in [trigger metadata](#automod-trigger-metadata) to understand which [trigger types](#automod-trigger-type) require `trigger_metadata` to be set.
^2^ Only applicable to `KEYWORD`, `SPAM`, `KEYWORD_PRESET`, `MENTION_SPAM`, and `GUILD_POLICY` [trigger types](#automod-trigger-type).
Delete Guild AutoMod Rule
Deletes a rule in the guild. Returns a 204 empty response on success. Requires the `MANAGE_GUILD` permission. Fires an [Auto Moderation Rule Delete](/gateway/gateway-events#auto-moderation-rule-delete) Gateway event.
Execute AutoMod Alert Action
Executes an alert action on an [AutoMod alert](#automod-alert). Requires the `MANAGE_GUILD` permission. Returns a 204 empty response on success. Fires a [Message Update](/gateway/gateway-events#message-update) Gateway event.
###### JSON Params
| Field | Type | Description |
| ----------------- | --------- | ----------------------------------------------------------------- |
| channel_id | snowflake | The ID of the channel where the alert was sent |
| message_id | snowflake | The ID of the AutoMod system message |
| alert_action_type | integer | The [type of alert action](#automod-alert-action-type) to execute |
Modify AutoMod Incident Actions
Sets the incident actions for the guild. Requires the `MANAGE_GUILD` permission. Fires a [Guild Update](/gateway/gateway-events#guild-update) Gateway event.
###### JSON Params
| Field | Type | Description |
| ----------------------- | ----------------- | ------------------------------------------------------- |
| invites_disabled_until? | ISO8601 timestamp | When invites will be re-enabled (max 24 hours from now) |
| dms_disabled_until? | ISO8601 timestamp | When DMs will be re-enabled (max 24 hours from now) |
###### Response Body
| Field | Type | Description |
| ---------------------- | ----------------- | ------------------------------------------------------- |
| invites_disabled_until | ISO8601 timestamp | When invites will be re-enabled (max 24 hours from now) |
| dms_disabled_until | ISO8601 timestamp | When DMs will be re-enabled (max 24 hours from now) |
###### Example Response
```json
{
"invites_disabled_until": "2024-01-01T18:00:00.000000+00:00",
"dms_disabled_until": "2024-01-01T18:00:00.000000+00:00"
}
```
Resolve AutoMod Incident
Resolves an [AutoMod incident](#automod-incident-notification). Requires the `MANAGE_GUILD` permission. Returns a 204 empty response on success. Fires a [Message Update](/gateway/gateway-events#message-update) Gateway event.
###### JSON Params
| Field | Type | Description |
| ---------------- | --------- | ---------------------------------------------------------------------------- |
| alert_message_id | snowflake | The ID of the AutoMod system message |
| reason | string | The [reason for resolving the notification](#automod-raid-resolution-reason) |
Report AutoMod Incident
Reports an ongoing raid [AutoMod incident](#automod-incident-notification). Requires the `MANAGE_GUILD` permission. Returns a 204 empty response on success. Fires a [Message Create](/gateway/gateway-events#message-update) Gateway event.
Clear Mention Raid Incident
Clears a mention raid [AutoMod incident](#automod-incident-notification). Requires the `MANAGE_GUILD` permission. Returns a 204 empty response on success.
---
# Messages
Link: https://docs.discord.food/resources/message
Messages are the core of Discord. They are the primary way users communicate with each other, and they can contain text, images, and other media. Embeddable content, such as polls, system messages, and calls are also represented as messages.
### Message Object
A message sent in a channel within Discord.
###### Message Structure
| Field | Type | Description |
| ----------------------------- | --------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------- |
| id | snowflake | The ID of the message |
| channel_id | snowflake | The ID of the channel the message was sent in |
| lobby_id? | snowflake | The ID of the lobby the message was sent in |
| author ^1^ | partial [user](/resources/user#user-object) object | The author of the message |
| content ^2^ | string | Contents of the message |
| timestamp | ISO8601 timestamp | When this message was sent |
| edited_timestamp | ?ISO8601 timestamp | When this message was last edited |
| tts | boolean | Whether this message will be read out by TTS |
| mention_everyone | boolean | Whether this message mentions everyone |
| mentions | array[partial [user](/resources/user#user-object) object] | Users specifically mentioned in the message |
| mention_roles | array[snowflake] | Roles specifically mentioned in this message |
| mention_channels? ^3^ | array[partial [channel](/resources/channel#channel-object) object] | Channels specifically mentioned in this message |
| attachments ^2^ | array[[attachment](#attachment-object) object] | The attached files |
| embeds ^2^ | array[[embed](#embed-object) object] | Content embedded in the message |
| reactions? | array[[reaction](#reaction-object) object] | Reactions on the message |
| nonce? | integer \| string | The message's nonce, used for message deduplication |
| pinned | boolean | Whether this message is pinned |
| webhook_id? | snowflake | The ID of the webhook that send the message |
| type | integer | The [type of message](#message-type) |
| activity? | [message activity](#message-activity-object) object | The rich presence activity the author is inviting users to |
| application? | [integration application](/resources/integration#integration-application-object) object | The application of the message's rich presence activity |
| application_id? | snowflake | The ID of the application; only sent for interaction responses and messages created through OAuth2 |
| flags | integer | The [message's flags](#message-flags) |
| message_reference? ^4^ | [message reference](#message-reference-object) object | The source of a crosspost, snapshot, channel follow add, pin, or reply message |
| referenced_message? ^5^ ^4^ | ?[message object](#message-object) | The message associated with the `message_reference` |
| message_snapshots? ^4^ | array[[message snapshot](#message-snapshot-object) object] | The partial message snapshot associated with the `message_reference` |
| call? | [message call](#message-call-object) object | The private channel call that prompted this message |
| interaction? **(deprecated)** | partial [message interaction](#message-interaction-object) object | The interaction the message is responding to, if the message is a response to an interaction without an existing message |
| interaction_metadata? | [message interaction](#message-interaction-object) object | The interaction the message originated from |
| resolved? | [resolved data](/interactions/receiving-and-responding#resolved-data-object) object | Data for users, members, channels, and roles referenced in this message |
| thread? | [channel](/resources/channel#channel-object) object | The thread that was started from this message, with the [`member`](/resources/channel#channel-object) key representing thread member data |
| role_subscription_data? | [message role subscription](#message-role-subscription-object) object | The role subscription purchase or renewal that prompted this message |
| purchase_notification? | [message purchase notification](#message-purchase-notification-object) object | The guild purchase that prompted this message |
| gift_info? | [message gift info](#message-gift-info-object) object | Information on the gift that prompted this message |
| components ^2^ | array[[message component](/resources/components#component-object) object] | The message's components (e.g. buttons, select menus) |
| sticker_items? | array[[sticker item](/resources/sticker#sticker-item-object) object] | The message's sticker items |
| stickers? | array[[sticker](/resources/sticker#sticker-object) object] | Extra rich information for the message's sticker items; only available in some contexts |
| poll? ^2^ | [poll](#poll-object) object | A poll! |
| changelog_id? | snowflake | The ID of the changelog that prompted this message |
| soundboard_sounds? | array[[soundboard sound](/resources/soundboard/#soundboard-sound-object) object] | The message's soundboard sounds |
| potions? | array[[potion](#potion-object) object] | Potions applied to the message |
| shared_client_theme? | [shared client theme](#shared-client-theme-object) object | The shared client theme |
^1^ The `author` object follows the structure of the user object, but may not be a valid user in the case where the message is generated by a webhook; you can recognize this by checking for the `webhook_id` key on the message object. In these cases, the below notice about the additional `member` keys does not apply as webhooks are not guild members.
^2^ Users must configure (or, in the case of bots, be approved for) the [`MESSAGE_CONTENT` intent](/gateway/using-gateway#message-content-intent) to receive non-empty values for these fields in most situations.
^3^ Not all channel mentions in a message will appear in `mention_channels`. Only textual channels that are visible to everyone in a lurkable guild will ever be included. Only crossposted messages (via Channel Following) currently include `mention_channels` at all. If no mentions in the message meet these requirements, this field will not be sent.
^4^ See the [message reference types](#message-reference-type) for more information on which message references have which fields.
^5^ This field is only returned for messages with a `type` of `REPLY`, `THREAD_STARTER_MESSAGE`, or `CONTEXT_MENU_COMMAND`. If the message is one of these but the `referenced_message` field is not present, the backend did not attempt to fetch the message, so its state is unknown. If the field exists but is `null`, the referenced message was deleted.
###### Partial Message Structure
This structure is a subset of the [message](#message-object) object above with the following fields:
| Field | Type | Description |
| ---------------------------------- | --------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------ |
| id | snowflake | The ID of the message |
| lobby_id? | snowflake | The ID of the lobby the message was sent in |
| channel_id ^1^ | snowflake | The ID of the channel the message was sent in |
| type? | integer | The [type of message](/resources/message#message-type) |
| content | string | Contents of the message |
| author | partial [user](/resources/user#user-object) object | The author of the message |
| activity? | [message activity](#message-activity-object) object | The rich presence activity the author is inviting users to |
| application? | [integration application](/resources/integration#integration-application-object) object | The application of the message's rich presence activity |
| application_id? | snowflake | The ID of the application |
| parent_application_id? | snowflake | The ID of the parent application |
| flags? | integer | The [message's flags](/resources/message#message-flags) |
| channel? ^2^ | [channnel](/resources/channel#channel-object) object | The channel the message was sent in |
| recipient_id? **(deprecated)** ^2^ | snowflake | The ID of the other recipient |
| moderation_metadata? | map[string, string] | Custom moderation metadata for the message (max 5 keys, 2000 characters per key and value) |
^1^ If the message was sent in a lobby and the lobby has no channel linked, this will be equal to the ID of the lobby.
^2^ These fields will be present only in ephemeral DM channels.
###### Message Type
Type `19` and `20` are only available in API v8 and above. In v7 and below, they are represented as type `0`. Additionally, type `21` is only available in API v9 and above.
| Value | Name | Description | Rendered Content | Deletable |
| ------ | --------------------------------------------- | --------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------- |
| 0 | DEFAULT | A default message (see below) | "\{content\}" | true |
| 1 | RECIPIENT_ADD | A message sent when a user is added to a group DM or thread | "\{author\} added \{mentions[0]\} to the \{group/thread\}." | false |
| 2 | RECIPIENT_REMOVE | A message sent when a user is removed from a group DM or thread | "\{author\} removed \{mentions[0]\} from the \{group/thread\}." | false |
| 3 | CALL | A message sent when a user creates a call in a private channel | participated ? "\{author\} started a call\{ended ? " that lasted \{duration\}" : " — Join the call"\}." : "You missed a call from \{author\} that lasted \{duration\}." | false |
| 4 | CHANNEL_NAME_CHANGE | A message sent when a group DM or thread's name is changed | "\{author\} \{content ? "changed the \{is_forum ? "post title" : "channel name"\}: **\{content\}**." : "removed the custom group name." \} | false |
| 5 | CHANNEL_ICON_CHANGE | A message sent when a group DM's icon is changed | "\{author\} changed the channel icon." | false |
| 6 | CHANNEL_PINNED_MESSAGE | A message sent when a message is pinned in a channel | "\{author\} pinned a message to this channel." | true |
| 7 | USER_JOIN | A message sent when a user joins a guild | See [user join message type](#user-join-message-type), obtained via the formula `timestamp_ms % 13` | true |
| 8 | PREMIUM_GUILD_SUBSCRIPTION | A message sent when a user subscribes to (boosts) a guild | "\{author\} just boosted the server\{content ? " **\{content\}** times"\}!" | true |
| 9 | PREMIUM_GUILD_SUBSCRIPTION_TIER_1 | A message sent when a user subscribes to (boosts) a guild to tier 1 | "\{author\} just boosted the server\{content ? " **\{content\}** times"\}! \{guild\} has achieved **Level 1!**" | true |
| 10 | PREMIUM_GUILD_SUBSCRIPTION_TIER_2 | A message sent when a user subscribes to (boosts) a guild to tier 2 | "\{author\} just boosted the server\{content ? " **\{content\}** times"\}! \{guild\} has achieved **Level 2!**" | true |
| 11 | PREMIUM_GUILD_SUBSCRIPTION_TIER_3 | A message sent when a user subscribes to (boosts) a guild to tier 3 | "\{author\} just boosted the server\{content ? " **\{content\}** times"\}! \{guild\} has achieved **Level 3!**" | true |
| 12 | CHANNEL_FOLLOW_ADD | A message sent when a news channel is followed | "\{author\} has added \{content\} to this channel. Its most important updates will show up here." | true |
| ~~13~~ | ~~GUILD_STREAM~~ | ~~A message sent when a user starts streaming in a guild~~ | | ~~true~~ |
| 14 | GUILD_DISCOVERY_DISQUALIFIED | A message sent when a guild is disqualified from discovery | "This server has been removed from Server Discovery because it no longer passes all the requirements. Check Server Settings for more details." | true |
| 15 | GUILD_DISCOVERY_REQUALIFIED | A message sent when a guild requalifies for discovery | "This server is eligible for Server Discovery again and has been automatically relisted!" | true |
| 16 | GUILD_DISCOVERY_GRACE_PERIOD_INITIAL_WARNING | A message sent when a guild has failed discovery requirements for a week | "This server has failed Discovery activity requirements for 1 week. If this server fails for 4 weeks in a row, it will be automatically removed from Discovery." | true |
| 17 | GUILD_DISCOVERY_GRACE_PERIOD_FINAL_WARNING | A message sent when a guild has failed discovery requirements for 3 weeks | "This server has failed Discovery activity requirements for 3 weeks in a row. If this server fails for 1 more week, it will be removed from Discovery." | true |
| 18 | THREAD_CREATED | A message sent when a thread is created | "\{author\} started a thread: **\{content\}**. See all threads." | true |
| 19 | REPLY | A message sent when a user replies to a message | "\{content\}" | true |
| 20 | CHAT_INPUT_COMMAND | A message sent when a user uses a slash command | "\{content\}" | true |
| 21 | THREAD_STARTER_MESSAGE | A message sent when a thread starter message is added to a thread | "\{referenced_message?.content\}" ?? "Sorry, we couldn't load the first message in this thread" | false |
| 22 | GUILD_INVITE_REMINDER | A message sent to remind users to invite friends to a guild | "Wondering who to invite?\nStart by inviting anyone who can help you build the server!" | true |
| 23 | CONTEXT_MENU_COMMAND | A message sent when a user uses a context menu command | "\{content\}" | true |
| 24 | AUTO_MODERATION_ACTION | A message sent when auto moderation takes an action | [Special embed rendered from `embeds[0]`](/resources/auto-moderation#automod-system-messages) | true ^1^ |
| 25 | ROLE_SUBSCRIPTION_PURCHASE | A message sent when a user purchases or renews a role subscription | "\{author\} \{is_renewal ? "renewed" : "joined"\} **\{role_subscription.tier_name\}** and has been a subscriber of \{guild\} for \{role_subscription.total_months_subscribed\} month(?s)!" | true |
| 26 | INTERACTION_PREMIUM_UPSELL | A message sent when a user is upsold to a premium interaction | "\{content\}" | true |
| 27 | STAGE_START | A message sent when a stage channel starts | "\{author\} started **\{content\}**" | true |
| 28 | STAGE_END | A message sent when a stage channel ends | "\{author\} ended **\{content\}**" | true |
| 29 | STAGE_SPEAKER | A message sent when a user starts speaking in a stage channel | "\{author\} is now a speaker." | true |
| 30 | STAGE_RAISE_HAND | A message sent when a user raises their hand in a stage channel | "\{author\} requested to speak." | true |
| 31 | STAGE_TOPIC | A message sent when a stage channel's topic is changed | "\{author\} changed the Stage topic: **\{content\}**" | true |
| 32 | GUILD_APPLICATION_PREMIUM_SUBSCRIPTION | A message sent when a user purchases an application premium subscription | "\{author\} upgraded \{application ?? "a deleted application"\} to premium for this server!" | true |
| ~~33~~ | ~~PRIVATE_CHANNEL_INTEGRATION_ADDED~~ | ~~A message sent when a user adds an application to group DM~~ | ~~"\{author\} added \{"the \{application\} app" ?? "a deleted application"\}. See our [Help Centre](https://support.discord.com/hc/en-us/articles/15104189280151-Apps-in-DMs) for more info."~~ | ~~false~~ |
| ~~34~~ | ~~PRIVATE_CHANNEL_INTEGRATION_REMOVED~~ | ~~A message sent when a user removed an application from a group DM~~ | ~~"\{author\} removed \{"the \{application\} app" ?? "a deleted application"\}. See our [Help Centre](https://support.discord.com/hc/en-us/articles/15104189280151-Apps-in-DMs) for more info."~~ | ~~false~~ |
| 35 | PREMIUM_REFERRAL | A message sent when a user gifts a premium (Nitro) referral | "\{content\}" | false |
| 36 | GUILD_INCIDENT_ALERT_MODE_ENABLED | A message sent when a user enabled lockdown for the guild | "\{author\} enabled security actions until \{content\}." | true |
| 37 | GUILD_INCIDENT_ALERT_MODE_DISABLED | A message sent when a user disables lockdown for the guild | "\{author\} disabled security actions." | true |
| 38 | GUILD_INCIDENT_REPORT_RAID | A message sent when a user reports a raid for the guild | "\{author\} reported a raid in \{guild\}." | true |
| 39 | GUILD_INCIDENT_REPORT_FALSE_ALARM | A message sent when a user reports a false alarm for the guild | "\{author\} reported a false alarm in \{guild\}." | true |
| 40 | GUILD_DEADCHAT_REVIVE_PROMPT | A message sent when no one sends a message in the current channel for 1 hour | "\{content\}" | true |
| 41 | CUSTOM_GIFT | A message sent when a user buys another user a gift | Special embed rendered from `embeds[0].url` and [`gift_info`](#message-gift-info-object) | true |
| 42 | GUILD_GAMING_STATS_PROMPT | | "\{content\}" | true |
| ~~43~~ | ~~POLL~~ | ~~A message sent when a user posts a poll~~ | | ~~true~~ |
| 44 | PURCHASE_NOTIFICATION | A message sent when a user purchases a guild product | "\{author\} has purchased \{purchase_notification.guild_product_purchase.product_name\}!" | true |
| ~~45~~ | ~~VOICE_HANGOUT_INVITE~~ | ~~A message sent when a user invites another user to hangout in a voice channel~~ | ~~Special embed rendered from `embeds[0]`~~ | ~~true~~ |
| 46 | POLL_RESULT | A message sent when a poll is finalized | [Special embed rendered from `embeds[0]`](#poll-result-notifications) | true |
| 47 | CHANGELOG | A message sent by the Discord Updates account when a new changelog is posted | "\{content\}" | true |
| 48 | NITRO_NOTIFICATION | A message sent when a Nitro promotion is triggered | Special embed rendered from `content` | true |
| 49 | CHANNEL_LINKED_TO_LOBBY | A message sent when a voice channel is linked to a lobby | "\{content\}" | true |
| 50 | GIFTING_PROMPT | A local-only ephemeral message sent when a user is prompted to gift Nitro to a friend on their friendship anniversary | Special embed | true |
| 51 | IN_GAME_MESSAGE_NUX | A local-only message sent when a user receives an in-game message NUX | "\{author\} messaged you from \{application.name\}. In-game chat may not include rich messaging features such as images, polls, or apps. [Learn More](https://support.discord.com/hc)" | true |
| 52 | GUILD_JOIN_REQUEST_ACCEPT_NOTIFICATION ^2^ | A message sent when a user accepts a guild join request | "\{join_request.user\}'s application to **\{content\}** was approved! Welcome!" | true |
| 53 | GUILD_JOIN_REQUEST_REJECT_NOTIFICATION ^2^ | A message sent when a user rejects a guild join request | "\{join_request.user\}'s application to **\{content\}** was rejected." | true |
| 54 | GUILD_JOIN_REQUEST_WITHDRAWN_NOTIFICATION ^2^ | A message sent when a user withdraws a guild join request | "\{join_request.user\}'s application to **\{content\}** has been withdrawn." | true |
| 55 | HD_STREAMING_UPGRADED | A message sent when a user upgrades to HD streaming | "\{author\} activated **HD Splash Potion**" | true |
| ~~56~~ | ~~CHAT_WALLPAPER_SET~~ | ~~A message sent when a user sets a DM wallpaper~~ | ~~"\{author\} changed the DM wallpaper to **\{chatWallpaperInfo.name\}**."~~ | ~~false~~ |
| ~~57~~ | ~~CHAT_WALLPAPER_REMOVE~~ | ~~A message sent when a user removes a DM wallpaper~~ | ~~"\{author\} removed the DM wallpaper."~~ | ~~false~~ |
| 58 | REPORT_TO_MOD_DELETED_MESSAGE | A message sent when a user resolves a moderation report by deleting the offending message | "\{author\} deleted the message" | true |
| 59 | REPORT_TO_MOD_TIMEOUT_USER | A message sent when a user resolves a moderation report by timing out the offending user | "\{author\} timed out \{mentions[0]\}" | true |
| 60 | REPORT_TO_MOD_KICK_USER | A message sent when a user resolves a moderation report by kicking the offending user | "\{author\} kicked \{mentions[0]\}" | true |
| 61 | REPORT_TO_MOD_BAN_USER | A message sent when a user resolves a moderation report by banning the offending user | "\{author\} banned \{mentions[0]\}" | true |
| 62 | REPORT_TO_MOD_CLOSED_REPORT | A message sent when a user resolves a moderation report | "\{author\} resolved this flag" | true |
| ~~63~~ | ~~EMOJI_ADDED~~ | ~~A message sent when a user adds a new emoji to a guild~~ | ~~"\{author\} added a new emoji, \{content\} **:\{emoji.name\}:**"~~ | ~~true~~ |
| 64 | PREMIUM_GROUP_INVITE | A message sent when a user invites another user to join a group Nitro subscription | Special embed | false |
| 65 | VOICE_SESSION | A message sent when a user starts a voice channel in a small guild | "\{author\} started a \[voice hangout\]\(\{channel\}\)." | true |
| 66 | GUILD_BOOST_UPSELL | A local-only ephemeral message asking the user to be the first to boost a guild | Special embed | true |
| 67 | FRIEND_REQUEST_ACCEPTED | A message sent when a user accepts another user's friend request | "\{author\} accepted your friend request." | true |
| 68 | MEDIA_MENTION_MESSAGE | | | true |
^1^ Can only be deleted by members with the `MANAGE_MESSAGES` permission.
^2^ The join request can be retrieved using the ID of the channel the message was sent in.
###### User Join Message Type
The type of rendered message is determined via converting the message's `timestamp` to a unix timestamp with millisecond precision, modulo 13.
| Value | Rendered Content |
| ----- | ------------------------------------------------- |
| 0 | "\{author\} joined the party." |
| 1 | "\{author\} is here." |
| 2 | "Welcome, \{author\}. We hope you brought pizza." |
| 3 | "A wild \{author\} appeared." |
| 4 | "\{author\} just landed." |
| 5 | "\{author\} just slid into the server." |
| 6 | "\{author\} just showed up!" |
| 7 | "Welcome \{author\}. Say hi!" |
| 8 | "\{author\} hopped into the server." |
| 9 | "Everyone welcome \{author\}!" |
| 10 | "Glad you're here, \{author\}." |
| 11 | "Good to see you, \{author\}." |
| 12 | "Yay you made it, \{author\}!" |
###### Message Flags
| Value | Name | Description |
| --------- | -------------------------------------- | ---------------------------------------------------------------------------- |
| 1 \<\< 0 | CROSSPOSTED | Message has been published to subscribed channels (via Channel Following) |
| 1 \<\< 1 | IS_CROSSPOST | Message originated from a message in another channel (via Channel Following) |
| 1 \<\< 2 | SUPPRESS_EMBEDS | Embeds will not be included when serializing this message |
| 1 \<\< 3 | SOURCE_MESSAGE_DELETED | Source message for this crosspost has been deleted (via Channel Following) |
| 1 \<\< 4 | URGENT | Message came from the urgent message system |
| 1 \<\< 5 | HAS_THREAD | Message has an associated thread, with the same ID as the message |
| 1 \<\< 6 | EPHEMERAL | Message is only visible to the user who invoked the interaction |
| 1 \<\< 7 | LOADING | Message is an interaction response and the bot is "thinking" |
| 1 \<\< 8 | FAILED_TO_MENTION_SOME_ROLES_IN_THREAD | Some roles were not mentioned and added to the thread (caps at 250) |
| 1 \<\< 9 | GUILD_FEED_HIDDEN | Message is hidden from the guild's feed |
| 1 \<\< 10 | SHOULD_SHOW_LINK_NOT_DISCORD_WARNING | Message contains a link that impersonates Discord |
| 1 \<\< 12 | SUPPRESS_NOTIFICATIONS | Message will not trigger push and desktop notifications |
| 1 \<\< 13 | IS_VOICE_MESSAGE | Message's audio attachment is rendered as a voice message |
| 1 \<\< 14 | HAS_SNAPSHOT | Message has a forwarded message snapshot attached |
| 1 \<\< 15 | IS_COMPONENTS_V2 | Message contains components from version 2 of the UI kit |
| 1 \<\< 16 | SENT_BY_SOCIAL_LAYER_INTEGRATION | Message was triggered by the social layer integration |
| 1 \<\< 17 | HIDDEN_SUSPENDED_USER | Message is hidden because the author is suspended |
| 1 \<\< 18 | IS_FIRST_BOOSTER | Marks guild boosted message as the first person to boost the guild |
| 1 \<\< 19 | IS_GUILD_OFFICIAL | Message is marked as official for the verified guild |
###### Example Message
```json
{
"id": "1076229630052270231",
"type": 0,
"content": "guh",
"channel_id": "1029316811088478299",
"author": {
"id": "545581357812678656",
"username": "alien",
"global_name": "Alien",
"avatar": "60387de43133809b083fb0f7458d2708",
"avatar_decoration_data": null,
"discriminator": "0",
"public_flags": 4194432,
"primary_guild": null
},
"attachments": [],
"embeds": [],
"mentions": [],
"mention_roles": [],
"pinned": false,
"mention_everyone": false,
"tts": false,
"timestamp": "2023-02-17T19:52:19.184000+00:00",
"edited_timestamp": null,
"flags": 0,
"components": [],
"reactions": [
{
"emoji": { "id": null, "name": "‼️" },
"count": 2,
"count_details": { "burst": 0, "normal": 82 },
"burst_colors": ["#f0ca59", "#4c704f", "#e07f45", "#f0ae59", "#f0bc59", "#f0a059", "#e08e45", "#f0984a"],
"me_burst": false,
"me": false
}
]
}
```
###### Example Crossposted Message
```json
{
"id": "1076589465084104805",
"type": 0,
"content": "test",
"channel_id": "909072028911423498",
"author": {
"bot": true,
"id": "999498190359371866",
"username": "Testing Server #News",
"avatar": "47b30f67c7e2c15637936cd180dd681c",
"discriminator": "0000"
},
"attachments": [],
"embeds": [],
"mentions": [],
"mention_roles": [],
"pinned": false,
"mention_everyone": false,
"tts": false,
"timestamp": "2023-02-18T19:42:10.541000+00:00",
"edited_timestamp": null,
"flags": 2,
"components": [],
"webhook_id": "999498190359371866",
"message_reference": {
"type": 0,
"channel_id": "901900332408381450",
"guild_id": "901900332408381449",
"message_id": "1076589456297054320"
}
}
```
### Message Activity Object
A rich presence invite in a message. See [Get Activity Secret](/resources/presence#get-activity-secret) for more information.
Activity invites are only valid while the user is still participating in the activity, up to 6 hours after they are sent.
###### Message Activity Structure
| Field | Type | Description |
| ------------------ | ------- | --------------------------------------------------------------------------------------------- |
| type | integer | The [type of activity request](/resources/presence#activity-action-type) |
| session_id ^1^ | string | The session ID associated with this activity |
| party_id? | string | The activity's party ID |
| name_override? ^2^ | string | The overridden activity name for the invite |
| icon_override? ^2^ | string | The overriden [activity asset image](/resources/presence#activity-asset-image) for the invite |
^1^ This field is send-only.
^2^ This field is receive-only.
### Message Call Object
A call in a private channel.
###### Message Call Structure
| Field | Type | Description |
| ------------------- | ------------------ | ---------------------------------------------------- |
| participants | array[snowflake] | The channel recipients that participated in the call |
| ended_timestamp ^1^ | ?ISO8601 timestamp | When the call ended, if it has |
^1^ This is a best-effort marker and may be unexpectedly `null` in some cases.
### Message Interaction Object
Metadata about the interaction, including the source of the interaction and the relevant guild and users.
###### Message Interaction Structure
| Field | Type | Description |
| -------------------------------- | --------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| id | snowflake | The ID of the interaction |
| type | integer | The [type of interaction](/interactions/receiving-and-responding#interaction-type) |
| name? | string | The name of the [application command](/interactions/application-commands#application-command-object) executed (including subcommands and subcommand groups), present only on [`APPLICATION_COMMAND`](/interactions/receiving-and-responding#interaction-type) interactions |
| command_type? | integer | The [type of application command](/interactions/application-commands#application-command-type) executed, present only on [`APPLICATION_COMMAND`](/interactions/receiving-and-responding#interaction-type) interactions |
| ephemerality_reason? | integer | The [reason this interaction is ephemeral](#ephemerality-reason) |
| user | partial [user](/resources/user#user-object) object | The user that initiated the interaction |
| authorizing_integration_owners | map[integer, snowflake] | IDs for each [installation context](/resources/application#application-integration-type) related to an interaction |
| original_response_message_id? | snowflake | The ID of the original response message, present only on [follow-up messages](/interactions/receiving-and-responding#followup-messages) |
| interacted_message_id? | snowflake | ID of the message that contained interactive component, present only on messages created from component interactions |
| triggering_interaction_metadata? | [message interaction](#message-interaction-object) object | Metadata for the interaction that was used to open the modal, present only on [`MODAL_SUBMIT`](/interactions/receiving-and-responding#interaction-type) interactions |
| target_user? | partial [user](/resources/user#user-object) object | The user that was targeted by the interaction, present only on [`USER_COMMAND`](/interactions/receiving-and-responding#interaction-type) interactions |
| target_message_id? | snowflake | The ID of the message that was targeted by the interaction, present only on [`MESSAGE_COMMAND`](/interactions/receiving-and-responding#interaction-type) interactions |
###### Partial Message Interaction Structure
This is sent on the [message object](/resources/message#message-object) when the message is a response to an interaction without an existing message.
This means responses to [Message Components](/resources/components) do not include this property, instead including a [message reference](/resources/message#message-reference-structure) object as components _always_ exist on preexisting messages.
| Field | Type | Description |
| ----- | -------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------- |
| id | snowflake | The ID of the interaction |
| type | integer | The [type of interaction](/interactions/receiving-and-responding#interaction-type) |
| name | string | The name of the [application command](/interactions/application-commands#application-command-object) executed (including subcommands and subcommand groups) |
| user | partial [user](/resources/user#user-object) object | The user that initiated the interaction |
###### Ephemerality Reason
| Value | Name | Description |
| ----- | ------------------------ | -------------------------------------------------------------------------------------------------- |
| 0 | NONE | Unknown reason |
| 1 | FEATURE_LIMITED | A required feature is temporarily limited |
| 2 | GUILD_FEATURE_LIMITED | A required feature is temporarily limited for this guild |
| 3 | USER_FEATURE_LIMITED | A required feature is temporarily limited for this user |
| 4 | SLOWMODE | The user is sending messages [past their `rate_limit_per_user`](/resources/channel#channel-object) |
| 5 | RATE_LIMIT | The user is being rate limited |
| 6 | CANNOT_MESSAGE_USER | The user does not have permission to message the target user |
| 7 | USER_VERIFICATION_LEVEL | The user does not meet the [guild `verification_level`](/resources/guild#guild-object) requirement |
| 8 | CANNOT_UNARCHIVE_THREAD | The user does not have permission to unarchive the thread |
| 9 | CANNOT_JOIN_THREAD | The user does not have permission to join the thread |
| 10 | MISSING_PERMISSIONS | The user does not have permission to send messages in the channel |
| 11 | CANNOT_SEND_ATTACHMENTS | The user does not have permission to send attachments in the channel |
| 12 | CANNOT_SEND_EMBEDS | The user does not have permission to send embeds in the channel |
| 13 | CANNOT_SEND_STICKERS | The user does not have permission to send stickers in the channel |
| 14 | AUTOMOD_BLOCKED | The message was blocked by AutoMod |
| 15 | HARMFUL_LINK | The message contains a link blocked by Discord |
| 16 | CANNOT_USE_COMMAND | The user does not have permission to use this command in this channel |
| 17 | BETA_GUILD_SIZE | The message is only visible to the user for this beta test |
| 18 | CANNOT_USE_EXTERNAL_APPS | The user does not have permission to use external applications in this channel |
### Message Role Subscription Object
A role subscription purchase or renewal.
###### Message Role Subscription Structure
| Field | Type | Description |
| ---------------------------- | --------- | --------------------------------------------------------------------- |
| role_subscription_listing_id | snowflake | The ID of the sku and listing that the user is subscribed to |
| tier_name | string | The name of the tier that the user is subscribed to |
| total_months_subscribed | integer | The cumulative number of months that the user has been subscribed for |
| is_renewal | boolean | Whether this notification is for a renewal rather than a new purchase |
### Message Purchase Notification Object
A guild product purchase notification.
###### Message Purchase Notification Structure
| Field | Type | Description |
| ---------------------- | ------------------------------------------------------------ | ----------------------------------------------------------- |
| type | integer | The [type of purchase](#message-purchase-notification-type) |
| guild_product_purchase | ?[guild product purchase](#guild-product-purchase-structure) | The guild product purchase that prompted this message |
###### Message Purchase Notification Type
Determines the type of purchase notification.
| Value | Name | Description |
| ----- | ------------- | ------------------------ |
| 0 | GUILD_PRODUCT | A guild product purchase |
###### Guild Product Purchase Structure
| Field | Type | Description |
| ------------ | --------- | ------------------------------------------------ |
| listing_id | snowflake | The ID of the product listing that was purchased |
| product_name | string | The name of the product that was purchased |
### Message Gift Info Object
Information on a gift that prompted a message. The relevant gift link is provided in the first embed of the message.
###### Message Gift Info Structure
| Field | Type | Description |
| ---------- | ---------------------------------------------------------------------- | ---------------------------------- |
| emoji? ^1^ | partial [emoji](/resources/emoji#emoji-object) object | The emoji associated with the gift |
| sound? | [message soundboard sound](#message-soundboard-sound-structure) object | The sound associated with the gift |
^1^ The emoji `name` and `id` fields are user-provided and not guaranteed to be valid or accurate. The `animated` field is never present.
###### Message Soundboard Sound Structure
| Field | Type | Description |
| ----- | ------ | ------------------------------ |
| id | string | The ID of the soundboard sound |
### Message Reference Object
A reference to an originating (replied to) message.
Message references are generic attribution on a message.
There are multiple message types that have a `message_reference` object.
###### Message Reference Structure
| Field | Type | Description |
| ----------------------- | -------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------- |
| type? ^1^ | integer | The [type of message reference](#message-reference-type) (default `DEFAULT`) |
| message_id? | snowflake | The ID of the originating message |
| channel_id ^1^ | snowflake | The ID of the originating channel |
| guild_id? | snowflake | The ID of the originating channel's guild |
| fail_if_not_exists? ^2^ | boolean | Whether to error if the referenced message doesn't exist instead of sending as a normal (non-reply) message (default true) |
| forward_only? ^2^ ^3^ | [message forward only](#message-forward-only-structure) object | What to include in the forwarded message |
^1^ Optional when creating a reply, but will always be present when receiving this object. In future API versions this will become a required field.
^2^ This field is send-only.
^3^ Only applicable to `FORWARD` type references.
###### Message Forward Only Structure
| Field | Type | Description |
| --------------- | ---------------- | --------------------------------------------------------------- |
| embed_indices? | array[integer] | The indices of the embeds from the original message to include |
| attachment_ids? | array[snowflake] | The IDs of the attachments from the original message to include |
###### Message Reference Type
Determines how associated data is populated.
| Value | Name | Description | Coupled Message Field |
| ----- | ----------- | --------------------------------------------------------- | --------------------- |
| 0 | DEFAULT | A standard reference used by replies and system messages | `referenced_message`? |
| 1 | FORWARD ^1^ | A reference used to point to a message at a point in time | `message_snapshot` |
^1^ This can only be used for basic messages, i.e., messages which do not have strong bindings to a non-global entity. Thus it only supports messages with `DEFAULT` or `REPLY` types, without any polls, calls, or components. This is subject to change in the future.
### Message Snapshot Object
A snapshot of a partial message at a point in time.
###### Message Snapshot Structure
| Field | Type | Description |
| ------- | ------------------------------------------------------ | ------------------------------------------------------ |
| message | [snapshot message](#snapshot-message-structure) object | A snapshot of the message when the forward was created |
###### Snapshot Message Structure
| Field | Type | Description |
| ------------------- | ----------------------------------------------------------------------------------- | ----------------------------------------------------------------------- |
| content ^1^ | string | Contents of the message |
| timestamp | ISO8601 timestamp | When this message was sent |
| edited_timestamp | ?ISO8601 timestamp | When this message was last edited |
| mentions | array[partial [user](/resources/user#user-object) object] | Users specifically mentioned in the message |
| mention_roles | array[snowflake] | Roles specifically mentioned in this message |
| attachments ^1^ | array[[attachment](#attachment-object) object] | The attached files |
| embeds ^1^ | array[[embed](#embed-object) object] | Content embedded in the message |
| type | integer | The [type of message](#message-type) |
| flags | integer | The [message's flags](#message-flags) |
| components? ^1^ ^2^ | array[[message component](/resources/components#component-object) object] | The message's components (e.g. buttons, select menus) |
| resolved? | [resolved data](/interactions/receiving-and-responding#resolved-data-object) object | Data for users, members, channels, and roles referenced in this message |
| sticker_items? | array[[sticker item](/resources/sticker#sticker-item-object) object] | The message's sticker items |
| soundboard_sounds? | array[[soundboard sound](/resources/soundboard/#soundboard-sound-object) object] | The message's soundboard sounds |
^1^ Users must configure (or, in the case of bots, be approved for) the [`MESSAGE_CONTENT` intent](/gateway/using-gateway#message-content-intent) to receive non-empty values for these fields in most situations.
^2^ Any interactive components will be artificially marked as disabled in the snapshot.
###### Example Message Snapshot
```json
{
"message": {
"type": 0,
"content": "guh",
"mentions": [],
"mention_roles": [],
"attachments": [],
"embeds": [],
"timestamp": "2023-02-17T19:52:19.184000+00:00",
"edited_timestamp": null,
"flags": 0,
"components": []
}
}
```
#### Message Types
There are multiple message types that have a `message_reference` object. Since message references are generic attribution to a previous message, there will be more types of messages which have this information in the future.
###### Crosspost Messages
- These are messages that originated from another channel (`IS_CROSSPOST` flag).
- These messages have all three fields, with data of the original message that was crossposted.
###### Forwarded Messages
- These are messages which capture a snapshot of a message, preventing spoofing or tampering (`HAS_SNAPSHOT` flag).
- These messages have an array of [`message_snapshots`](#message-snapshot-object) field containing a copy of the original message. This copy follows the same structure as a message, but has only the minimal set of fields returned required for context/rendering.
- A forwarded message can be identified by looking at it's `message_reference.type` field.
- Message snapshots will be the message data associated with the forward. Currently only 1 snapshot is supported.
- Message snapshots are taken at moment the forward message is created, and are **immutable**; any mutations to the orignal message will not be propagated.
- Forwards are created by including a [`message_reference`](#message-reference-object) of a [`FORWARD`](#message-reference-type) type when sending a message. When sending, `type`, `message_id`, and `channel_id` are required, and the requester must have `VIEW_CHANNEL` permissions.
- You can opt to only include specific attachments and embed in the forward by including the [`forward_only` field in the `message_reference`](#message-reference-object).
- Stricter rate limits for this feature have been applied based on:
- Number of forwards sent
- Total attachment size
###### Channel Follow Add Messages
- These are automatic messages sent when a channel is followed into the current channel (type `12`).
- These messages have the `channel_id` and `guild_id` fields, with data of the followed announcement channel.
###### Pin Messages
- These are automatic messages sent when a message is pinned (type `6`).
- These messages have `message_id` and `channel_id`, and `guild_id` if it is in a guild, with data of the message that was pinned.
###### Reply Messages
- These are messages replying to a previous message (type `19`).
- These messages have `message_id` and `channel_id`, and `guild_id` if it is in a guild, with data of the message that was replied to. The `channel_id` and `guild_id` will be the same as the reply.
- Replies are created by including a `message_reference` when sending a message. When sending, only `message_id` is required.
###### Thread Created Messages
- These are automatic messages sent when a public thread is created from an old message or without a message (type `18`).
- These messages have the `channel_id` and `guild_id` fields, with data of the created thread channel.
###### Thread Starter Messages
- These are the first message in public threads created from messages. They point back to the message in the parent channel from which the thread was started (type `21`).
- These messages have `message_id`, `channel_id`, and `guild_id`.
- These messages will never have `content`, `embeds`, or `attachments`, mainly just the `message_reference` and `referenced_message` fields.
###### Voice Messages
Voice messages are messages with the `VOICE_MESSAGE` flag. They have the following properties:
- They cannot be edited.
- Only a single audio attachment is allowed. No other attachments, content, embeds, stickers, etc.
- The [attachment](#attachment-object) has the additional fields `duration_secs` and `waveform`. The `Content-Type` of the attachment must begin with `audio/` to respect these fields.
The `waveform` is intended to be a preview of the entire voice message, with 1 byte per datapoint encoded in base64.
Official clients sample the recording at most once per 100 milliseconds, but will downsample so that no more than 256 datapoints are in the waveform.
When uploading a voice message attachment directly, the provided content type must match an audio content type to support the additional fields.
Official clients upload a 1 channel, 48000 Hz, 32 kbps Opus stream in an OGG container.
The encoding and waveform details are an implementation detail and may change without warning.
###### Clips
Clips are a special type of attachment that can be sent with a message. They are created by recording a stream and then clipping a portion of the recording.
Clip [attachments](#attachment-object) have the [`CLIP` flag](#attachment-flags) set, and have the additional fields `clip_created_at`, `clip_participants`, and optionally `title` and `application`.
When uploading a clip, an increased default file size limit of **100 MiB** applies.
An attachment can be sent as a clip by specifying the `is_clip`, `clip_created_at`, and `clip_participant_ids` fields, and optionally the `title` and `application_id` fields.
For an attachment to be a valid clip, it must be an MP4 file and have the text `uuid` and the hardcoded UUID of `a1c85299-3346-4db8-88f0-83f57a75a5ef` appended to the end of the file in binary format
(represented in hexadecimal bytes as `75 75 69 64 A1 C8 52 99 33 46 4D B8 88 F0 83 F5 7A 75 A5 EF`).
This can be done with the following pseudocode:
```py
import uuid
clip_uuid = uuid.UUID("a1c85299-3346-4db8-88f0-83f57a75a5ef")
with open("cat.mp4", "r+b") as file:
file.seek(0, 2)
file.write(b"uuid")
file.write(clip_uuid.bytes)
```
### Reaction Object
###### Reaction Structure
| Field | Type | Description |
| ------------- | ------------------------------------------------------------------ | ------------------------------------------------------------------- |
| count | integer | Total amount of times this emoji has been used to react |
| count_details | [reaction count details](#reaction-count-details-structure) object | Details about the number of times this emoji has been used to react |
| me | boolean | Whether the current user reacted using this emoji |
| me_burst | boolean | Whether the current user burst-reacted using this emoji |
| emoji | partial [emoji](/resources/emoji#emoji-object) object | Reaction emoji information |
| burst_colors | array[string] | The hex-encoded colors to render the burst reaction with |
###### Reaction Count Details Structure
| Field | Type | Description |
| ------ | ------- | ---------------------------------------------------------- |
| normal | integer | Amount of times this emoji has been used to react normally |
| burst | integer | Amount of times this emoji has been used to burst-react |
###### Reaction Type
| Value | Name | Description |
| ----- | ------ | ------------------------ |
| 0 | NORMAL | A normal reaction |
| 1 | BURST | A burst (super) reaction |
### Embed Object
The combined sum of characters in all `title`, `description`, `field.name`, `field.value`, `footer.text`, and `author.name` fields across all embeds attached to a message must not exceed 6000 characters. Leading and trailing whitespace characters are trimmed automatically.
Embeds are deduplicated by URL. If a message contains multiple embeds with the same URL, only the first is shown. If the duplicates have additional images, all images are shown in a grid in the first embed.
The media proxy caches link embeds for 30 minutes.
###### Embed Structure
| Field | Type | Description |
| ----------------------------- | --------------------------------------------------- | --------------------------------------------------------------------------------------- |
| title? | string | The title of the embed (max 256 characters) |
| type? ^1^ | string | The [type of embed](#embed-type) (always `rich` for sent embeds) |
| description? | string | The description of the embed (max 4096 characters) |
| url? | string | The URL of the embed (max 2048 characters) |
| timestamp? | ISO8601 timestamp | Timestamp of embed content |
| color? | integer | The color of the embed encoded as an integer representation of a hexadecimal color code |
| footer? | [embed footer](#embed-footer-structure) object | Embed footer information |
| image? | [embed media](#embed-media-structure) object | Embed image information |
| thumbnail? | [embed media](#embed-media-structure) object | Embed thumbnail information |
| video? ^1^ | [embed media](#embed-media-structure) object | Embed video information |
| provider? ^1^ | [embed provider](#embed-provider-structure) object | Embed provider information |
| author? | [embed author](#embed-author-structure) object | Embed author information |
| fields? | array[[embed field](#embed-field-structure) object] | The fields of the embed (max 25) |
| reference_id? ^1^ | snowflake | The ID of the message this embed was generated from |
| content_scan_version? ^1^ ^2^ | integer | The version of the explicit content scan filter this embed was scanned with |
| flags? ^1^ | integer | The [embed's flags](#embed-flags) |
^1^ These fields cannot be specified in a rich embed.
^2^ This field will be missing if the embed has not yet been scanned. In this case, a scan can be triggered with the [Scan Explicit Media](#scan-explicit-media) endpoint. If the field is present and set to `0`, the embed is not eligible for a scan (e.g. it is a textual embed without media).
###### Embed Type
Most embed types are "loosely defined" and, for the most part, are not used by clients for rendering. Embed attributes power what is rendered.
| Type | Description |
| ---------------------------------------- | ----------------------------------------------------------------------------------------- |
| age_verification_system_notification ^1^ | [Age verification system message embed](#age-verification-system-message) |
| application_news **(deprecated)** | Application news embed |
| article | Article embed |
| auto_moderation_message ^1^ | [AutoMod alert](/resources/auto-moderation#automod-alert) |
| auto_moderation_notification ^1^ | [AutoMod incident notification](/resources/auto-moderation#automod-incident-notification) |
| gift | Gift embed |
| gifv | Animated GIF image rendered as a video embed |
| image | Image embed |
| link | Link embed |
| poll_result ^1^ | [Poll result notification](#poll-result-notifications) |
| post_preview ^2^ | Media channel post preview embed |
| rich | Generic embed rendered from embed attributes |
| safety_policy_notice ^1^ | [Safety policy notice embed](/resources/safety-hub#safety-policy-notice) |
| safety_system_notification ^1^ | [Safety system message embed](/resources/safety-hub#safety-system-notification) |
| video | Video embed |
^1^ These embed types are system-generated and cannot be sent by users. Their [`fields` array](#embed-object) represents the object linked in the description as a list of key-value pairs.
^2^ This embed type is used to signal to the client to render a [preview of the linked media channel post](#get-channel-media-preview). This embed is created for URLs that link to a media channel post if the channel is a paywalled role subscription benefit. The URL is always in the format `https://discord.com/channels/:guild_id/:parent_id/threads/:thread_id/:initial_message_id`.
###### Embed Flags
| Value | Name | Description |
| -------- | -------------------------- | ------------------------------------------------------------------------------------------------------ |
| 1 \<\< 4 | CONTAINS_EXPLICIT_MEDIA | Embed was flagged as [sensitive content](https://support.discord.com/hc/en-us/articles/18210995019671) |
| 1 \<\< 5 | CONTENT_INVENTORY_ENTRY | Embed is a legacy content inventory reply |
| 1 \<\< 6 | CONTAINS_GORE_CONTENT | Embed was flagged as [gore](https://support.discord.com/hc/en-us/articles/18210995019671) |
| 1 \<\< 7 | CONTAINS_SELF_HARM_CONTENT | Embed was flagged as [self-harm content](https://support.discord.com/hc/en-us/articles/18210995019671) |
###### Embed Media Structure
| Field | Type | Description |
| -------------------------- | ---------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------- |
| url | string | Source URL of media (only supports http(s) and attachments) (max 2048 characters) |
| proxy_url? ^1^ | string | A proxied URL of the media |
| height? ^1^ | integer | Height of media |
| width? ^1^ | integer | Width of media |
| flags? ^1^ | integer | The [media's attachment flags](#attachment-flags) |
| description? | string | Alt text for the media |
| content_type? ^1^ | string | The attachment's [media type](https://en.wikipedia.org/wiki/Media_type) |
| content_scan_metadata? ^1^ | [content scan metadata](#content-scan-metadata-structure) object | The content scan metadata for the media |
| placeholder_version? ^1^ | integer | The attachment placeholder protocol version (currently 1) |
| placeholder? ^1^ | string | A low-resolution [thumbhash](https://github.com/evanw/thumbhash) of the media, to display before it is loaded |
^1^ This field is received only and cannot be set.
###### Embed Provider Structure
| Field | Type | Description |
| ----- | ------ | --------------------------------------------- |
| name? | string | The name of the provider (max 256 characters) |
| url? | string | URL of the provider (max 2048 characters) |
###### Embed Author Structure
| Field | Type | Description |
| ------------------- | ------ | --------------------------------------------------------------------------------------------- |
| name | string | The name of the author (max 256 characters) |
| url? | string | URL of the author (only supports http(s)) (max 2048 characters) |
| icon_url? | string | Source URL of the author's icon (only supports http(s) and attachments) (max 2048 characters) |
| proxy_icon_url? ^1^ | string | A proxied URL of the author's icon |
^1^ This field is received only and cannot be set.
###### Embed Footer Structure
| Field | Type | Description |
| ------------------- | ------ | ------------------------------------------------------------------------------------------- |
| text | string | The footer text (max 2048 characters) |
| icon_url? | string | Source URL of the footer icon (only supports http(s) and attachments) (max 2048 characters) |
| proxy_icon_url? ^1^ | string | A proxied URL of the footer icon |
^1^ This field is received only and cannot be set.
###### Embed Field Structure
| Field | Type | Description |
| ------- | ------- | -------------------------------------------------------- |
| name | string | The name of the field (max 256 characters) |
| value | string | The value of the field (max 1024 characters) |
| inline? | boolean | Whether this field should display inline (default false) |
###### Content Scan Metadata Structure
| Field | Type | Description |
| ------- | ------- | --------------------------------------------------------------------------- |
| flags | integer | The [content scan flags](#content-scan-flags) of the media |
| version | integer | The version of the explicit content scan filter this media was scanned with |
###### Content Scan Flags
| Value | Name | Description |
| -------- | -------- | ----------------------------------------- |
| 1 \<\< 0 | EXPLICIT | The media was flagged as explicit content |
| 1 \<\< 1 | GORE | The media was flagged as gore |
### Attachment Object
###### Attachment Structure
When sending/editing messages, only `id` is required. `filename` is also required when [uploading to Google Cloud](/topics/cloud-uploads).
| Field | Type | Description |
| ----------------------------- | ------------------------------------------------------------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| id | snowflake | The attachment ID |
| filename | string | The name of file attached (1-1024 characters) |
| title? | string | The name of the file without the extension or title of the clip (max 1024 characters, automatically provided when the filename is normalized or randomly generated due to invalid characters) |
| uploaded_filename? ^3^ | string | The name of the file pre-uploaded to Discord's GCP bucket |
| description? | string | Alt text for the file (max 1024 characters) |
| content_type? ^2^ | string | The attachment's [media type](https://en.wikipedia.org/wiki/Media_type) |
| size | integer | The size of file in bytes |
| url ^2^ | string | Source URL of the file |
| proxy_url ^2^ ^4^ | string | A proxied url of the file |
| height? ^2^ | ?integer | Height of image |
| width? ^2^ | ?integer | Width of image |
| content_scan_version? ^2^ ^5^ | integer | The version of the explicit content scan filter this attachment was scanned with |
| placeholder_version? ^2^ | integer | The attachment placeholder protocol version (currently 1) |
| placeholder? ^2^ | string | A low-resolution [thumbhash](https://github.com/evanw/thumbhash) of the attachment, to display before it is loaded |
| ephemeral? ^1^ ^2^ | boolean | Whether this attachment is ephemeral |
| duration_secs? | float | Duration of the audio file (if [voice message](#voice-messages)) |
| waveform? | string | Base64-encoded bytearray representing a sampled waveform (if [voice message](#voice-messages)) |
| flags? ^6^ | integer | The [attachment's flags](#attachment-flags) |
| is_clip? ^6^ ^7^ ^8^ | boolean | Whether the file being uploaded is a [clipped recording of a stream](https://support.discord.com/hc/en-us/articles/16861982215703-Clips) |
| is_thumbnail? ^6^ | boolean | Whether the file being uploaded is a thumbnail |
| is_remix? ^6^ | boolean | Whether this attachment is a [remixed](https://support.discord.com/hc/en-us/articles/15145601963031-Remix-FAQ) version of another attachment |
| is_spoiler? ^6^ | boolean | Whether this attachment is a spoiler |
| clip_created_at? ^8^ | ISO8601 timestamp | When the clip was created |
| clip_participant_ids? ^7^ ^8^ | array[snowflake] | The IDs of the participants in the clip (max 100) |
| clip_participants? ^8^ | array[partial [user](/resources/user#user-object) object] | The participants in the clip (max 100) |
| application_id? ^8^ | snowflake | The ID of the application the clip was taken in |
| application? ^8^ | ?partial [application](/resources/application#application-object) object | The application the clip was taken in |
^1^ Ephemeral attachments will automatically be removed after a set period of time. Ephemeral attachments on messages are guaranteed to be available as long as the message itself exists.
^2^ These fields are received only and cannot be set.
^3^ This field is send-only. See [Cloud Uploads](/topics/cloud-uploads) topic for more information.
^4^ The proxy URL only supports attachments with a defined `width` and `height`, such as images and videos. For all other attachments, the proxy returns a 415 unsupported media type error.
^5^ This field will be missing if the attachment has not yet been scanned. In this case, a scan can be triggered with the [Explicit Content Scan](#scan-explicit-media) endpoint. If the field is present and set to `0`, the attachment is not eligible for a scan.
^6^ The `flags` field is received only and cannot be set directly. To set flags, use the `is_clip`, `is_thumbnail`, `is_remix`, and `is_spoiler` send-only fields.
^7^ When sending a clip, `is_clip`, `clip_created_at`, and `clip_participant_ids` are required. [See message types](#clips) for more information.
^8^ The `clip_participant_ids` and `application_id` fields are send-only. You will receive the `clip_participants` and `application` fields back when retrieving the [message](#message-object).
###### Attachment Flags
| Value | Name | Description |
| -------- | -------------------------- | ------------------------------------------------------------------------------------------------------------------- |
| 1 \<\< 0 | IS_CLIP | Attachment is a [clipped recording of a stream](https://support.discord.com/hc/en-us/articles/16861982215703-Clips) |
| 1 \<\< 1 | IS_THUMBNAIL | Attachment is a thumbnail |
| 1 \<\< 2 | IS_REMIX | Attachment has been [remixed](https://support.discord.com/hc/en-us/articles/15145601963031-Remix-FAQ) |
| 1 \<\< 3 | IS_SPOILER | Attachment is a spoiler |
| 1 \<\< 4 | CONTAINS_EXPLICIT_MEDIA | Attachment was flagged as [sensitive content](https://support.discord.com/hc/en-us/articles/18210995019671) |
| 1 \<\< 5 | IS_ANIMATED | Attachment is an animated image |
| 1 \<\< 6 | CONTAINS_GORE_CONTENT | Attachment was flagged as [gore](https://support.discord.com/hc/en-us/articles/18210995019671) |
| 1 \<\< 7 | CONTAINS_SELF_HARM_CONTENT | Attachment was flagged as [self-harm content](https://support.discord.com/hc/en-us/articles/18210995019671) |
### Allowed Mentions Object
The allowed mention field allows for more granular control over mentions without various hacks to the message content. This will always validate against message content to avoid phantom pings (e.g. to ping everyone, you must still have "@everyone" in the message content) and check against user permissions.
###### Allowed Mention Types
| Value | Description |
| -------- | ------------------------------------- |
| roles | Controls role mentions |
| users | Controls user mentions |
| everyone | Controls @everyone and @here mentions |
###### Allowed Mentions Structure
| Field | Type | Description |
| ------------- | ---------------- | ------------------------------------------------------------------------------------------ |
| parse? | array[string] | The [allowed mention types](#allowed-mention-types) to parse from the content |
| roles? | array[snowflake] | The role IDs to mention (max 100) |
| users? | array[snowflake] | The user IDs to mention (max 100) |
| replied_user? | boolean | For replies, whether to mention the author of the message being replied to (default false) |
###### Allowed Mentions Reference
Due to the complexity of possibilities, we have included a set of examples and behavior for the allowed mentions field.
If `allowed_mentions` is _not_ passed in (i.e. the key does not exist), the mentions will be parsed via the content. This corresponds with existing behavior.
In the example below we would ping @here (and also @role124 and @user123)
```json
{
"content": "@here Hi there from <@123>, cc <@&124>"
}
```
To suppress all mentions in a message use:
```json
{
"content": "@everyone hi there, <@&123>",
"allowed_mentions": {
"parse": []
}
}
```
This will suppress _all_ mentions in the message (no @everyone or user mention).
The `parse` field is mutually exclusive with the other fields. In the example below, we would ping users `123` and role `124`, but _not_ @everyone. Note that passing a falsy value ([], `null`) into the `users` field does not trigger a validation error.
```json
{
"content": "@everyone <@123> <@&124>",
"allowed_mentions": {
"parse": ["users", "roles"],
"users": []
}
}
```
In the next example, we would ping @everyone, (and also users `123` and `124` if they suppressed
@everyone mentions), but we would not ping any roles.
```json
{
"content": "@everyone <@123> <@124> <@125> <@&200>",
"allowed_mentions": {
"parse": ["everyone"],
"users": ["123", "124"]
}
}
```
Due to possible ambiguities, not all configurations are valid. An _invalid_ configuration is as follows
```json
{
"content": "@everyone <@123> <@124> <@125> <@&200>",
"allowed_mentions": {
"parse": ["users"],
"users": ["123", "124"]
}
}
```
Because `parse: ["users"]` and `users: ["123", "124"]` are both present, Discord would throw a validation error.
This is because the conditions cannot be fulfilled simultaneously (they are mutually exclusive).
Any entities with an ID included in the list of IDs can be mentioned. Note that the IDs of entities not present in the message's content will simply be ignored.
e.g. The following example is valid, and would mention user 123, but _not_ user 125 since there is no mention of
user 125 in the content.
```json
{
"content": "<@123> Time for some memes.",
"allowed_mentions": {
"users": ["123", "125"]
}
}
```
### Poll Object
The poll object has a lot of levels and nested structures. It was also designed
to support future extensibility, so some fields may appear to be more complex than
necessary.
###### Poll Structure
| Field | Type | Description |
| ----------------- | --------------------------------------------------- | ------------------------------------------------ |
| question ^1^ | [poll media](#poll-media-structure) object | The question of the poll |
| answers | array[[poll answer](#poll-answer-structure) object] | The answers available in the poll |
| expiry ^2^ | ?IS08601 timestamp | When the poll ends |
| allow_multiselect | boolean | Whether a user can select multiple answers |
| layout_type | integer | The [layout type](#poll-layout-type) of the poll |
| results? | [poll results](#poll-results-structure) object | The results of the poll |
^1^ Only `text` is supported.
^2^ `expiry` is marked as nullable to support non-expiring polls in the future, but all polls have an expiry currently.
###### Poll Create Structure
This is the request object used when creating a poll across the different endpoints.
It is similar but not exactly identical to the main [poll](#poll-structure) object.
The main difference is that the request has `duration` which eventually becomes `expiry`.
| Field | Type | Description |
| ------------------ | --------------------------------------------------- | -------------------------------------------------------------------- |
| question ^1^ | [poll media](#poll-media-structure) object | The question of the poll |
| answers | array[[poll answer](#poll-answer-structure) object] | Each of the answers available in the poll (max 10) |
| duration | integer | Number of hours the poll should be open for (max 32 days, default 1) |
| allow_multiselect? | boolean | Whether a user can select multiple answers (default false) |
| layout_type? | integer | The [layout type](#poll-layout-type) of the poll (default `DEFAULT`) |
^1^ Only `text` is supported.
###### Poll Layout Type
Different layouts for polls will come in the future. For now though, this value will always be `DEFAULT`.
| Value | Name | Description |
| ----- | ---------------------- | ------------------------------------- |
| 1 | DEFAULT | The default layout type |
| ~~2~~ | ~~IMAGE_ONLY_ANSWERS~~ | ~~Poll answers can have only images~~ |
###### Poll Media Structure
The poll media object is a common object that backs both the question and answers.
For now, `question` only supports `text`, while answers can have an optional `emoji`.
| Field | Type | Description |
| ---------- | ----------------------------------------------------- | --------------------------------------------------------------------------------- |
| text? ^1^ | string | The text of the field (max 300 characters for question, 55 characters for answer) |
| emoji? ^2^ | partial [emoji](/resources/emoji#emoji-object) object | The emoji of the field |
^1^ `text` should always be non-`null` for both questions and answers, but do not depend on that in the future.
^2^ When creating a poll answer with an emoji, clients only needs to send either the `id` (custom emoji) or `name` (default emoji) as the only field.
###### Poll Answer Structure
The `answer_id` is a number that labels each answer.
As an implementation detail, it currently starts at 1 for the first answer and goes up sequentially.
We recommend against depending on this sequence.
Currently, there is a maximum of 10 answers per poll.
| Field | Type | Description |
| ------------- | ------------------------------------------ | ---------------------- |
| answer_id ^1^ | integer | The ID of the answer |
| poll_media | [poll media](#poll-media-structure) object | The data of the answer |
^1^ When sending, this field is optional.
###### Poll Results Structure
In a nutshell, this contains the number of votes for each answer.
The `results` field may be not present in certain responses where, as an implementation detail, Discord does not fetch the poll results in the backend.
This should be treated as "unknown results", as opposed to "no results". You can keep using the results if you have previously received them through other means.
Due to the intricacies of counting at scale, while a poll is in progress the results may not be perfectly accurate.
They usually are accurate, and shouldn't deviate significantly—it's just difficult to make guarantees.
To compensate for this, after a poll is finished there is a background job which performs a final, accurate tally of votes.
This tally concludes once `is_finalized` is `true`. Polls that have ended will also always contain results.
If `answer_counts` does not contain an entry for a particular answer, then there are no votes for that answer.
| Field | Type | Description |
| ------------- | --------------------------------------------------------------- | --------------------------------------------- |
| is_finalized | boolean | Whether the votes have been precisely counted |
| answer_counts | array[[poll answer count](#poll-answer-count-structure) object] | The counts for each answer |
###### Poll Answer Count Structure
| Field | Type | Description |
| -------- | ------- | ---------------------------------------------- |
| id | integer | The ID of the answer |
| count | integer | The number of votes for this answer |
| me_voted | boolean | Whether the current user voted for this answer |
###### Example Poll
```json
{
"question": {
"text": "Aliens?"
},
"answers": [
{
"answer_id": 1,
"poll_media": {
"text": "Alien"
}
},
{
"answer_id": 2,
"poll_media": {
"text": "Alien 2",
"emoji": {
"id": null,
"name": "👽"
}
}
},
{
"answer_id": 3,
"poll_media": {
"text": "Alien 3",
"emoji": {
"id": "1120790948302033046",
"name": "meowlien"
}
}
}
],
"expiry": "2024-05-02T10:00:02.039342+00:00",
"allow_multiselect": true,
"layout_type": 1,
"results": {
"answer_counts": [
{
"id": 1,
"count": 1,
"me_voted": false
}
],
"is_finalized": false
}
}
```
### Poll Result Notifications
Poll result notifications are sent as standard [messages](#message-object) in the channel with the `POLL_RESULT` [message type](#message-type).
The author of the message is the user who created the poll, and the message has a reference pointing to the original poll message.
These messages have a special [embed](#embed-object) structure which contains information about the poll results.
The custom embed fields below are collapsed as a list of key-value pairs into the `fields` array on the [embed object](#embed-object).
As [embed field values](#embed-field-structure) are strings, all below fields are serialized as strings, even if the type is specified as otherwise.
###### Poll Result Embed Structure
| Field | Type | Description |
| ----------------------------- | --------- | --------------------------------------------------- |
| poll_question_text | string | The text of the poll question |
| total_votes | integer | The total number of votes on the poll |
| victor_answer_id? ^1^ | integer | The ID of the winning answer |
| victor_answer_text? ^1^ | string | The text of the winning answer |
| victor_answer_emoji_id? ^1^ | snowflake | The ID of the emoji of the winning answer |
| victor_answer_emoji_name? ^1^ | string | The name of the emoji of the winning answer |
| victor_answer_emoji_animated? | boolean | Whether the emoji of the winning answer is animated |
| victor_answer_votes | integer | The number of votes on the winning answer |
^1^ If these fields are omitted, the poll did not have a decisive winner.
###### Example Poll Result Embed
```json
{
"type": "poll_result",
"fields": [
{
"name": "poll_question_text",
"value": "aliens?",
"inline": false
},
{
"name": "victor_answer_votes",
"value": "100",
"inline": false
},
{
"name": "total_votes",
"value": "101",
"inline": false
},
{
"name": "victor_answer_id",
"value": "1",
"inline": false
},
{
"name": "victor_answer_text",
"value": "ofc",
"inline": false
},
{
"name": "victor_answer_emoji_id",
"value": "1243729917288386560",
"inline": false
},
{
"name": "victor_answer_emoji_name",
"value": "cheeks",
"inline": false
},
{
"name": "victor_answer_emoji_animated",
"value": "true",
"inline": false
}
]
}
```
### Age Verification System Message
Age verification system messages are sent by the official Discord account to notify the user of their results. The message content will contain a localized, user-friendly message explaining their classification with a relevant help center link.
###### Age Verification System Message Embed Structure
| Field | Type | Description |
| ------------ | ------ | ------------------------------------------------------------------------------------------------------- |
| ctas? | string | Comma-separated list of CTAs to display (currently only `retry`) |
| content_type | string | The [age verification system message content type](#age-verification-system-message-embed-content-type) |
###### Age Verification System Message Embed Content Type
| Name | Description |
| -------------- | ---------------------------------------------------- |
| verified_adult | User was verified as a adult |
| verified_teen | User was verified as a teen |
| error | An error occured during the age verification process |
###### Example Age Verification System Message Embed
```json
{
"type": "age_verification_system_notification",
"fields": [
{
"name": "content_type",
"value": "verified_teen",
"inline": false
},
{
"name": "ctas",
"value": "retry",
"inline": false
}
]
}
```
### Potion Object
###### Potion Structure
| Field | Type | Description |
| ---------- | ------------------------------------------------------------ | ----------------------------------------- |
| used_by | snowflake | The ID of the user who applied the potion |
| type | integer | The [type of the potion](#potion-type) |
| emoji | array[partial [emoji](/resources/emoji#emoji-object) object] | The emoji associated with the potion |
| created_at | ISO8601 timestamp | When the potion was applied |
###### Potion Type
| Value | Name | Description |
| ----- | -------- | ----------------- |
| 0 | CONFETTI | A Confetti potion |
###### Confetti Potion Structure
| Field | Type | Description |
| ------------- | ----------------------------------------------------- | ------------------------------------ |
| message_emoji | partial [emoji](/resources/emoji#emoji-object) object | The emoji associated with the potion |
###### Example Potion
```json
{
"type": 0,
"created_at": "2025-02-06T12:34:56.855553+00:00",
"used_by": "177424155371634688",
"emoji": [
{
"name": "👽",
"id": null
}
]
}
```
### Shared Client Theme Object
###### Shared Client Theme Structure
| Field | Type | Description |
| -------------- | ------------- | ------------------------------------------------------------ |
| colors | array[string] | The hex-encoded colors associated with the theme (1-5 items) |
| gradient_angle | integer | The angle of the gradient (0-360) |
| base_mix | integer | The base mix value (0-100) |
| base_theme? | ?integer | The [base theme type](/resources/user-settings-proto#theme) |
###### Example Shared Client Theme
```json
{
"colors": ["22D71D", "7A9374", "FD2EF6", "C24462", "9B5300"],
"gradient_angle": 180,
"base_mix": 100,
"base_theme": 1
}
```
### Conversation Summary Object
Conversation summaries are short, LLM-generated descriptions of a channel's activity.
###### Conversation Summary Structure
| Field | Type | Description |
| ----------- | ---------------- | ------------------------------------------------------- |
| id | snowflake | The ID of the summary |
| topic | string | A short description of the topic of the conversation |
| summ_short | string | A brief summary of the conversation |
| message_ids | array[snowflake] | The IDs of the messages included in the summary |
| people | array[snowflake] | The IDs of the users included in the summary |
| unsafe | boolean | Whether the summary contains potentially unsafe content |
| start_id | snowflake | The ID of the first message in the conversation |
| end_id | snowflake | The ID of the last message in the conversation |
| count | integer | The number of messages included in the summary |
| source | integer | The [source of the summary](#summary-source) |
| type | integer | The [type of summary](#summary-type) |
###### Summary Source
| Value | Name | Description |
| ----- | -------- | ------------------------------------- |
| 0 | SOURCE_0 | The summary was generated by source 0 |
| 1 | SOURCE_1 | The summary was generated by source 1 |
| 2 | SOURCE_2 | The summary was generated by source 2 |
###### Summary Type
| Value | Name | Description |
| ----- | -------- | ------------------------------------- |
| 0 | UNSET | The summary type is unset |
| 1 | SOURCE_1 | The summary was generated by source 1 |
| 2 | SOURCE_2 | The summary was generated by source 2 |
| 3 | UNKNOWN | Unknown |
###### Example Conversation Summary
```json
{
"topic": "Rare Footage of Alien Cat",
"summ_short": "Conversation about rare footage of an alien cat species.",
"message_ids": ["1314941815144845413", "1314944583397937213"],
"people": ["852892297661906993", "841509053422632990"],
"id": "1315651706670813286",
"unsafe": false,
"start_id": "1314941815144845413",
"end_id": "1315650462522802196",
"count": 2,
"source": 2,
"type": 3
}
```
### Message Pin Object
###### Message Pin Structure
| Field | Type | Description |
| --------- | --------------------------------- | ------------------------------------------- |
| pinned_at | ISO8601 timestamp | When the message was pinned |
| message | [message](#message-object) object | The pinned message, without `reactions` key |
## Endpoints
List Messages
Returns a list of [message](#message-object) objects in the channel. Requires the `VIEW_CHANNEL` permission if operating on a guild channel. If the current user is missing the `READ_MESSAGE_HISTORY` permission in the channel then this will return no messages (since they cannot read the message history).
###### Query String Params
| Field | Type | Description |
| ------- | --------- | ---------------------------------------------------- |
| around? | snowflake | Get messages around this message ID |
| before? | snowflake | Get messages before this message ID |
| after? | snowflake | Get messages after this message ID |
| limit | integer | Max number of messages to return (1-100, default 50) |
List DM Messages
Returns a list of partial [message](#partial-message-structure) objects in the DM channel.
This endpoint is subject to the following limitations:
1. A DM channel must already exist between the user and the recipient
1. Both users must have authorized the OAuth2 application for message history to be retrievable
1. Only a maximum of 200 messages and up to 72 hours of history can be retrieved
This endpoint is only usable with an OAuth2 access token with the `dm_channels.messages.read` scope.
###### Query String Params
| Field | Type | Description |
| ----- | ------- | ---------------------------------------------------- |
| limit | integer | Max number of messages to return (1-200, default 50) |
Preload Messages
Preloads the last message sent in a series of private channels. Returns a list of [message](#message-object) objects without the `reactions` key.
###### JSON Body
| Field | Type | Description |
| ----------- | ---------------- | ---------------------------------------------------------- |
| channel_ids | array[snowflake] | The IDs of the channels to preload messages from (max 100) |
Search Guild Messages
Returns a list of messages without the `reactions` key that match a search query in the guild. Requires the `READ_MESSAGE_HISTORY` permission.
For applications, this endpoint is restricted according to whether the `MESSAGE_CONTENT` [Privileged Intent](/gateway/using-gateway#privileged-intents) is enabled for the application.
If the entity you are searching is not yet indexed, the endpoint will return a 202 accepted response. The response body will not contain any search results, and will look similar to an error response:
```json
{
"message": "Index not yet available. Try again later",
"code": 110000,
"documents_indexed": 0,
"retry_after": 2
}
```
You should retry the request after the timeframe specified in the `retry_after` field. If the `retry_after` field is `0`, you should retry the request after a short delay.
See [the unavailable resources section](/topics/rate-limits#unavailable-resources) for more information.
Due to speed optimizations, search may return slightly fewer results than the limit specified when messages have not been accessed for a long time.
Clients should not rely on the length of the `messages` array to paginate results.
Additionally, when messages are actively being created or deleted, the `total_results` field may not be accurate.
###### Query String Params
| Field | Type | Description |
| ---------------------- | ---------------- | ------------------------------------------------------------------------------------------------ |
| limit? | integer | Max number of messages to return (1-25, default 25) |
| offset? | integer | Number to offset the returned messages by (max 9975) |
| max_id? ^6^ | snowflake | Get messages before this message ID |
| min_id? ^6^ | snowflake | Get messages after this message ID |
| slop? | integer | Max number of words to skip between matching tokens in the search `content` (max 100, default 2) |
| content? | string | Filter messages by content (max 1024 characters) |
| contents? | array[string] | Filter messages by [tokenized content](#tokenized-content) (max 1024 characters, max 100) |
| channel_id? ^1^ | array[snowflake] | Filter messages by these channels (max 500) |
| author_type? | array[string] | Filter messages by [author type](#author-type) |
| author_id? | array[snowflake] | Filter messages by these authors (max 100) |
| mentions? | array[snowflake] | Filter messages that mention these users (max 100) |
| mentions_role_id? | array[snowflake] | Filter messages that mention these roles (max 100) |
| mention_everyone? | boolean | Filter messages that do or do not mention @everyone |
| replied_to_user_id? | array[snowflake] | Filter messages that reply to these users (max 100) |
| replied_to_message_id? | array[snowflake] | Filter messages that reply to these messages (max 100) |
| pinned? | boolean | Filter messages by whether they are or are not pinned |
| has? | array[string] | Filter messages by whether or not they [have specific things](#search-has-type) |
| embed_type? | array[string] | Filter messages by [embed type](#search-embed-type) |
| embed_provider? | array[string] | Filter messages by embed provider (case-sensitive, e.g. `Tenor`) (max 256 characters, max 100) |
| link_hostname? | array[string] | Filter messages by link hostname (e.g. `discordapp.com`) (max 256 characters, max 100) |
| attachment_filename? | array[string] | Filter messages by attachment filename (max 1024 characters, max 100) |
| attachment_extension? | array[string] | Filter messages by attachment extension (e.g. `txt`) (max 256 characters, max 100) |
| command_id? ^3^ ^4^ | snowflake | Filter messages by application command ID |
| command_name? ^3^ ^4^ | string | Filter messages by application command name (max 32 characters) |
| sort_by? ^2^ | string | The [sorting algorithm](#search-sort-mode) to use |
| sort_order? ^2^ | string | The direction to sort (`asc` or `desc`, default `desc`) |
| include_nsfw? ^5^ | boolean | Whether to include results from NSFW channels (default false) |
^1^ Not applicable when operating on a private channel.
^2^ Sort order is not respected when sorting by relevance.
^3^ Parameter is unstable and should not be relied on.
^4^ `command_id` and `command_name` must be provided together.
^5^ Users that do not have [`nsfw_allowed`](/resources/user#user-object) set to `true` will not receive results from NSFW channels, regardless of this parameter.
^6^ When sorting by `timestamp`, these parameters may be used for pagination instead of `offset`. This allows search to paginate through more than 10,000 results.
###### Tokenized Content
Search queries can be tokenized client-side to allow for more flexible matching. The tokenized terms must be prepended with a `slop` value, followed by a seperator (`|`).
An example search query might look like this: `?contents=0|"important phrase"&contents=2|other&contents=2|text`
###### Author Type
All types can be negated by prefixing them with `-`, which means results will not include messages that match the type.
| Value | Description |
| ------- | ------------------------------------- |
| user | Return messages sent by user accounts |
| bot | Return messages sent by bot accounts |
| webhook | Return messages sent by webhooks |
###### Search Has Type
All types can be negated by prefixing them with `-`, which means results will not include messages that match the type.
| Value | Description |
| -------- | --------------------------------------------- |
| image | Return messages that have an image |
| sound | Return messages that have a sound attachment |
| video | Return messages that have a video |
| file | Return messages that have an attachment |
| sticker | Return messages that have a sent sticker |
| embed | Return messages that have an embed |
| link | Return messages that have a link |
| poll | Return messages that have a poll |
| snapshot | Return messages that have a forwarded message |
###### Search Embed Type
These do not correspond 1:1 to actual [embed types](#embed-type) and encompass a wider range of actual types.
| Value | Description |
| ------- | ------------------------------------------ |
| image | Return messages that have an image embed |
| video | Return messages that have a video embed |
| gif ^1^ | Return messages that have a gifv embed |
| sound | Return messages that have a sound embed |
| article | Return messages that have an article embed |
^1^ Messages sent before February 24, 2026 may not be properly indexed under the `gif` embed type.
###### Search Sort Mode
| Value | Description |
| --------- | -------------------------------------------------------- |
| timestamp | Sort by the message creation time (default) |
| relevance | Sort by the relevance of the message to the search query |
###### Response Body
| Field | Type | Description |
| --------------------------- | ---------------------------------------------------------------------- | ----------------------------------------------------------------------------------------- |
| analytics_id | string | The analytics ID for the search query |
| doing_deep_historical_index | boolean | Whether the guild is undergoing a deep historical indexing operation |
| documents_indexed? | integer | The number of documents that have been indexed during the current index operation, if any |
| total_results | integer | The total number of results that match the query |
| messages ^1^ | array[array[[message](#message-object) object]] | A nested array of messages that match the query |
| channels? ^2^ | array[[channel](/resources/channel#channel-object) object] | The channels that contain the returned messages |
| threads? | array[[channel](/resources/channel#channel-object) object] | The threads that contain the returned messages |
| members? | array[[thread member](/resources/channel#thread-member-object) object] | A thread member object for each returned thread the current user has joined |
^1^ The nested array was used to provide surrounding context to search results. However, surrounding context is no longer returned.
^2^ Only applicable when operating on a private channel.
###### Example Response
```json
{
"analytics_id": "67ab1d6e97c631025fbba32d4eb82a16",
"doing_deep_historical_index": false,
"total_results": 1,
"messages": [
[
{
"id": "1076986676557131916",
"type": 0,
"content": "domainreaction fear",
"channel_id": "885895521909227581",
"author": {
"id": "545581357812678656",
"username": "alien",
"global_name": "Alien",
"avatar": "60387de43133809b083fb0f7458d2708",
"avatar_decoration_data": null,
"collectibles": null,
"discriminator": "0",
"public_flags": 4194432,
"primary_guild": null
},
"attachments": [],
"embeds": [],
"mentions": [],
"mention_roles": [],
"pinned": false,
"mention_everyone": false,
"tts": false,
"timestamp": "2023-02-19T22:00:33.136000+00:00",
"edited_timestamp": null,
"flags": 0,
"components": [],
"hit": true
}
]
]
}
```
Search Channel Messages
Returns a list of messages without the `reactions` key that match a search query in the private channel.
See [Search Guild Messages](#search-guild-messages) for more information.
Search Guild Messages by Tab
Returns a list of messages without the `reactions` key that match a set of parallelized search queries in the guild. Requires the `READ_MESSAGE_HISTORY` permission.
If the entity you are searching is not yet indexed, the endpoint will return a 202 accepted response. The response body will not contain any search results, and will look similar to an error response:
```json
{
"message": "Index not yet available. Try again later",
"code": 110000,
"documents_indexed": 0,
"retry_after": 2
}
```
You should retry the request after the timeframe specified in the `retry_after` field. If the `retry_after` field is `0`, you should retry the request after a short delay.
See [the unavailable resources section](/topics/rate-limits#unavailable-resources) for more information.
Due to speed optimizations, search may return slightly fewer results than the limit specified when messages have not been accessed for a long time.
Clients should not rely on the length of the `messages` array to paginate results.
Additionally, when messages are actively being created or deleted, the `total_results` field may not be accurate.
###### JSON Params
| Field | Type | Description |
| ----------------------- | ------------------------------------------------------- | ---------------------------------------------------------------------------------------------------- |
| tabs | map[string, [search tab](#search-tab-structure) object] | A map of [predefined tab names](#search-tab-type) to search queries |
| channel_ids? ^1^ | array[snowflake] | Filter messages by these channels (max 500) |
| include_nsfw? ^2^ | boolean | Whether to include results from NSFW channels (default false) |
| track_exact_total_hits? | boolean | Whether to return accurate total result count information at the cost of performance (default false) |
^1^ Only applicable when operating on a guild.
^2^ Users that do not have [`nsfw_allowed`](/resources/user#user-object) set to `true` will not receive results from NSFW channels, regardless of this parameter.
###### Search Tab Type
While the tab names themselves are enforced, what they are used for is not. Clients are free to use any combinations of filters even if they don't follow the spirit of the tab name.
| Value | Description |
| -------- | ------------ |
| messages | Messages tab |
| links | Links tab |
| media | Media tab |
| files | Files tab |
| pins | Pins tab |
###### Search Tab Structure
| Field | Type | Description |
| ---------------------- | ------------------------------------------------- | ------------------------------------------------------------------------------------------------ |
| limit? | integer | Max number of messages to return (1-25, default 25) |
| cursor? ^1^ | ?[search cursor](#search-cursor-structure) object | The cursor to use for pagination |
| offset? ^1^ | integer | Number to offset the returned messages by (max 9975) |
| max_id? | snowflake | Get messages before this message ID |
| min_id? | snowflake | Get messages after this message ID |
| slop? | integer | Max number of words to skip between matching tokens in the search `content` (max 100, default 2) |
| content? | string | Filter messages by content (max 1024 characters) |
| contents? | array[string] | Filter messages by [tokenized content](#tokenized-content) (max 1024 characters, max 100) |
| author_type? | array[string] | Filter messages by [author type](#author-type) |
| author_id? | array[snowflake] | Filter messages by these authors (max 100) |
| mentions? | array[snowflake] | Filter messages that mention these users (max 100) |
| mentions_role_id? | array[snowflake] | Filter messages that mention these roles (max 100) |
| mention_everyone? | boolean | Filter messages that do or do not mention @everyone |
| replied_to_user_id? | array[snowflake] | Filter messages that reply to these users (max 100) |
| replied_to_message_id? | array[snowflake] | Filter messages that reply to these messages (max 100) |
| pinned? | boolean | Filter messages by whether they are or are not pinned |
| has? | array[string] | Filter messages by whether or not they [have specific things](#search-has-type) |
| embed_type? | array[string] | Filter messages by [embed type](#search-embed-type) |
| embed_provider? | array[string] | Filter messages by embed provider (case-sensitive, e.g. `Tenor`) (max 256 characters, max 100) |
| link_hostname? | array[string] | Filter messages by link hostname (e.g. `discordapp.com`) (max 256 characters, max 100) |
| attachment_filename? | array[string] | Filter messages by attachment filename (max 1024 characters, max 100) |
| attachment_extension? | array[string] | Filter messages by attachment extension (e.g. `txt`) (max 256 characters, max 100) |
| command_id? ^3^ ^4^ | snowflake | Filter messages by application command ID |
| command_name? ^3^ ^4^ | string | Filter messages by application command name (max 32 characters) |
| sort_by? ^2^ | string | The [sorting algorithm](#search-sort-mode) to use |
| sort_order? ^2^ | string | The direction to sort (`asc` or `desc`, default `desc`) |
^1^ You may only paginate with either `offset` or `cursor`, not both. If `cursor` is provided, the [search cursor type](#search-cursor-type) should match the [sorting algorithm](#search-sort-mode) used in `sort_by`.
^2^ Sort order is not respected when sorting by relevance.
^3^ Parameter is unstable and should not be relied on.
^4^ `command_id` and `command_name` must be provided together.
###### Search Cursor Structure
| Field | Type | Description |
| ------------- | ------------------------------------------------------------ | ------------------------------------------------------------------- |
| type | string | The [type of the cursor](#search-cursor-type) |
| timestamp ^1^ | snowflake | The ID of the last message in this page of results |
| score? ^2^ | [search cursor score](#search-cursor-score-structure) object | The relevance metadata for the last message in this page of results |
^1^ Only used for `timestamp` cursors.
^2^ Only used for `score` cursors.
###### Search Cursor Score Structure
| Field | Type | Description |
| --------- | --------- | --------------------------------------------------------------- |
| timestamp | snowflake | The ID of the last message in this page of results |
| score? | float | The relevance score of the last message in this page of results |
###### Search Cursor Type
| Value | Description |
| --------- | ----------------------------- |
| timestamp | Paginate results by timestamp |
| score | Paginate results by relevance |
###### Response Body
| Field | Type | Description |
| --------------------------- | ---------------------------------------------------------------------- | ----------------------------------------------------------------------------------------- |
| analytics_id | string | The analytics ID for the search query |
| doing_deep_historical_index | boolean | Whether the guild is undergoing a deep historical indexing operation |
| documents_indexed? | integer | The number of documents that have been indexed during the current index operation, if any |
| tabs | map[string, [search tab results](#search-tab-results-structure) object | A map of [requested tab names](#search-tab-type) to search results |
###### Search Tab Results Structure
| Field | Type | Description |
| ----------------- | ---------------------------------------------------------------------- | --------------------------------------------------------------------------- |
| messages ^1^ | array[array[[message](#message-object) object]] | A nested array of messages that match the query |
| channels | array[[channel](/resources/channel#channel-object) object] | The channels that contain the returned messages |
| threads? | array[[channel](/resources/channel#channel-object) object] | The threads that contain the returned messages |
| members? | array[[thread member](/resources/channel#thread-member-object) object] | A thread member object for each returned thread the current user has joined |
| cursor ^2^ | [search cursor](#search-cursor-structure) object | The cursor for the next page of results |
| total_results ^3^ | integer | The total number of results that match the query |
| time_spent_ms | integer | Duration taken (in milliseconds) processing the search query |
^1^ The nested array was used to provide surrounding context to search results. However, surrounding context is no longer returned.
^2^ Will be an empty object if there is no more data to paginate.
^3^ Amount will be capped at 1001 if `track_exact_total_hits` is set to `false`.
Search Channel Messages by Tab
Returns a list of messages without the `reactions` key that match a set of parallelized search queries in the private channel.
See [Search Guild Messages by Tab](#search-guild-messages-by-tab) for more information.
Search User Messages by Tab
Returns a list of messages without the `reactions` key that match a set of parallelized search queries across all user private channels.
See [Search Guild Messages by Tab](#search-guild-messages-by-tab) for more information.
This endpoint will not return results authored by blocked users.
Get Message
Returns a specific [message](#message-object) object in the channel. Requires the `READ_MESSAGE_HISTORY` permission if operating on a guild channel.
This endpoint is not usable by user accounts.
Create Message
Discord may strip certain characters from message content, like invalid unicode characters or characters which cause unexpected message formatting. If you are passing user-generated strings into message content, consider sanitizing the data to prevent unexpected behavior and using `allowed_mentions` to prevent unexpected mentions.
Posts a message to a text-based channel. Returns a [message](#message-object) object on success. Fires a [Message Create](/gateway/gateway-events#message-create) Gateway event. See [message formatting](/reference#message-formatting) for more information on how to properly format messages.
To create a message as a reply to another message, you can include a [`message_reference`](#message-reference-object) with a `message_id`. The `channel_id` and `guild_id` in the `message_reference` are optional, but will be validated if provided.
Files must be attached using a `multipart/form-data` body (or pre-uploaded to Discord's GCP bucket) as described in [Uploading Files](/reference#uploading-files).
###### Limitations
- When operating on a guild channel, the current user must have the `SEND_MESSAGES` permission.
- When sending a message with `poll`, the current user must have the `SEND_POLLS` permission.
- When sending a message with `tts` (text-to-speech) set to `true`, the current user must have the `SEND_TTS_MESSAGES` permission.
- When creating a message as a reply to another message, the current user must have the `READ_MESSAGE_HISTORY` permission.
- The referenced message must exist and cannot be a system message.
- The maximum request size when sending a message is **200 MiB**.
- For the embed object, you can set every field except `type` (it will be `rich` regardless of if you try to set it), `provider`, `video`, and any `height`, `width`, or `proxy_url` values for images.
Note that when sending a message, you must provide a value for **at least one of** `content`, `embeds`, `components`, `sticker_ids`, `activity`, `files[n]`, `poll`, `shared_client_theme`, `with_checkpoint`, or a forwarded `message_reference`.
###### JSON/Form Params
| Field | Type | Description |
| -------------------- | ------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| content? | string | The message contents (up to 2000 characters) |
| tts? | boolean | Whether this is a TTS message |
| embeds? ^2^ | array[[embed](#embed-object) object] | Embedded `rich` content (max 6000 characters, max 10) |
| nonce? ^3^ | integer \| string | The message's nonce, used for message deduplication (will be present in the returned object and accompanying [Message Create](/gateway/gateway-events#message-create) event) |
| allowed_mentions? | [allowed mention](#allowed-mentions-object) object | Allowed mentions for the message |
| message_reference? | [message reference](#message-reference-structure) object | The message being replied to or forwarded |
| components? ^2^ | array[[message component](/resources/components#component-object) object] | The components to include with the message |
| sticker_ids? | array[snowflake] | IDs of up to 3 [stickers](/resources/sticker#sticker-object) to send in the message |
| activity? | [message activity](#message-activity-object) object | The rich presence activity to invite users to |
| application_id? | snowflake | The application ID of the activity to create a rich presence invite for (defaults to the primary activity if unspecified) |
| flags? | integer | The [message's flags](/resources/message#message-flags) (only `SUPPRESS_EMBEDS`, `SUPPRESS_NOTIFICATIONS`, and `VOICE_MESSAGE` can be set) |
| files[n]? ^1^ | file contents | Contents of the file being sent (max 10) |
| attachments? ^1^ | array[partial [attachment](#attachment-object) object] | The attachments to upload (max 10) |
| poll? | [poll create](#poll-create-structure) object | A poll! |
| confetti_potion? | [confetti potion](#confetti-potion-structure) object | A confetti potion to apply to the message |
| shared_client_theme? | [shared client theme](#shared-client-theme-object) object | A shared client theme |
| with_checkpoint? | boolean | Whether to send a [checkpoint card](/resources/components#checkpoint-card) component (default false) |
^1^ See [Uploading Files](/reference#uploading-files) for details. The attachments must be uploaded through the [Create Message Attachments](/topics/cloud-uploads#create-message-attachments) endpoint.
^2^ Cannot be used by user accounts.
^3^ Sending multiple messages in the same channel with the same nonce in a short period of time will result in only the first message being sent.
###### Example Request Body (application/json)
```json
{
"content": "Hello, World!",
"tts": false,
"embeds": [
{
"title": "Hello, Embed!",
"description": "This is an embedded message."
}
]
}
```
Examples for file uploads are available in [Uploading Files](/reference#uploading-files).
Create DM Message
Posts a message to a text-based channel. Returns a [message](#message-object) object on success. Fires a [Message Create](/gateway/gateway-events#message-create) Gateway event.
Functionally identical to the [Create Message](#create-message) endpoint, but is used for DM channels in an OAuth2 context and has some additional parameters. Check there for more information.
A message can be sent between two users in the following situations:
- Both users are online and have a presence corresponding to the OAuth2 application (i.e. in the game)
- Both users are friends with each other
- Both users share a mutual guild with DMs allowed and have previously DM'd each other on Discord
This endpoint is only usable with an OAuth2 access token with the `dm_channels.messages.write` or `activities.invites.write` scope.
If the `activities.invites.write` scope is used, only the `activity` and `application_id` fields may be provided.
###### Extra JSON Params
| Field | Type | Description |
| --------- | ------ | -------------------------------------------------------------------------------- |
| metadata? | object | Custom metadata for the message (max 25 keys, 1024 characters per key and value) |
Create Greet Message
Posts a greet message to a channel. This endpoint requires the channel is a DM channel or you reply to a system message. Returns a [message](#message-object) object on success. Fires a [Message Create](/gateway/gateway-events#message-create) Gateway event.
###### JSON Params
| Field | Type | Description |
| ------------------ | -------------------------------------------------------- | ---------------------------------------------------------------------------------- |
| sticker_ids | array[snowflake] | IDs of up to 1 [sticker](/resources/sticker#sticker-object) to send in the message |
| allowed_mentions? | [allowed mention](#allowed-mentions-object) object | Allowed mentions for the message |
| message_reference? | [message reference](#message-reference-structure) object | The message being replied to |
Scan Explicit Media
Scans for explicit media in a list of messages. Returns a 204 empty response on success. Fires multiple [Message Update](/gateway/gateway-events#message-update) Gateway events.
This endpoint should be used by users with explicit content filtering enabled to scan for explicit media on messages that have embeds or attachments with a missing or outdated `content_filter_version`. Invalid message IDs are ignored.
The latest explicit content filter version is provided in the [`explicit_content_scan_version` field of the Ready event](/gateway/gateway-events#ready).
###### JSON Params
| Field | Type | Description |
| ----------- | ---------------- | ------------------------------ |
| message_ids | array[snowflake] | The message IDs to scan (1-75) |
Bulk Scan Explicit Media
Scans for explicit media in a list of messages in multiple channels. Returns a 204 empty response on success. Fires multiple [Message Update](/gateway/gateway-events#message-update) Gateway events.
Similar to [Scan Explicit Media](#scan-explicit-media), but allows scanning messages in multiple channels at once. Invalid channel and message IDs are ignored.
###### JSON Params
| Field | Type | Description |
| -------- | --------------------------------------------------------------- | ---------------------------- |
| messages | array[[bulk scan message](#bulk-scan-message-structure) object] | The messages to scan (1-100) |
###### Bulk Scan Message Structure
| Field | Type | Description |
| ---------- | --------- | --------------------------------------- |
| channel_id | snowflake | The ID of the channel the message is in |
| message_id | snowflake | The ID of the message to scan |
Report Sent Explicit Content False Positive
Reports an explicit content false positive for a list of uploaded attachments. Returns a 204 empty response on success.
This endpoint should be used after the user attempts to send an message containing attachments but receives a 400 bad request with a [`20009` JSON error code](/topics/errors#json-error-codes).
The error structure for `20009` will contain an additional `attachments` key with [attachment](#attachment-object) objects for each attachment that was flagged as explicit content.
###### JSON Params
| Field | Type | Description |
| -------------- | ---------------- | -------------------------------------------------------------------------------- |
| channel_id | snowflake | The ID of the channel the message is in |
| message_id | snowflake | A locally-generated ID representing the message |
| attachment_ids | array[snowflake] | The IDs of the attachments that were flagged as explicit content (max 100) |
| filenames | array[string] | The filenames of the attachments that were flagged as explicit content (max 100) |
Report Explicit Content False Positive
Reports an explicit content false positive for a message. Returns a 204 empty response on success.
This endpoint should be used upon viewing a message that was flagged as explicit content but was determined to be a false positive.
##### JSON Params
| Field | Type | Description |
| -------------- | ---------------- | ---------------------------------------------------------------------------------------------------------------------------------------- |
| channel_id | snowflake | The ID of the channel the message is in |
| message_id | snowflake | The ID of the message that was flagged as explicit content |
| attachment_ids | array[snowflake] | The IDs of the attachments that were flagged as explicit content (max 100) |
| embed_ids | array[string] | Locally generated IDs representing the embeds that were flagged as explicit content, in the format `lodash.uniqueId("embed_")` (max 100) |
Crosspost Message
Crossposts a message in a News Channel to following channels. Requires the `SEND_MESSAGES` permission if the current user sent the message, or additionally the `MANAGE_MESSAGES` permission for all other messages. Returns a [message](#message-object) object on success. Fires a [Message Update](/gateway/gateway-events#message-update) (and possibly multiple [Message Create](/gateway/gateway-events#message-create)) Gateway event.
Hide Message from Guild Feed
Hides a message from the feed of the guild the channel belongs to. Returns a 204 empty response on success. Fires a [Message Update](/gateway/gateway-events#message-update) Gateway event.
Unhide Message from Guild Feed
Unhides a message from the feed of the guild the channel belongs to. Returns a 204 empty response on success. Fires a [Message Update](/gateway/gateway-events#message-update) Gateway event.
List Reactions
Get a list of users that reacted with this emoji. Returns an array of partial [user](/resources/user#user-object) objects.
The `emoji` must be [URL Encoded](https://en.wikipedia.org/wiki/Percent-encoding) or the request will fail. To use custom emoji, you must encode it in the format `name:id` with the emoji name and emoji ID.
###### Query String Params
| Field | Type | Description |
| ------ | --------- | --------------------------------------------------------------------------- |
| after? | snowflake | Get users after this user ID |
| limit? | integer | Max number of users to return (1-100, default 25) |
| type? | integer | The [type of reaction](#reaction-type) to get users for (default `REGULAR`) |
Create Reaction
Creates a reaction for the message. Requires the `READ_MESSAGE_HISTORY` permission if operating on a guild channel. Additionally, if nobody else has reacted to the message using this emoji, this endpoint requires the `ADD_REACTIONS` permission. Returns a 204 empty response on success. Fires a [Message Reaction Add](/gateway/gateway-events#message-reaction-add) Gateway event.
The `emoji` must be [URL Encoded](https://en.wikipedia.org/wiki/Percent-encoding) or the request will fail. To use custom emoji, you must encode it in the format `name:id` with the emoji name and emoji ID.
###### Query String Params
| Field | Type | Description |
| ----- | ------- | -------------------------------------------------------------------- |
| type? | integer | The [type of reaction](#reaction-type) to create (default `REGULAR`) |
Delete Own Reaction
Deletes a reaction the current user has made for the message. Returns a 204 empty response on success. Fires a [Message Reaction Remove](/gateway/gateway-events#message-reaction-remove) Gateway event.
The `emoji` must be [URL Encoded](https://en.wikipedia.org/wiki/Percent-encoding) or the request will fail. To use custom emoji, you must encode it in the format `name:id` with the emoji name and emoji ID.
Delete Reaction
Deletes another user's reaction. Requires the `MANAGE_MESSAGES` permission. Returns a 204 empty response on success. Fires a [Message Reaction Remove](/gateway/gateway-events#message-reaction-remove) Gateway event.
The `emoji` must be [URL Encoded](https://en.wikipedia.org/wiki/Percent-encoding) or the request will fail. To use custom emoji, you must encode it in the format `name:id` with the emoji name and emoji ID.
Delete Reaction Emoji
Deletes all the reactions for a given emoji on a message. Returns a 204 empty response on success. Requires the `MANAGE_MESSAGES` permission. Fires a [Message Reaction Remove Emoji](/gateway/gateway-events#message-reaction-remove-emoji) Gateway event.
The `emoji` must be [URL Encoded](https://en.wikipedia.org/wiki/Percent-encoding) or the request will fail. To use custom emoji, you must encode it in the format `name:id` with the emoji name and emoji ID.
Delete All Reactions
Deletes all reactions on a message. Returns a 204 empty response on success. Requires the `MANAGE_MESSAGES` permission. Fires a [Message Reaction Remove All](/gateway/gateway-events#message-reaction-remove-all) Gateway event.
Get Message Interaction Data
Returns information about the interaction that created the given message.
###### Response Body
| Field | Type | Description |
| ------------------- | --------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------- |
| id | snowflake | The ID of the interaction |
| type | integer | The [type of interaction](/interactions/receiving-and-responding#interaction-type) |
| name | string | The name of the [application command](/interactions/application-commands#application-command-object) executed (including subcommands and subcommand groups) |
| application_command | [application command](/interactions/application-commands#application-command-object) object | The [application command](/interactions/application-commands#application-command-object) executed |
| options? | array[[application command data option](/interactions/receiving-and-responding#application-command-data-option-structure) object] | The options provided to the command, if any |
Edit Message
Edits a previously sent message. All fields can be edited by the original message author. Other users can only edit `flags` and only if they have the `MANAGE_MESSAGES` permission in the corresponding channel. When specifying flags, ensure to include all previously set flags/bits in addition to ones that you are modifying.
When the `content` field is edited, the `mentions` array in the message object will be reconstructed from scratch based on the new content. The `allowed_mentions` field of the edit request controls how this happens. If there is no explicit `allowed_mentions` in the edit request, the content will be parsed with _default_ allowances, that is, without regard to whether or not an `allowed_mentions` was present in the request that originally created the message.
Returns a [message](#message-object) object. Fires a [Message Update](#message-object) Gateway event.
Refer to [Uploading Files](/reference#uploading-files) for details on attachments and `multipart/form-data` requests.
Any provided files will be **appended** to the message. To remove or replace files you will have to supply the `attachments` field which specifies the files to retain on the message after edit.
Starting with API v10, the `attachments` array must contain all attachments that should be present after edit, including **retained and new** attachments provided in the request body.
Messages older than 1 hour may only be edited 3 times per 6-second window per channel.
###### JSON/Form Params
| Field | Type | Description |
| ----------------- | -------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------- |
| content? | ?string | The message contents (up to 2000 characters) |
| embeds? ^2^ | ?array[[embed](#embed-object) object] | Embedded `rich` content (max 6000 characters) |
| allowed_mentions? | ?[allowed mention](#allowed-mentions-object) object | Allowed mentions for the message |
| components? ^2^ | ?array[[message component](/resources/components#component-object) object] | The components to include with the message |
| flags? | ?integer | The [message's flags](/resources/message#message-flags) (only `SUPPRESS_EMBEDS` can be set) |
| files[n] ^1^ | ?file contents | Contents of the file being sent |
| attachments ^1^ | ?array[partial [attachment](#attachment-object) object] | Partial attachment objects with `filename` and `description`, including attached files to keep |
^1^ See [Uploading Files](/reference#uploading-files) for details. The attachments must be uploaded through the [Create Message Attachments](/topics/cloud-uploads#create-message-attachments) endpoint.
^2^ Cannot be used by user accounts.
Edit DM Message
Edits a previously sent message. Messages can be edited by the original message author. Returns a [message](#message-object) object. Fires a [Message Update](#message-object) Gateway event.
This endpoint is only usable with an OAuth2 access token with the `dm_channels.messages.write` or `activities.invites.write` scope.
###### JSON/Form Params
| Field | Type | Description |
| -------- | ------- | -------------------------------------------- |
| content? | ?string | The message contents (up to 2000 characters) |
Delete Message
Deletes a message. Requires the `MANAGE_MESSAGES` permission if operating on a guild channel and trying to delete a message that was not sent by the current user. Returns a 204 empty response on success. Fires a [Message Delete](/gateway/gateway-events#message-delete) Gateway event.
Delete DM Message
Deletes a message. Messages can be deleted by the original message author. Returns a 204 empty response on success. Fires a [Message Delete](/gateway/gateway-events#message-delete) Gateway event.
This endpoint is only usable with an OAuth2 access token with the `dm_channels.messages.write` scope.
Bulk Delete Messages
Deletes multiple messages from a guild channel in a single request. Requires the `MANAGE_MESSAGES` permission. Returns a 204 empty response on success. Fires a [Message Delete Bulk](/gateway/gateway-events#message-delete-bulk) Gateway event.
This endpoint will not delete messages older than 2 weeks, and will fail if any message provided is older than that or if any duplicate message IDs are provided.
This endpoint is not usable by user accounts.
###### JSON Params
| Field | Type | Description |
| -------- | ---------------- | --------------------------------- |
| messages | array[snowflake] | The message IDs to delete (2-100) |
List Message Pins
Returns all message pins in the channel. Requires the `VIEW_CHANNEL` permission.
If the current user does not have `READ_MESSAGE_HISTORY` permission, an empty `items` array will be returned.
###### Query String Params
| Field | Type | Description |
| ------- | ----------------- | ----------------------------------------------- |
| before? | ISO8601 timestamp | Get messages pinned before this timestamp |
| limit? | integer | Max number of pins to return (1-50, default 50) |
###### Response Body
| Field | Type | Description |
| -------- | ------------------------------------------------ | ------------------------------------------------------------------------------------------------- |
| items | array[[message pin](#message-pin-object) object] | The message pins in the channel |
| has_more | boolean | Whether there are potentially additional message pins that could be returned on a subsequent call |
List Pinned Messages
Returns up to 50 pinned messages in the channel as an array of [message](#message-object) objects without the `reactions` key.
This endpoint is deprecated. It is replaced by [List Message Pins](#list-message-pins).
Pin Message
Pins a message in a channel. Requires the `MANAGE_MESSAGES` permission if operating on a guild channel. Returns a 204 empty response on success. Fires a [Channel Pins Update](/gateway/gateway-events#channel-pins-update) Gateway event.
Unpin Message
Unpins a message in a channel. Requires the `MANAGE_MESSAGES` permission if operating on a guild channel. Returns a 204 empty response on success. Fires a [Channel Pins Update](/gateway/gateway-events#channel-pins-update) Gateway event.
Get Channel Media Preview
Returns information on the media of a post (thread) in a media channel. The media channel must be a paywalled role subscription benefit. If the user is not in the guild, the guild must be discoverable.
###### Response Body
| Field | Type | Description |
| ----- | ------------------------------------------------ | ------------------------------------------------------ |
| media | [media preview](#media-preview-structure) object | The preview of the media in the thread's first message |
###### Media Preview Structure
| Field | Type | Description |
| ------------------------ | --------------------------------------- | ----------------------------------------------------------------------- |
| guild_id | snowflake | The ID of the guild the media is in |
| guild_name | string | The name of the guild the media is in |
| guild_icon | string | The [icon hash](/reference#cdn-formatting) of the guild the media is in |
| channel_id | snowflake | The ID of the thread that represents the media |
| parent_channel_id | snowflake | The ID of the media channel the thread is in |
| message_id | snowflake | The ID of the thread's first message (same as the thread ID) |
| author_id | snowflake | The ID of the author of the thread's first message |
| title | string | The name of the thread |
| description | string | The first 64 characters of the first message's content |
| has_media_attachment ^1^ | boolean | Whether the first message has a media attachment |
| thumbnail? | [attachment](#attachment-object) object | The thumbnail of the thread's first message, if any |
^1^ If a media attachment is present, a fake thumbnail will be rendered in the preview as a CTA to subscribe to the role that unlocks the media channel.
###### Example Response
```json
{
"media": {
"guild_id": "1046920999469330512",
"channel_id": "1120793989809967114",
"parent_channel_id": "1120793939562217483",
"message_id": "1120793989809967114",
"title": "feet picers",
"description": "https://tenor.com/view/naomi-bunny-melon-gif-22514980",
"guild_name": "Hood Network",
"guild_icon": "a_78187748cb59baec2bf6a1f8766ff9fc",
"author_id": "728342296696979526",
"thumbnail": {
"url": "https://media.tenor.com/ttfzDdgGOqgAAAAM/naomi-bunny.png",
"proxy_url": "https://images-ext-2.discordapp.net/external/RGh8LSJbaADcUFgzFsvpODM6E2nz3xKVg_Mrg9UE58k/https/media.tenor.com/ttfzDdgGOqgAAAAe/naomi-bunny.png",
"width": 388,
"height": 640
},
"has_media_attachment": true
}
}
```
Unfurl Embed
Returns debug information about an embed.
###### JSON Params
| Field | Type | Description |
| ----- | ------ | ----------------- |
| url | string | The URL to unfurl |
###### Response Body
| Field | Type | Description |
| -------------- | -------------------------------------------------- | ------------------------------------------------------------- |
| response? | [embed response](#embed-response-structure) object | The response from the website |
| error? | string | The error that occurred while parsing the website |
| context_errors | array[string] | The contextual errors that occurred while parsing the website |
| embeds? | array[[embed](#embed-object) object] | The found embeds for the URL |
###### Embed Response Structure
| Field | Type | Description |
| ------- | ------------------- | ------------------------------------------------------ |
| headers | map[string, string] | The relevant headers returned by the website |
| body | string | The body of the website, if used to generate the embed |
Unfurl Embeds
Returns embed data from a list of URLs.
###### JSON Params
| Field | Type | Description |
| ----- | ------------- | -------------------------- |
| urls | array[string] | The URLs to unfurl (max 4) |
###### Response Body
| Field | Type | Description |
| ------ | ------------------------------------ | ----------------------------- |
| embeds | array[[embed](#embed-object) object] | The found embeds for the URLs |
List Poll Answer Voters
Get a list of users that voted for this specific answer.
###### Query String Params
| Field | Type | Description |
| ------ | --------- | ------------------------------------------------- |
| after? | snowflake | Get users after this user ID |
| limit? | integer | Max number of users to return (1-100, default 25) |
###### Response Body
| Field | Type | Description |
| ----- | --------------------------------------------------------- | ------------------------------- |
| users | array[partial [user](/resources/user#user-object) object] | Users who voted for this answer |
End Poll
Immediately ends the poll. You cannot end polls from other users.
Returns a [message](#message-object) object. Fires a [Message Update](/gateway/gateway-events#message-update) Gateway event.
Create Poll Vote
Submits a poll vote for the current user. Returns a 204 empty response on success. May fire multiple [Message Poll Vote Add](/gateway/gateway-events#message-poll-vote-add) and [Message Poll Vote Remove](/gateway/gateway-events#message-poll-vote-remove) Gateway events.
###### JSON Params
| Field | Type | Description |
| ---------- | -------------- | -------------------------------------- |
| answer_ids | array[integer] | Selected answers, empty to clear votes |
List Conversation Summaries
Get a list of up to 50 latest conversation summaries for a text channel in reverse chronological order. Requires the `READ_MESSAGE_HISTORY` permission.
###### Response Body
| Field | Type | Description |
| --------- | ------------------------------------------------------------------ | --------------------------------------------------- |
| summaries | array[[conversation summary](#conversation-summary-object) object] | The conversation summaries for the channel (max 50) |
Delete Conversation Summary
Deletes a conversation summary. Requires the `MANAGE_MESSAGES` permission. Returns a 204 empty response on success. Fires a [Conversation Summary Update](/gateway/gateway-events#conversation-summary-update) Gateway event.
List User Message Summaries
Returns a list of [user message summary](#user-message-summary-structure) objects for each DM channel.
###### User Message Summary Structure
| Field | Type | Description |
| --------------- | --------- | ------------------------------------------------------------------------------------- |
| user_id | snowflake | The ID of the recipient |
| last_message_id | snowflake | The ID of the last message sent in DM channel (may not point to an existing resource) |
Update User Message Moderation Metadata
Updates a message's moderation metadata in the DM channel. Accepts a moderation metadata mapping, up to 5 keys, max 2000 characters per value. Returns a 204 empty response. Fires a [Message Update](/gateway/gateway-events#message-update) Gateway event.
This endpoint is not usable by user accounts.
---
# Voice
Link: https://docs.discord.food/resources/voice
Voice resources are used to interact with voice in Discord. For more information on connecting to voice, see the [Voice Connections topic](/topics/voice-connections).
### Voice State Object
Used to represent a user's voice connection status.
###### Voice State Structure
| Field | Type | Description |
| -------------------------- | ----------------------------------------------------------- | ----------------------------------------------------------------------- |
| guild_id? ^1^ | ?snowflake | The guild ID this voice state is for |
| channel_id | ?snowflake | The channel ID this user is connected to |
| lobby_id? | snowflake | The ID of the lobby this user is connected to |
| user_id | snowflake | The user ID this voice state is for |
| member? ^1^ | [guild member](/resources/guild#guild-member-object) object | The guild member this voice state is for |
| session_id | string | The session ID this voice state is from |
| connected_at? | integer | Unix time (in seconds) of when the user connected to voice |
| deaf | boolean | Whether this user is deafened by the guild, if any |
| mute | boolean | Whether this user is muted by the guild, if any |
| self_deaf | boolean | Whether this user is locally deafened |
| self_mute | boolean | Whether this user is locally muted |
| self_stream? | boolean | Whether this user is streaming using "Go Live" |
| self_video | boolean | Whether this user's camera is enabled |
| suppress | boolean | Whether this user's permission to speak is denied |
| request_to_speak_timestamp | ?ISO8601 timestamp | When which the user requested to speak |
| discoverable? | boolean | Whether to show this voice state in the user's presence (default false) |
| user_volume? ^2^ | float | Volume level of the user (0-100) |
^1^ Omitted in the [Gateway guild](/gateway/gateway-events#gateway-guild-object) object.
^2^ Only available in [OAuth2 contexts](/gateway/using-gateway#oauth2-and-the-gateway). For regular connections, user volumes are available in [audio settings](/resources/user-settings-proto#audio-settings-structure).
###### Example Voice State
```json
{
"channel_id": "157733188964188161",
"user_id": "80351110224678912",
"session_id": "90326bd25d71d39b9ef95b299e3872ff",
"connected_at": 1617216331,
"deaf": false,
"mute": false,
"self_deaf": false,
"self_mute": true,
"suppress": false,
"request_to_speak_timestamp": "2021-03-31T18:45:31.297561+00:00"
}
```
### Voice Region Object
A special voice region ID of `deprecated` is used as the default in the deprecated [guild `region`](/resources/guild#guild-object) field.
###### Voice Region Structure
| Field | Type | Description |
| ---------- | ------- | -------------------------------------------------------------------- |
| id | string | The unique ID for the region |
| name | string | The name of the region |
| optimal | boolean | Whether this is the closest to the current user's client |
| deprecated | boolean | Whether this is a deprecated voice region (avoid switching to these) |
| custom | boolean | Whether this is a custom voice region (used for events, etc.) |
## Endpoints
List Voice Regions
Returns an array of [voice region](#voice-region-object) objects that can be used when setting a [voice channel's `rtc_region`](/resources/channel#channel-object).
List Guild Voice Regions
Returns a list of [voice region](#voice-region-object) objects that can be used when setting a [voice channel's `rtc_region`](/resources/channel#channel-object). Unlike the similar [List Voice Regions](#list-voice-regions) route, this returns VIP servers when the guild is VIP-enabled.
Upload Voice Public Key
Uploads a persistent public key used for voice encryption. Returns a 204 empty response on success.
This key is used for persistent keypair signatures in the DAVE protocol. For further details, see the [whitepaper](https://daveprotocol.com/#persistent-signature-keypairs).
Generating a keypair and signature can be done with the following Python pseudocode:
```python
import base64
import requests
from cryptography.hazmat.primitives.asymmetric import ec
from cryptography.hazmat.primitives import hashes
from cryptography.hazmat.primitives import serialization
API_ENDPOINT = 'https://discord.com/api/v9'
private_key = ec.generate_private_key(ec.SECP256R1())
public_key = private_key.public_key().public_bytes(serialization.Encoding.X962, serialization.PublicFormat.CompressedPoint)
# https://datatracker.ietf.org/doc/html/rfc9000#name-variable-length-integer-enc
def encode_quic_varint(data: bytes) -> bytes:
length = len(data)
if length < 2**6:
return bytes([length]) + data
elif length < 2**14:
return bytes([(1 << 6) | (length >> 8), length & 0xFF]) + data
elif length < 2**30:
return bytes([(2 << 6) | (length >> 24), (length >> 16) & 0xFF, (length >> 8) & 0xFF, length & 0xFF]) + data
else:
return bytes([(3 << 6) | (length >> 56), (length >> 48) & 0xFF, (length >> 40) & 0xFF, (length >> 32) & 0xFF, (length >> 24) & 0xFF, (length >> 16) & 0xFF, (length >> 8) & 0xFF, length & 0xFF]) + data
# https://datatracker.ietf.org/doc/html/rfc9420/#name-signing
def sign_with_label(private_key: ec.EllipticCurvePrivateKey, label: str, content: bytes) -> bytes:
label_bytes = b'MLS 1.0 ' + label.encode('ascii')
sign_content = encode_quic_varint(label_bytes) + encode_quic_varint(content)
signature = private_key.sign(sign_content, ec.ECDSA(hashes.SHA256()))
return signature
# The session ID is the static_client_session_id value from the READY payload
session_id = '00000000-0000-0000-0000-000000000000'.encode('ascii')
signature = sign_with_label(private_key, "DiscordSelfSignature", session_id + b':' + public_key)
data = {
'key_version': 1,
'public_key': 'data:application/octet-stream;base64,' + base64.b64encode(public_key).decode('utf-8'),
'signature': 'data:application/octet-stream;base64,' + base64.b64encode(signature).decode('utf-8'),
}
headers = {
'authorization': 'token',
# Rest of headers here
}
r = requests.put('%s/voice/public-keys' % API_ENDPOINT, json=data, headers=headers)
r.raise_for_status()
```
###### JSON Params
| Field | Type | Description |
| ----------- | ------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------- |
| key_version | integer | The version of the persistent key protocol (currently 1) |
| public_key | [cdn data](/reference#cdn-data) | The X9.62 P256 public key data |
| signature | [cdn data](/reference#cdn-data) | An MLS style self-signature of the public key data with application label `DiscordSelfSignature` and content `static_client_session_id:public_key` |
Verify Voice Public Key
Verifies a user's persistent public key for voice encryption against their uploaded ones.
This key is used by another user to encrypt voice data. For further details, see the [whitepaper](https://daveprotocol.com/#persistent-verification).
###### JSON Params
| Field | Type | Description |
| ----------- | ------------------------------- | -------------------------------------------------------- |
| key_version | integer | The version of the persistent key protocol (currently 1) |
| public_key | [cdn data](/reference#cdn-data) | The X9.62 P256 public key data |
###### Response Body
| Field | Type | Description |
| -------- | ------- | -------------------------------------------------------------------------------- |
| is_match | boolean | Whether the public key matches one of the user's uploaded persistent public keys |
Get Current User Voice State
Returns the current user's [voice state](#voice-state-object) object in the guild.
This endpoint is not usable by user accounts.
Get User Voice State
Returns the specified user's [voice state](#voice-state-object) object in the guild.
This endpoint is not usable by user accounts.
Modify Current User Voice State
Updates the current user's voice state in the given guild ID. Returns a 204 empty response on success. Fires a [Voice State Update](/gateway/gateway-events#voice-state-update) Gateway event.
There are currently several caveats for this endpoint:
- `channel_id` must point to a stage channel
- Current user must already have joined `channel_id`
- You must have the `MUTE_MEMBERS` permission to unsuppress yourself; you can always suppress yourself
- You must have the `REQUEST_TO_SPEAK` permission to request to speak; you can always clear your own request to speak
- You can only set `request_to_speak_timestamp` to the present or a future time
###### JSON Params
| Field | Type | Description |
| --------------------------- | ------------------ | ---------------------------------------------------------------------------------- |
| channel_id? | snowflake | The ID of the channel the user is currently in |
| suppress? | boolean | Whether the user is suppressed in the channel |
| request_to_speak_timestamp? | ?ISO8601 timestamp | When the user requested to speak |
| silent? | boolean | Whether to acknowledge the stage speaker request without notifying (default false) |
Modify User Voice State
Updates another user's voice state in the given guild ID. Returns a 204 empty response on success. Fires a [Voice State Update](/gateway/gateway-events#voice-state-update) Gateway event.
There are currently several caveats for this endpoint:
- `channel_id` must point to a stage channel
- Target user must already have joined `channel_id`
- You must have the `MUTE_MEMBERS` permission
- When unsuppressed, user accounts will have their `request_to_speak_timestamp` set to the current time; bot users will not
- When suppressed, the user will have their `request_to_speak_timestamp` removed
###### JSON Params
| Field | Type | Description |
| ---------- | --------- | ---------------------------------------------- |
| channel_id | snowflake | The ID of the channel the user is currently in |
| suppress? | boolean | Whether the user is suppressed in the channel |
Send Voice Channel Effect
Sends a voice channel effect to a voice channel. Returns a 204 empty response on success. Fires a [Voice Channel Effect Send](/gateway/gateway-events#voice-channel-effect-send) Gateway event.
Sending a voice channel effect requires the current user to be connected to the voice channel. The user cannot be server muted, deafened, or suppressed.
###### JSON Params
| Field | Type | Description |
| ----------------- | ---------- | ---------------------------------------------------------------------------------------------------- |
| animation_type? | ?integer | The [type of emoji animation](#voice-channel-effect-animation-type), if applicable (default `BASIC`) |
| animation_id? ^1^ | ?integer | The ID of the emoji animation (default 0) |
| emoji_id? | ?snowflake | The ID of the custom emoji to send |
| emoji_name? | ?string | The emoji name or unicode character of the emoji to send |
^1^ The animation ID is a zero-based index in the animation set selected by `animation_type`. `BASIC` only supports ID `0`. `PREMIUM` supports IDs `0` through `20`.
###### Voice Channel Effect Animation Type
| Value | Name | Description |
| ----- | ------- | -------------------------------------------------------- |
| 0 | PREMIUM | A fun animation, requires a premium (Nitro) subscription |
| 1 | BASIC | The standard animation |
Send Custom Call Sound
Sends the user's configured custom call sound effect to a voice channel. Returns a 204 empty response on success. Fires a [Voice Channel Effect Send](/gateway/gateway-events#voice-channel-effect-send) Gateway event.
Sending a custom call sound requires the current user to be connected to the voice channel. The user cannot be server muted, deafened, or suppressed.
###### JSON Params
| Field | Type | Description |
| ---------------- | ------- | ------------------------------------------------------------------------------- |
| animation_type | integer | The [type of animation](#voice-channel-effect-animation-type) (default `BASIC`) |
| animation_id ^1^ | integer | The ID of the animation (default 0) |
^1^ The animation ID is a zero-based index in the animation set selected by `animation_type`. `BASIC` only supports ID `0`. For `PREMIUM`, the official client randomly selects IDs `10` through `15`, but any IDs from `0` through `20` are supported.
Modify Stream
Modifies the stream. User must be the owner of the stream. Returns a 204 empty response on success. Fires a [Stream Update](/gateway/gateway-events#stream-update) Gateway event.
###### JSON Params
| Field | Type | Description |
| ------- | ------ | -------------------------------------------------------------------------- |
| region? | string | The [voice region](/resources/voice#voice-region-object) ID for the stream |
Get Stream Preview
Returns a URL to a stream preview for the given [stream key](/gateway/gateway-events#stream-key). Requires the `CONNECT` permission in the stream's channel.
###### Response Body
| Field | Type | Description |
| ----- | ------ | --------------------------------- |
| url | string | The CDN URL to the stream preview |
Upload Stream Preview
Uploads a stream preview for the given [stream key](/gateway/gateway-events#stream-key). User must be the owner of the stream. Returns a 204 empty response on success.
###### JSON Params
| Field | Type | Description |
| --------- | --------------------------------- | ------------------------ |
| thumbnail | [image data](/reference#cdn-data) | The stream preview image |
Upload Video Stream Preview
Uploads a stream preview video for the given [stream key](/gateway/gateway-events#stream-key). User must be the owner of the stream. Returns a 204 empty response on success.
###### Form Params
| Field | Type | Description |
| ----- | ------------- | ---------------------------------- |
| file | file contents | The stream preview video to upload |
Broadcast Stream Notification
Broadcasts a stream notification to all friends of the current user that are in the same guild as the stream and have stream notifications enabled. User must be the owner of the stream and must be streaming in a guild. Returns a 204 empty response on success.
The guild must have more than 1 and no more than 50 members to be eligible for stream notifications.
---
# Applications
Link: https://docs.discord.food/resources/application
Applications are Discord entities that represent games, services, and other integrations within Discord.
Applications can be used for a variety of purposes, including OAuth2 authentication, rich presence, bots, and much more.
Any external service that integrates with Discord in some way, including many first-party features like Stickers and Nitro, have an associated application.
### Application Object
###### Application Structure
| Field | Type | Description |
| -------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| id | snowflake | The ID of the application |
| name | string | The name of the application |
| description | string | The description of the application |
| icon | ?string | The application's [icon hash](/reference#cdn-formatting) |
| cover_image? | string | The application's default rich presence invite [cover image hash](/reference#cdn-formatting) |
| splash? | string | The application's [splash hash](/reference#cdn-formatting) |
| type | ?integer | The [type of the application](#application-type), if any |
| flags ^7^ | integer | The [application's flags](#application-flags) (including private) |
| flags_new ^7^ | string | The [application's flags](#application-flags) (including private) serialized as a stringified integer |
| primary_sku_id? ^1^ | snowflake | The ID of the application's primary SKU (game, application subscription, etc.) |
| verify_key | string | The hex encoded client public key for verification in interactions and the GameSDK's `GetTicket` |
| guild_id? | snowflake | The ID of the guild linked to the application |
| eula_id? | snowflake | The ID of the [EULA](/resources/store#eula-object) required to play the application's game |
| slug? ^1^ | string | The URL slug that links to the primary store page of the application |
| aliases? | array[string] | Other names the application's game is associated with |
| executables? | array[[application executable](/resources/game#application-executable-object) object] | The unique executables of the application's game |
| third_party_skus? | array[[application SKU](/resources/game#application-sku-object) object] | The third party SKUs of the application's game |
| hook | boolean | Whether the Discord client is allowed to hook into the application's game directly |
| overlay? | boolean | Whether the application's game supports the [Discord overlay](https://support.discord.com/hc/en-us/articles/217659737-Game-Overlay-101) (default false) |
| overlay_methods? | integer | The [methods of overlaying](#overlay-method-flags) that the application's game supports |
| overlay_warn? | boolean | Whether the [Discord overlay](https://support.discord.com/hc/en-us/articles/217659737-Game-Overlay-101) is known to be problematic with this application's game (default false) |
| overlay_compatibility_hook? | boolean | Whether to use the compatibility hook for the overlay (default false) |
| bot? | partial [user](/resources/user#user-object) object | The bot attached to this application |
| owner | partial [user](/resources/user#user-object) object | The owner of the application |
| team? ^2^ | ?[team](/resources/team#team-object) object | The team that owns the application |
| developers? | array[[company](/resources/team#company-object) object] | The companies that developed the application |
| publishers? | array[[company](/resources/team#company-object) object] | The companies that published the application |
| rpc_origins? | array[string] | The whitelisted RPC origin URLs for the application, if RPC is enabled |
| redirect_uris | array[string] | The whitelisted URLs for redirecting to during [OAuth2 authorization](/topics/oauth2) (max 10) |
| deeplink_uri? | string | The URL used for deep linking during [OAuth2 authorization](/topics/oauth2) on mobile devices |
| integration_public | boolean | Whether only the application owner can add the integration |
| integration_require_code_grant | boolean | Whether the integration will only be added upon completion of a full OAuth2 token exchange |
| bot_public? ^3^ **(deprecated)** | boolean | Whether only the application owner can add the bot |
| bot_require_code_grant? ^3^ **(deprecated)** | boolean | Whether the application's bot will only be added upon completion of a full OAuth2 token exchange |
| bot_disabled? | boolean | Whether the application's bot is disabled by Discord (default false) |
| bot_quarantined? | boolean | Whether the application's bot is [quarantined](https://support.discord.com/hc/en-us/articles/6461420677527-Limited-Access-FAQ) by Discord; quarantined bots cannot join more guilds or start new direct messages (default false) |
| bot_approximate_guild_count? | integer | Approximate count of guilds the application's bot is in |
| approximate_guild_count? | integer | Approximate count of guilds that have authorized the application with the `applications.commands` scope |
| approximate_user_install_count | integer | Approximate count of users that have authorized the application with the `applications.commands` scope |
| approximate_user_authorization_count | integer | Approximate count of users that have OAuth2 authorizations for the application |
| internal_guild_restriction | integer | What guilds the [application can be authorized in](#internal-guild-restriction) |
| terms_of_service_url? | string | The URL to the application's terms of service |
| privacy_policy_url? | string | The URL to the application's privacy policy |
| role_connections_verification_url | ?string | The role connection verification entry point of the integration; when configured, this will render the application as a verification method in guild role verification configuration |
| interactions_endpoint_url | string | The URL of the application's [interactions endpoint](/interactions/receiving-and-responding#receiving-an-interaction) |
| interactions_version | integer | The [version of the application's interactions endpoint implementation](#application-interactions-version) |
| interactions_event_types ^4^ | array[string] | The enabled [event webhook types](#event-webhooks-type) to send to the interaction endpoint |
| event_webhooks_status? | integer | Whether [event webhooks are enabled](#event-webhooks-status) |
| event_webhooks_url? | string | The URL of the application's event webhooks endpoint |
| event_webhooks_types? | array[string] | The enabled [event webhook types](#event-webhooks-type) to send to the event webhooks endpoint |
| explicit_content_filter | integer | [Whether uploaded media content](#explicit-content-filter-level) used in application commands is scanned and deleted for explicit content |
| tags? | array[string] | Tags describing the content and functionality of the application (max 20 characters, max 5) |
| install_params? | [application install params](#application-install-params-object) object | The default in-app authorization link for the integration |
| custom_install_url? | string | The default custom authorization link for the integration |
| integration_types_config? | map[integer, ?[application integration type configuration](#application-integration-type-configuration-structure) object] | The configuration for each [integration type](#application-integration-type) supported by the application |
| connection_entrypoint_url? | string | The URL which users will be directed to when connecting their account in the application to their Discord account |
| is_verified | boolean | Whether the application is verified |
| verification_state | integer | The current [verification state](#application-verification-state) of the application |
| store_application_state | integer | The current [store approval state](#store-application-state) of the commerce application |
| rpc_application_state | integer | The current [RPC approval state](#rpc-application-state) of the application |
| creator_monetization_state ^5^ | integer | The current guild [creator monetization state](#creator-monetization-state) of the application |
| is_discoverable | boolean | Whether the application is discoverable in the application directory |
| discoverability_state | integer | The current [application directory discoverability state](#application-discoverability-state) of the application |
| discovery_eligibility_flags | integer | The current [application directory eligibility flags](#application-discovery-eligibility-flags) for the application |
| is_monetized | boolean | Whether the application has monetization enabled |
| storefront_available | boolean | Whether the application has public subscriptions or products available for purchase |
| monetization_state | integer | The current [application monetization state](#application-monetization-state) of the application |
| monetization_eligibility_flags? ^2^ | integer | The current [application monetization eligibility flags](#application-monetization-eligibility-flags) for the application |
| max_participants? ^6^ | integer | The maximum possible participants in the application's embedded activity (-1 for no limit) |
| embedded_activity_config? ^6^ | [embedded activity config](#embedded-activity-config-object) object | The configuration for the application's embedded activity |
| approved_consoles | array[integer] | The [approved console types](#approvable-console-type) for social SDK builds |
| pricing_localization_strategy | string | The [pricing localization strategy](#pricing-localization-strategy) used for the application's store presence |
^1^ The `primary_sku_id` and `slug` fields can be combined to form a URL to the application's primary store page like so: `https://discord.com/store/skus/{primary_sku_id}/{slug}`.
^2^ Only present when fetched from the [Get Current Application](#get-current-application), [Get Application](#get-application), or [Transfer Application](#transfer-application) endpoints.
^3^ In some cases, these fields may still be provided instead of `integration_public` and `integration_require_code_grant`. These fields will not be present if the application does not have a bot.
^4^ The sending of Gateway events over the interactions endpoint requires [interactions version 2](#application-interactions-version).
^5^ Only applicable for applications of type [`CREATOR_MONETIZATION`](#application-type).
^6^ Only applicable for applications with the [`EMBEDDED` flag](#application-flags).
^7^ The `flags` field is serialized as a number; however, this number will not grow beyond 31 bits. New flag bits beyond bit 30 will only appear in `flags_new`, a string-serialized integer
containing the full set of flag bits.
###### Partial Application Structure
Partial applications may have any combination of fields, depending on the context in which they are provided. Certain data may be included or omitted depending on what data is needed for the given operation. Fields [marked as required](/reference#nullable-and-optional-resource-fields) will always be present.
Further complicating things, some optional fields may be omitted if their value is `null`, even if the specific partial does include this data.
| Field | Type | Description |
| -------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| id | snowflake | The ID of the application |
| name | string | The name of the application |
| description | string | The description of the application |
| icon | ?string | The application's [icon hash](/reference#cdn-formatting) |
| cover_image? | string | The application's default rich presence invite [cover image hash](/reference#cdn-formatting) |
| splash? | string | The application's [splash hash](/reference#cdn-formatting) |
| type | ?integer | The [type of the application](#application-type), if any |
| flags ^7^ | integer | The [application's flags](#application-flags) (including private) |
| flags_new ^7^ | string | The [application's flags](#application-flags) (including private) serialized as a stringified integer |
| primary_sku? ^6^ | [SKU](/resources/store#sku-object) object | The primary SKU the application displays |
| primary_sku_id? ^1^ | snowflake | The ID of the application's primary SKU (game, application subscription, etc.) |
| verify_key | string | The hex encoded client public key for verification in interactions and the GameSDK's `GetTicket` |
| guild_id? | snowflake | The ID of the guild linked to the application |
| guild? ^2^ | partial [guild](/resources/guild#guild-object) object | The guild linked to the application |
| eula_id? | snowflake | The ID of the EULA required to play the application's game {/* todo: link this here */} |
| slug? ^1^ | string | The URL slug that links to the primary store page of the application |
| aliases? | array[string] | Other names the application's game is associated with |
| executables? | array[[application executable](/resources/game#application-executable-object) object] | The unique executables of the application's game |
| third_party_skus? | array[[application SKU](/resources/game#application-sku-object) object] | The third party SKUs of the application's game |
| hook | boolean | Whether the Discord client is allowed to hook into the application's game directly |
| overlay? | boolean | Whether the application's game supports the [Discord overlay](https://support.discord.com/hc/en-us/articles/217659737-Game-Overlay-101) (default false) |
| overlay_methods? | integer | The [methods of overlaying](#overlay-method-flags) that the application's game supports |
| overlay_warn? | boolean | Whether the [Discord overlay](https://support.discord.com/hc/en-us/articles/217659737-Game-Overlay-101) is known to be problematic with this application's game (default false) |
| overlay_compatibility_hook? | boolean | Whether to use the compatibility hook for the overlay (default false) |
| bot? | partial [user](/resources/user#user-object) object | The bot attached to this application |
| team? ^3^ | ?[team](/resources/team#team-object) object | The team that owns the application |
| developers? | array[[company](/resources/team#company-object) object] | The companies that developed the application |
| publishers? | array[[company](/resources/team#company-object) object] | The companies that published the application |
| rpc_origins? | array[string] | The whitelisted RPC origin URLs for the application, if RPC is enabled |
| deeplink_uri? | string | The URL used for deep linking during [OAuth2 authorization](/topics/oauth2) on mobile devices |
| integration_public? | boolean | Whether only the application owner can add the integration |
| integration_require_code_grant? | boolean | Whether the integration will only be added upon completion of a full OAuth2 token exchange |
| bot_public? ^4^ **(deprecated)** | boolean | Whether only the application owner can add the bot |
| bot_require_code_grant? ^4^ **(deprecated)** | boolean | Whether the application's bot will only be added upon completion of a full OAuth2 token exchange |
| terms_of_service_url? | ?string | The URL to the application's terms of service |
| privacy_policy_url? | ?string | The URL to the application's privacy policy |
| tags? | array[string] | Tags describing the content and functionality of the application (max 20 characters, max 5) |
| install_params? | [application install params](#application-install-params-object) object | The default in-app authorization link for the integration |
| custom_install_url? | string | The default custom authorization link for the integration |
| integration_types_config? | map[integer, ?[application integration type configuration](#application-integration-type-configuration-structure) object] | The configuration for each [integration type](#application-integration-type) supported by the application |
| connection_entrypoint_url? | string | The URL which users will be directed to when connecting their account in the application to their Discord account |
| is_verified | boolean | Whether the application is verified |
| is_discoverable | boolean | Whether the application is discoverable in the application directory |
| is_monetized | boolean | Whether the application has monetization enabled |
| storefront_available | boolean | Whether the application has public subscriptions or products available for purchase |
| max_participants? ^5^ | integer | The maximum possible participants in the application's embedded activity (-1 for no limit) |
| embedded_activity_config? ^5^ | [embedded activity config](#embedded-activity-config-object) object | The configuration for the application's embedded activity |
| parent_id? | snowflake | The ID of the parent application |
| categories? ^6^ | [category](/resources/application-directory#application-directory-category-object) object | The application directory entry categories |
| directory_entry? ^6^ | [directory entry](/resources/application-directory#application-directory-entry-object) object | The application directory entry |
| position? ^6^ | integer | The position of the application in the directory collection |
| game_data_overrides? | [game data overrides](#game-data-overrides-object) | The game data overrides for the application |
^1^ The `primary_sku_id` and `slug` fields can be combined to form a URL to the application's primary store page like so: `https://discord.com/store/skus/{primary_sku_id}/{slug}`.
^2^ Only present when fetched from the [Get Partial Application](#get-partial-application) endpoint with `with_guild` set to `true`. The guild must be discoverable.
^3^ Only present when fetched from the [List Guild Applications](#list-guild-applications) endpoint. You must own the application or be a member of the owning team to receive this information.
^4^ In some cases, these fields may still be provided instead of `integration_public` and `integration_require_code_grant`. These fields will not be present if the application does not have a bot.
^5^ Only applicable for applications with the [`EMBEDDED` flag](#application-flags).
^6^ Only present when fetched from [Application Directory](/resources/application-directory) endpoints.
^7^ The `flags` field is serialized as a number; however, this number will not grow beyond 31 bits. New flag bits beyond bit 30 will only appear in `flags_new`, a string-serialized integer
containing the full set of flag bits.
###### Application Type
| Value | Name | Description |
| ----- | -------------------- | -------------------------------------------------------------------------------------------- |
| 1 | DEPRECATED_GAME | A game integrating with Discord through the legacy GameSDK or sold on the defunct game store |
| ~~2~~ | ~~MUSIC~~ | ~~A music service integrating with Discord~~ |
| 3 ^1^ | TICKETED_EVENTS | A limited application used for ticketed event SKUs |
| 4 ^1^ | CREATOR_MONETIZATION | A limited application used for creator monetization (e.g. role subscription) SKUs |
| 5 | GAME | A game integrating with Discord |
^1^ Applications of these types cannot be used through most of the regular applications APIs outlined here.
###### Application Flags
| Value | Name | Description | Public |
| ------------- | -------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------- | ------- |
| 1 \<\< 1 | EMBEDDED_RELEASED | Embedded application is released to the public (see also [release phases](#embedded-activity-release-phase)) | Yes |
| 1 \<\< 2 | MANAGED_EMOJI | Application can create managed emoji | No |
| 1 \<\< 3 | EMBEDDED_IAP | Embedded application can use in-app purchases | Yes |
| 1 \<\< 4 | GROUP_DM_CREATE | Application can create group DMs without limit | No |
| 1 \<\< 5 | RPC_PRIVATE_BETA | Application can use the `rpc` scope without limitation | No |
| 1 \<\< 6 | AUTO_MODERATION_RULE_CREATE_BADGE | Application has created 100+ AutoMod rules | Yes |
| 1 \<\< 7 | GAME_PROFILE_DISABLED | Application has its game profile page disabled | Yes |
| 1 \<\< 8 | PUBLIC_OAUTH2_CLIENT | Application's OAuth2 credentials are considered public and a client secret is not required | No |
| 1 \<\< 9 | CONTEXTLESS_ACTIVITY | Embedded application's activity can be launched without a context | Yes |
| 1 \<\< 10 | SOCIAL_LAYER_INTEGRATION_LIMITED | Application has limited access to the social layer SDK | Yes |
| 1 \<\< 11 | CLOUD_GAMING_DEMO | Application is trialing cloud gaming features | No |
| 1 \<\< 12 | GATEWAY_PRESENCE | Intent required for bots in **100 or more guilds** to receive [Presence Update](/gateway/gateway-events#presence-update) Gateway events | Yes |
| 1 \<\< 13 | GATEWAY_PRESENCE_LIMITED | Intent required for bots in **under 100 guilds** to receive [Presence Update](/gateway/gateway-events#presence-update) Gateway events | Yes |
| 1 \<\< 14 | GATEWAY_GUILD_MEMBERS | Intent required for bots in **100 or more guilds** to receive guild member-related events like [Guild Member Add](/gateway/gateway-events#guild-member-add) | Yes |
| 1 \<\< 15 | GATEWAY_GUILD_MEMBERS_LIMITED | Intent required for bots in **under 100 guilds** to receive guild member-related events like [Guild Member Add](/gateway/gateway-events#guild-member-add) | Yes |
| 1 \<\< 16 | VERIFICATION_PENDING_GUILD_LIMIT | Indicates unusual growth of an application that prevents verification | Yes |
| 1 \<\< 17 | EMBEDDED | Application can be embedded within the Discord client | Yes |
| 1 \<\< 18 | GATEWAY_MESSAGE_CONTENT | Intent required for bots in **100 or more guilds** to receive [message content](https://support-dev.discord.com/hc/en-us/articles/4404772028055) | Yes |
| 1 \<\< 19 | GATEWAY_MESSAGE_CONTENT_LIMITED | Intent required for bots in **under 100 guilds** to receive [message content](https://support-dev.discord.com/hc/en-us/articles/4404772028055) | Yes |
| 1 \<\< 20 | EMBEDDED_FIRST_PARTY | Embedded application is created by Discord | Yes |
| 1 \<\< 21 | APPLICATION_COMMAND_MIGRATED | Unknown | Yes |
| 1 \<\< 23 | APPLICATION_COMMAND_BADGE | Application has registered global application commands | Yes |
| 1 \<\< 24 | ACTIVE | Application has had at least one global application command used in the last 30 days | No |
| 1 \<\< 25 | ACTIVE_GRACE_PERIOD | Application has not had any global application commands used in the last 30 days and has lost the `ACTIVE` flag | No |
| 1 \<\< 26 | IFRAME_MODAL | Application can use IFrames within modals | Yes |
| 1 \<\< 27 | SOCIAL_LAYER_INTEGRATION | Application can use the social layer SDK | Yes |
| 1 \<\< 29 | PROMOTED | Application is promoted by Discord in the application directory | Yes |
| 1 \<\< 30 | PARTNER | Application is a Discord partner | Yes |
| 1 \<\< 33 | PARENT | Application is a parent of a child application | Yes |
| 1 \<\< 34 | DISABLE_RELATIONSHIP_ACCESS | Application cannot access relationship information | Yes |
| 1 \<\< 35 | STOREFRONT_ELIGIBLE | Application can create storefront listings | No |
| ~~1 \<\< 8~~ | ~~ALLOW_ASSETS~~ | ~~Application can use activity assets~~ | ~~No~~ |
| ~~1 \<\< 9~~ | ~~ALLOW_ACTIVITY_ACTION_SPECTATE~~ | ~~Application can enable spectating activities~~ | ~~No~~ |
| ~~1 \<\< 10~~ | ~~ALLOW_ACTIVITY_ACTION_JOIN_REQUEST~~ | ~~Application can enable activity join requests~~ | ~~No~~ |
| ~~1 \<\< 11~~ | ~~RPC_HAS_CONNECTED~~ | ~~Application has accessed the client RPC server before~~ | ~~Yes~~ |
###### Overlay Method Flags
| Value | Name | Description |
| -------- | -------------- | -------------------------------------- |
| 1 \<\< 0 | OUT_OF_PROCESS | Overlay can be rendered out of process |
###### Internal Guild Restriction
| Value | Name | Description |
| ----- | ------------------ | -------------------------------------------------------------------------------------------------------------------------------------- |
| 1 | JOIN_ALL | The application can be authorized in any guild |
| 2 | JOIN_EXTERNAL_ONLY | The application can only be authorized in guilds without the [`INTERNAL_EMPLOYEE_ONLY` guild feature](/resources/guild#guild-features) |
| 3 | JOIN_INTERNAL_ONLY | The application can only be authorized in guilds with the [`INTERNAL_EMPLOYEE_ONLY` guild feature](/resources/guild#guild-features) |
###### Application Interactions Version
| Value | Name | Description |
| ----- | --------- | ------------------------------------------------------------------------------------------------------------- |
| 1 | VERSION_1 | Only [Interaction Create](/gateway/gateway-events#interaction-create) events are sent as documented (default) |
| 2 | VERSION_2 | A selection of chosen events are sent |
###### Event Webhooks Status
| Value | Name | Description |
| ----- | -------- | --------------------------- |
| 1 | DISABLED | Event webhooks are disabled |
| 2 | ENABLED | Event webhooks are enabled |
###### Event Webhooks Type
| Value | Description |
| -------------------------- | ---------------------------------------------------------------------- |
| APPLICATION_AUTHORIZED | Sent when a user authorizes the application |
| APPLICATION_DEAUTHORIZED | Sent when a user deauthorizes the application |
| ENTITLEMENT_CREATE | Sent when a user creates an entitlement |
| ENTITLEMENT_UPDATE | Sent when an entitlement is updated |
| ENTITLEMENT_DELETE | Sent when an entitlement is deleted |
| QUEST_USER_ENROLLMENT | Sent when a user enrolls in a quest |
| LOBBY_MESSAGE_CREATE | Sent when a user sends a message in a lobby |
| LOBBY_MESSAGE_UPDATE | Sent when a user updates a message in a lobby |
| LOBBY_MESSAGE_DELETE | Sent when a user deletes a message in a lobby |
| GAME_DIRECT_MESSAGE_CREATE | Sent when a user sends a direct message through the social layer SDK |
| GAME_DIRECT_MESSAGE_UPDATE | Sent when a user updates a direct message through the social layer SDK |
| GAME_DIRECT_MESSAGE_DELETE | Sent when a user deletes a direct message through the social layer SDK |
###### Explicit Content Filter Level
| Value | Name | Description |
| ----- | ------- | ---------------------------------------------------------------------------------------------- |
| 0 | INHERIT | Inherits the guild's [explicit content filter](/resources/guild#explicit-content-filter-level) |
| 1 | ALWAYS | Media content will always be scanned |
###### Application Verification State
| Value | Name | Description |
| ----- | ---------------------- | ---------------------------------------------------------------------------------------------------- |
| 1 | INELIGIBLE | This application is ineligible for verification |
| 2 | UNSUBMITTED | This application has not yet been applied for verification |
| 3 | SUBMITTED | This application has submitted a verification request |
| 4 | APPROVED_MANUALLY | This application has been verified manually from Discord staff or using the old verification process |
| 5 | BLOCKED | This application is blocked and cannot be verified |
| 6 | APPROVED_AUTOMATICALLY | This application has been verified automatically through the Stripe identity verification process |
###### Store Application State
| Value | Name | Description |
| ----- | --------- | ------------------------------------------------------------------------------------------ |
| 1 | NONE | This application does not have a commerce license |
| 2 | PAID | This application has a commerce license but has not yet submitted a store approval request |
| 3 | SUBMITTED | This application has submitted a store approval request |
| 4 | APPROVED | This application has been approved for the store |
| 5 | REJECTED | This application has been rejected from the store |
###### RPC Application State
| Value | Name | Description |
| ----- | ----------- | -------------------------------------------------------- |
| 0 | DISABLED | This application does not have access to RPC |
| 1 | UNSUBMITTED | This application has not yet been applied for RPC access |
| 2 | SUBMITTED | This application has submitted a RPC access request |
| 3 | APPROVED | This application has been approved for RPC access |
| 4 | REJECTED | This application has been rejected from RPC access |
###### Application Discoverability State
| Value | Name | Description |
| ----- | ---------------- | ----------------------------------------------------------------------------- |
| 1 | INELIGIBLE | This application is ineligible for the application directory |
| 2 | NOT_DISCOVERABLE | This application is not listed in the application directory |
| 3 | DISCOVERABLE | This application is listed in the application directory |
| 4 | FEATUREABLE | This application is featurable in the application directory |
| 5 | BLOCKED | This application has been blocked from appearing in the application directory |
###### Application Discovery Eligibility Flags
| Value | Name | Description |
| --------- | ----------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| 1 \<\< 0 | VERIFIED | Application is verified |
| 1 \<\< 1 | TAG | Application has at least one tag set |
| 1 \<\< 2 | DESCRIPTION | Application has a description |
| 1 \<\< 3 | TERMS_OF_SERVICE | Application has terms of service set |
| 1 \<\< 4 | PRIVACY_POLICY | Application has a privacy policy set |
| 1 \<\< 5 | INSTALL_PARAMS | Application has a custom install URL or install parameters |
| 1 \<\< 6 | SAFE_NAME | Application's name is safe for work |
| 1 \<\< 7 | SAFE_DESCRIPTION | Application's description is safe for work |
| 1 \<\< 8 | APPROVED_COMMANDS | Application has the [message content intent](/gateway/using-gateway#message-content-intent) approved or utilizes [application commands](/interactions/application-commands) |
| 1 \<\< 9 | SUPPORT_GUILD | Application has a support guild set |
| 1 \<\< 10 | SAFE_COMMANDS | Application's commands are safe for work |
| 1 \<\< 11 | MFA | Application's owner has MFA enabled |
| 1 \<\< 12 | SAFE_DIRECTORY_OVERVIEW | Application's directory long description is safe for work |
| 1 \<\< 13 | SUPPORTED_LOCALES | Application has at least one supported locale set |
| 1 \<\< 14 | SAFE_SHORT_DESCRIPTION | Application's directory short description is safe for work |
| 1 \<\< 15 | SAFE_ROLE_CONNECTIONS | Application's role connections metadata is safe for work |
###### Application Monetization State
| Value | Name | Description |
| ----- | ------- | -------------------------------------------------- |
| 1 | NONE | This application does not have monetization set up |
| 2 | ENABLED | This application has monetization set up |
| 3 | BLOCKED | This application has been blocked from monetizing |
###### Creator Monetization State
The values of this enum are currently unknown. Help us by figuring them out and [submitting a pull request](https://github.com/discord-userdoccers/discord-userdoccers/edit/master/pages/resources/application.mdx)!
###### Application Monetization Eligibility Flags
| Value | Name | Description |
| --------- | --------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| 1 \<\< 0 | VERIFIED | Application is verified |
| 1 \<\< 1 | HAS_TEAM | Application is owned by a team |
| 1 \<\< 2 | APPROVED_COMMANDS | Application has the [message content intent](/gateway/using-gateway#message-content-intent) approved or utilizes [application commands](/interactions/application-commands) |
| 1 \<\< 3 | TERMS_OF_SERVICE | Application has terms of service set |
| 1 \<\< 4 | PRIVACY_POLICY | Application has a privacy policy set |
| 1 \<\< 5 | SAFE_NAME | Application's name is safe for work |
| 1 \<\< 6 | SAFE_DESCRIPTION | Application's description is safe for work |
| 1 \<\< 7 | SAFE_ROLE_CONNECTIONS | Application's role connections metadata is safe for work |
| 1 \<\< 8 | USER_IS_TEAM_OWNER | User is the owner of the team that owns the application |
| 1 \<\< 9 | NOT_QUARANTINED | Application is not quarantined |
| 1 \<\< 10 | USER_LOCALE_SUPPORTED | User's locale is supported by monetization |
| 1 \<\< 11 | USER_AGE_SUPPORTED | User is old enough to use monetization |
| 1 \<\< 12 | USER_DATE_OF_BIRTH_DEFINED | User has a date of birth defined on their account |
| 1 \<\< 13 | USER_MFA_ENABLED | User has MFA enabled |
| 1 \<\< 14 | USER_EMAIL_VERIFIED | User's email is verified |
| 1 \<\< 15 | TEAM_MEMBERS_EMAIL_VERIFIED | All members of the team that owns the application have verified emails |
| 1 \<\< 16 | TEAM_MEMBERS_MFA_ENABLED | All members of the team that owns the application have MFA enabled |
| 1 \<\< 17 | NO_BLOCKING_ISSUES | This application has no issues blocking monetization |
| 1 \<\< 18 | VALID_PAYOUT_STATUS | Owning team has a valid payout status |
###### Pricing Localization Strategy
The values of this enum are currently unknown. Help us by figuring them out and [submitting a pull request](https://github.com/discord-userdoccers/discord-userdoccers/edit/master/pages/resources/application.mdx)!
| Value | Description |
| -------------------- | --------------------------------- |
| localized_price_sets | Localized price for each currency |
###### Example Application
```json
{
"id": "891436243903728565",
"name": "Socket",
"icon": "26f3dcdc6e6371b52c384c812c30546c",
"description": "Socket",
"type": null,
"is_monetized": false,
"is_verified": false,
"is_discoverable": false,
"bot": {
"id": "891436243903728565",
"username": "Socket",
"avatar": "26f3dcdc6e6371b52c384c812c30546c",
"discriminator": "0001",
"public_flags": 0,
"bot": true,
"banner": null,
"accent_color": null,
"global_name": null,
"avatar_decoration_data": null,
"primary_guild": null
},
"deeplink_uri": "https://google.com/search?q=power+sockets+near+me",
"bot_public": true,
"bot_require_code_grant": false,
"verify_key": "852634a9ed80c0c5ac81e3c46d4b10a05400cb71898ea0484e7b63ac3a27096a",
"flags": 27828224,
"tags": ["60hz", "AC", "", "120v"],
"hook": true,
"storefront_available": false,
"redirect_uris": ["http://localhost:5000/callback"],
"interactions_endpoint_url": null,
"role_connections_verification_url": "https://google.com/search?q=power+sockets+near+me",
"owner": {
"id": "1110738998453837384",
"username": "team1110738998453837384",
"avatar": null,
"discriminator": "0000",
"public_flags": 1024,
"banner": null,
"accent_color": null,
"global_name": null,
"avatar_decoration_data": null,
"primary_guild": null
},
"bot_approximate_guild_count": 100,
"approximate_guild_count": 100,
"approximate_user_install_count": 1000,
"interactions_event_types": [],
"interactions_version": 1,
"explicit_content_filter": 1,
"rpc_application_state": 0,
"store_application_state": 1,
"creator_monetization_state": 1,
"verification_state": 1,
"integration_public": true,
"integration_require_code_grant": false,
"discoverability_state": 1,
"discovery_eligibility_flags": 36294,
"monetization_state": 1,
"monetization_eligibility_flags": 0,
"publishers": [{ "id": "1058932127820939295", "name": "AlienTec" }],
"developers": [{ "id": "1058932084854509568", "name": "Alien Games" }],
"team": {
"id": "1110738998453837384",
"icon": null,
"name": "Power",
"owner_user_id": "852892297661906993",
"members": [
{
"user": {
"id": "852892297661906993",
"username": "dolfies",
"avatar": "c78ef8fb1db15a3d5f1b4c057856c5c9",
"discriminator": "0",
"public_flags": 136,
"banner": null,
"accent_color": null,
"global_name": "Dolfies",
"avatar_decoration_data": null,
"primary_guild": null
},
"team_id": "1110738998453837384",
"membership_state": 2,
"role": "admin"
}
]
},
"internal_guild_restriction": 1
}
```
###### Example Partial Application
```json
{
"id": "880218394199220334",
"name": "Watch Together",
"icon": "ec48acbad4c32efab4275cb9f3ca3a58",
"description": "Create and watch a playlist of YouTube videos with your friends. Your choice to share the remote or not. ",
"type": null,
"is_monetized": false,
"is_verified": false,
"is_discoverable": false,
"cover_image": "3cc9446876ae9eec6e06ff565703c292",
"bot": {
"id": "880218394199220334",
"username": "Watch Together",
"avatar": "fe2b7fa334817b0346d57416ad75e93b",
"discriminator": "5319",
"public_flags": 0,
"bot": true,
"banner": null,
"accent_color": null,
"global_name": null,
"avatar_decoration_data": null,
"primary_guild": null
},
"summary": "",
"bot_public": false,
"bot_require_code_grant": false,
"terms_of_service_url": "https://discord.com/terms",
"privacy_policy_url": "https://discord.com/privacy",
"verify_key": "e2aaf50fbe2fd9d025ac669035f5efb89099931690fba9dc28efb7eaade7f96d",
"flags": 1179648,
"max_participants": -1,
"tags": ["Video Player", "Watch"],
"hook": true,
"storefront_available": false,
"embedded_activity_config": {
"activity_preview_video_asset_id": "1104184163201990836",
"supported_platforms": ["web", "ios", "android"],
"default_orientation_lock_state": 2,
"tablet_default_orientation_lock_state": 1,
"requires_age_gate": false,
"legacy_responsive_aspect_ratio": false,
"premium_tier_requirement": null,
"free_period_starts_at": null,
"free_period_ends_at": null,
"client_platform_config": {
"ios": { "label_type": 0, "label_until": null, "release_phase": "global_launch" },
"android": { "label_type": 0, "label_until": null, "release_phase": "global_launch" },
"web": { "label_type": 0, "label_until": null, "release_phase": "global_launch" }
},
"shelf_rank": 3,
"has_csp_exception": false,
"displays_advertisements": false
}
}
```
### Application Install Params Object
###### Application Install Params Structure
| Field | Type | Description |
| ----------- | ------------- | -------------------------------------------------------------------------------------------- |
| scopes | array[string] | The [scopes](/topics/oauth2#oauth2-scopes) to authorize the integration with |
| permissions | string | The [permissions](/topics/permissions) to request for the application's bot integration role |
###### Application Integration Type
An application's supported installation contexts.
| Value | Name | Description |
| ----- | ------------- | -------------------------- |
| 0 | GUILD_INSTALL | Guild installation context |
| 1 | USER_INSTALL | User installation context |
###### Application Integration Type Configuration Structure
| Field | Type | Description |
| ---------------------- | -------------------------------------------------------------------------- | ------------------------------------------------------------------ |
| oauth2_install_params? | [application install params](#application-install-params-structure) object | The default in-app authorization link for the installation context |
###### Example Application Install Params
```json
{
"scopes": ["applications.commands", "bot"],
"permissions": "8"
}
```
### Application Proxy Config Object
The application proxy makes it possible to proxy requests to a domain through the Discord activity proxy.
This is used by embedded activities to be able to make requests without being blocked by Discord's content security policy (CSP).
Mapped URLs are available at `.discordsays.com/`.
###### Application Proxy Config Structure
| Field | Type | Description |
| ------- | ------------------------------------------------------------------------------- | ---------------------------- |
| url_map | array[[application proxy mapping](#application-proxy-mapping-structure) object] | The URLs mapped to the proxy |
###### Application Proxy Mapping Structure
| Field | Type | Description |
| ------ | ------ | ----------------------- |
| prefix | string | The prefix on the proxy |
| target | string | The domain to proxy |
###### Example Application Proxy Config
```json
{
"url_map": [
{
"prefix": "/api",
"target": "api.example.com"
}
]
}
```
### Embedded Activity Config Object
###### Embedded Activity Config Structure
| Field | Type | Description |
| ----------------------------------------- | ----------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------- |
| application_id? ^1^ | snowflake | The ID of the application this embedded activity is for |
| activity_preview_video_asset_id | ?snowflake | The ID of the application asset to preview the activity with |
| supported_platforms | array[string] | The [platforms this activity is supported on](#embedded-activity-platform-type) |
| default_orientation_lock_state | integer | The default [orientation lock state](#embedded-activity-orientation-lock-state-type) for the activity on mobile |
| tablet_default_orientation_lock_state | integer | The default [orientation lock state](#embedded-activity-orientation-lock-state-type) for the activity on tablets |
| requires_age_gate | boolean | Whether the activity is age gated |
| legacy_responsive_aspect_ratio | boolean | Whether the activity uses a responsive aspect ratio instead of a dynamic aspect ratio |
| premium_tier_requirement **(deprecated)** | ?integer | The minimum [guild premium tier](/resources/guild#premium-tier) required to use the activity, if any |
| free_period_starts_at **(deprecated)** | ?ISO8601 timestamp | When the current free period for the activity starts, if any |
| free_period_ends_at **(deprecated)** | ?ISO8601 timestamp | When the current free period for the activity ends, if any |
| client_platform_config | map[string, [embedded activity platform config](#embedded-activity-platform-config-structure) object] | The release configuration for the activity on each [platform](#embedded-activity-platform-type) |
| shelf_rank | integer | The rank of the activity in the activity shelf sort order |
| has_csp_exception | boolean | Whether the activity is not routed through the Discord activity proxy |
| displays_advertisements | boolean | Whether the activity displays advertisements |
| supported_locales ^2^ | array[string] | The [ISO 3166-1 alpha-2](https://en.wikipedia.org/wiki/ISO_3166-1_alpha-2) country codes the activity is available in |
| blocked_locales | array[string] | The [ISO 3166-1 alpha-2](https://en.wikipedia.org/wiki/ISO_3166-1_alpha-2) country codes the activity is blocked in |
^1^ Omitted in the [application object](#application-object).
^2^ If the field is empty, the activity is available in all countries.
###### Embedded Activity Orientation Lock State Type
| Value | Name | Description |
| ----- | --------- | ------------------------ |
| 1 | UNLOCKED | Unrestricted orientation |
| 2 | PORTRAIT | Portrait only |
| 3 | LANDSCAPE | Landscape only |
##### Embedded Activity Platform Type
| Value | Description |
| ------- | ----------- |
| web | Web |
| android | Android |
| ios | iOS |
###### Embedded Activity Platform Config Structure
| Field | Type | Description |
| ------------------------ | ------------------ | --------------------------------------------------------------------------- |
| label_type | integer | The [type of release label](#embedded-activity-label-type) for the platform |
| label_until? | ?ISO8601 timestamp | When the release label expires |
| release_phase | string | The [release phase](#embedded-activity-release-phase) for the platform |
| omit_badge_from_surfaces | array[string] | The [surfaces](#embedded-activity-surface) to omit the activity badge from |
###### Embedded Activity Label Type
| Value | Name | Description |
| ----- | ------- | -------------------------------------- |
| 0 | NONE | No special label |
| 1 | NEW | The activity is new |
| 2 | UPDATED | The activity has been recently updated |
###### Embedded Activity Release Phase
| Value | Description |
| --------------------- | ------------------------------------------------------------------------------------------------------------------- |
| in_development | The activity is still in development |
| activities_team | The activity is available to guilds with the [`ACTIVITIES_ALPHA` guild feature](/resources/guild#guild-features) |
| employee_release | The activity is available to guilds with the [`ACTIVITIES_EMPLOYEE` guild feature](/resources/guild#guild-features) |
| soft_launch | The activity is available to all guilds in Canada |
| soft_launch_multi_geo | The activity is available to all guilds in multiple countries |
| global_launch | The activity is available to all guilds |
###### Embedded Activity Surface
| Value | Description |
| -------------- | ---------------------------------------------------- |
| voice_launcher | The activity launcher in the voice channel interface |
| text_launcher | The activity launcher in the text channel interface |
###### Example Embedded Activity Config
```json
{
"activity_preview_video_asset_id": "1104184163201990836",
"supported_platforms": ["web", "ios", "android"],
"default_orientation_lock_state": 2,
"tablet_default_orientation_lock_state": 1,
"requires_age_gate": false,
"legacy_responsive_aspect_ratio": false,
"premium_tier_requirement": null,
"free_period_starts_at": null,
"free_period_ends_at": null,
"client_platform_config": {
"android": {
"label_type": 0,
"label_until": null,
"release_phase": "global_launch",
"omit_badge_from_surfaces": []
},
"ios": {
"label_type": 0,
"label_until": null,
"release_phase": "global_launch",
"omit_badge_from_surfaces": []
},
"web": {
"label_type": 0,
"label_until": null,
"release_phase": "global_launch",
"omit_badge_from_surfaces": []
}
},
"shelf_rank": 3,
"has_csp_exception": false,
"displays_advertisements": false,
"application_id": "880218394199220334"
}
```
### Embedded Activity Instance Object
###### Embedded Activity Instance Structure
| Field | Type | Description |
| --------------------- | --------------------------------------------------------------------------------------- | --------------------------------------------------------------------------- |
| application_id | snowflake | The ID of the application for this activity instance |
| composite_instance_id | string | The [composite ID](#embedded-activity-instance-id) of the activity instance |
| instance_id | snowflake | The ID of the activity instance |
| launch_id | snowflake | The ID of the activity instance launch |
| location | [embedded activity location](#embedded-activity-location-structure) object | The location the activity instance is running in |
| participants | array[[embedded activity participant](#embedded-activity-participant-structure) object] | The users participating in the activity instance |
###### Embedded Activity Instance ID
The composite ID of an activity instance is a globally unique identifier for an activity instance in a channel.
It is in the format `i----`, where `` is omitted for private channels.
###### Embedded Activity Location Structure
| Field | Type | Description |
| ---------- | ---------- | ----------------------------------------------------------------------------------- |
| id | string | The [composite ID](#embedded-activity-location-id) of the location |
| kind | string | The [type of location](#embedded-activity-location-type) the activity is running in |
| channel_id | snowflake | The ID of the channel the activity is running in |
| guild_id? | ?snowflake | The ID of the guild the activity is running in |
###### Embedded Activity Location ID
The composite ID of an activity location is a globally unique identifier for a channel.
It is in the format `--`, where `` is omitted for private channels.
###### Embedded Activity Location Type
| Value | Description |
| ----- | --------------- |
| gc | Guild channel |
| pc | Private channel |
###### Embedded Activity Participant Structure
| Field | Type | Description |
| ---------- | ----------------------------------------------------------- | ------------------------------------------------- |
| user_id | snowflake | The ID of the user participating in the activity |
| member? | [guild member](/resources/guild#guild-member-object) object | The guild member data for the user, if in a guild |
| session_id | string | The session ID the participant is connected with |
| nonce | ?string | Unknown |
###### Example Embedded Activity Instance
```json
{
"application_id": "1211781489931452447",
"composite_instance_id": "i-1420621242070732950-pc-1386091138305359984",
"instance_id": "1420621242070732950",
"launch_id": "1420621242070732950",
"location": {
"channel_id": "1386091138305359984",
"id": "pc-1386091138305359984",
"kind": "pc"
},
"participants": [
{
"nonce": null,
"session_id": "3b5d8906771b15af3346454c4e6cf9d5",
"user_id": "852892297661906993"
}
]
}
```
### Game Data Overrides Object
###### Game Data Overrides Structure
| Field | Type | Description |
| -------------------- | -------------------------------------------------------------------- | -------------------------------------------------------------------------------------------- |
| description? | ?string | The description of the game |
| genres? | array[integer] | The [genres](/resources/store#sku-genre) of the game |
| platforms? | array[integer] | The [platforms that the game is available on](/resources/game#game-platform-type) |
| cover_hash? | ?string | The application's default rich presence invite [cover image hash](/reference#cdn-formatting) |
| screenshot_hashes? | array[string] | The game's [screenshot hashes](/reference#cdn-formatting) |
| trailer_asset_ids? | array[snowflake] | The IDs of game trailer assets |
| websites? | array[[game website](/resources/game#game-website-structure) object] | The websites relating to the game |
| companies | array[[company](/resources/game#company-structure) object] | The companies working on the game |
| shop_collection_ids? | array[snowflake] | The IDs of the storefront collections |
| banner_hash? | ?string | The game's [banner hash](/reference#cdn-formatting) |
| icon_hash? | ?string | The game's [icon hash](/reference#cdn-formatting) |
| game_flags? | integer | The [game's flags](/resources/game#game-flags) |
### Application OAuth2 Asset Object
###### Application OAuth2 Asset Structure
| Field | Type | Description |
| --------------------- | ------- | ------------------------------------------------ |
| id | string | The ID of the asset |
| type **(deprecated)** | integer | The [type of the asset](#application-asset-type) |
| name | string | The name of the asset |
###### Application OAuth2 Asset Type
| Value | Name | Description |
| ----- | ----- | ----------- |
| 1 | SMALL | Small asset |
| 2 | LARGE | Large asset |
###### Example Application OAuth2 Asset
```json
{
"id": "1131721726514954381",
"type": 1,
"name": "alien"
}
```
### Application Asset Object
###### Application Asset Structure
| Field | Type | Description |
| ---------- | ----------------------------------------------------------------------- | ------------------------------------------------------------ |
| asset_id | snowflake | The [ID of the asset](/reference#cdn-formatting) |
| asset_type | string | The [type of the asset](#application-asset-type) |
| key | string | The name of the asset |
| metadata | [application asset metadata](#application-asset-metadata-object) object | The metadata for the asset |
| updated_at | ISO8601 timestamp | When the asset was last updated |
| visibility | string | The [visibility of the asset](#application-asset-visibility) |
###### Application Asset Metadata Object
| Field | Type | Description |
| ------------ | ------- | ----------------------------- |
| content_type | string | The content type of the asset |
| height | integer | The height of the asset |
| width | integer | The width of the asset |
| is_animated | boolean | Whether the asset is animated |
###### Application Asset Type
| Value | Description |
| ----- | -------------- |
| image | An image asset |
###### Application Asset Visibility
| Value | Description |
| ------- | ----------------------------------- |
| private | Whether the asset should be private |
| public | Whether the asset should be public |
### Application Role Connection Object
The role connection object that an application has attached to a user.
###### Application Role Connection Structure
| Field | Type | Description |
| --------------------- | -------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| platform_name | ?string | The vanity name of the platform a bot has connected (max 50 characters) |
| platform_username | ?string | The username on the platform a bot has connected (max 100 characters) |
| metadata | object | Object mapping [application role connection metadata](#application-role-connection-metadata-object) keys to their `string`-ified value (max 100 characters) for the user on the platform a bot has connected |
| application? | [integration application](/resources/integration#integration-application-object) object | The application that owns the role connection |
| application_metadata? | array[[application role connection metadata](#application-role-connection-metadata-object) object] | The metadata that the application has set for the role connection |
### Application Role Connection Metadata Object
A representation of role connection metadata for an [application](#application-object).
When a guild has added an application integration and that integration has configured its [`role_connections_verification_url`](#application-object), the application will render as a potential verification method in the guild's role verification configuration.
If an application has configured role connection metadata, its metadata will appear in the role verification configuration when the application has been added as a verification method to the role.
When a user connects their account using the integration's [`role_connections_verification_url`](#application-object), the integration will [update a user's role connection with metadata](#modify-user-application-role-connection) using the OAuth2 `role_connections.write` scope.
###### Application Role Connection Metadata Structure
| Field | Type | Description |
| -------------------------- | ------------- | ------------------------------------------------------------------------------------ |
| type | integer | The [type of metadata value](/resources/guild#role-connection-operator-type) |
| key | string | Key for the metadata field (1-50 characters, must be `a-z`, `0-9`, or `_`) |
| name | string | The name of the metadata field (1-100 characters) |
| name_localizations? | map[str, str] | Translations of the name with keys in [available locales](/reference#locales) |
| description | string | The description of the metadata field (1-200 characters) |
| description_localizations? | map[str, str] | Translations of the description with keys in [available locales](/reference#locales) |
Each metadata type offers a comparison operation that allows guilds to configure role requirements based on metadata values stored by the bot. Bots specify a `metadata value` for each user and guilds specify the required `guild's configured value` within the guild role settings.
### Activity Link Object
###### Activity Link Structure
| Field | Type | Description |
| ----------------------------- | --------- | ------------------------------------------------ |
| application_id | snowflake | The application ID |
| link_id ^1^ | string | The link ID |
| asset_path? ^2^ | string | The hash of the application quick link asset |
| asset_id? ^2^ | snowflake | The ID of the application asset |
| title | string | The title of the activity link |
| description | string | The description of the activity link |
| custom_id? | ?string | A custom ID for the activity link |
| primary_cta? **(deprecated)** | ?string | The primary call to action for the activity link |
^1^ The link ID is in the format `-` where `type` is the [activity link type](#activity-link-type) and `id` is the snowflake ID.
^2^ `asset_path` is only present on quick links, while `asset_id` is only present on managed links.
###### Activity Link Type
| Value | Name | Description |
| ----- | ------------ | ------------------------------------------------ |
| 0 | MANAGED_LINK | Managed by the application and last indefinitely |
| 1 | QUICK_LINK | Made by the user and last for 30 days |
###### Example Activity Link
```json
{
"application_id": "891436233903964161",
"link_id": "1-1385320255148003439",
"asset_path": "74420086a1aee57564cd6fc9a28461b1",
"title": "Alien",
"description": "aliens",
"primary_cta": null,
"custom_id": "button"
}
```
### Social SDK Release Object
###### Social SDK Release Structure
| Field | Type | Description |
| ----------------- | ----------------------------------------------------------------------------------- | ----------------------------- |
| version | string | The version of the SDK |
| release_date_time | ISO8601 timestamp | When the SDK version released |
| artifacts ^1^ | array[[social SDK release artifact](#social-sdk-release-artifact-structure) object] | The SDK artifacts |
^1^ Only included when fetched from the [Get Social SDK Release](#get-social-sdk-release) endpoint.
### Social SDK Release Artifact Structure
| Field | Type | Description |
| ------------ | ------- | ----------------------------------- |
| download_url | string | The SDK download URL |
| filename | string | The filename |
| size_bytes | integer | The The size (in bytes) of the file |
###### Example Social SDK Release
```json
{
"version": "1.2.8730",
"release_date_time": "2025-05-08T12:00:00+00:00",
"artifacts": [
{
"download_url": "https://storage.googleapis.com/discord-slayer-sdk-artifacts/discord_partner_sdk/XXX/release/DiscordSocialSdk-1.2.8730.zip",
"filename": "DiscordSocialSdk-1.2.8730.zip",
"size_bytes": 156241906
},
{
"download_url": "https://storage.googleapis.com/discord-slayer-sdk-artifacts/discord_partner_sdk/XXX/release/DiscordSocialSdk-UnityPlugin-1.2.8730.zip",
"filename": "DiscordSocialSdk-UnityPlugin-1.2.8730.zip",
"size_bytes": 67692124
},
{
"download_url": "https://storage.googleapis.com/discord-slayer-sdk-artifacts/discord_partner_sdk/XXX/release/DiscordSocialSdk-UnitySample-1.2.8730.zip",
"filename": "DiscordSocialSdk-UnitySample-1.2.8730.zip",
"size_bytes": 67804418
},
{
"download_url": "https://storage.googleapis.com/discord-slayer-sdk-artifacts/discord_partner_sdk/XXX/release/DiscordSocialSdk-UnrealPlugin-1.2.8730.zip",
"filename": "DiscordSocialSdk-UnrealPlugin-1.2.8730.zip",
"size_bytes": 81056342
},
{
"download_url": "https://storage.googleapis.com/discord-slayer-sdk-artifacts/discord_partner_sdk/XXX/release/DiscordSocialSdk-UnrealSample-1.2.8730.zip",
"filename": "DiscordSocialSdk-UnrealSample-1.2.8730.zip",
"size_bytes": 81290780
}
]
}
```
###### Application External Identity Provider Configuration Structure
| Field | Type | Description |
| --------------- | ----------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------ |
| application_id | snowflake | The ID of the application |
| provider_type | integer | The [type of the identity provider](#application-identity-provider-type) |
| client_id | string | The ID of the primary provider client |
| oidc_issuer_url | ?string | The primary URL of the OpenID Connect Issuer |
| clients | array[[application external identity provider client](#application-external-identity-provider-client-structure) object] | The provider clients |
###### Application Identity Provider Type
| Value | Description |
| -------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------- |
| OIDC | OpenID Connect |
| EPIC_ONLINE_SERVICES | [Epic Online Services](https://dev.epicgames.com/docs/epic-online-services/eos-overview)-based authentication |
| STEAM | Steam-based authentication |
| UNITY | [Unity](https://docs.unity.com/ugs/manual/authentication/manual/unity-player-accounts)-based authentication |
| DISCORD_BOT ^1^ | Authentication via a Discord bot |
| APPLE | [Apple ID](https://developer.apple.com/documentation/devicemanagement/implementing-the-oauth2-authentication-user-enrollment-flow)-based authentication |
| PLAYSTATION_NETWORK | PlayStation Network-based authentication |
^1^ This provider type is not external and therefore cannot be created or modified.
###### Application External Identity Provider Client Structure
| Field | Type | Description |
| --------------- | ------- | --------------------------------------- |
| id | string | The ID of the provider client |
| oidc_issuer_url | ?string | The URL of the OpenID Connect Issuer |
| description? | ?string | The description of the client (max 250) |
| environment? | ?string | The environment for the client |
###### Example Application External Identity Provider Configuration
```json
{
"application_id": "1169421761859833997",
"provider_type": "UNITY",
"client_id": "d360455e-2b56-4922-bf73-b64b157d5934",
"oidc_issuer_url": null,
"clients": [
{
"id": "d360455e-2b56-4922-bf73-b64b157d5934",
"oidc_issuer_url": null,
"description": null,
"environment": null
}
]
}
```
###### Application Undeletable Reason
| Value | Name | Description |
| ----- | ----------------------------- | -------------------------------------------------- |
| 0 | UNKNOWN | Unknown |
| 1 | USER_THRESHOLD_EXCEEDED | The application has over 500 active users |
| 2 | SOCIAL_SDK_APP_DELETION_ERROR | The application is not deletable for other reasons |
| 3 | PARENT_HAS_CHILD_APPLICATIONS | The application has child applications |
###### Approvable Console Type
| Value | Name | Description |
| ----- | ------------- | ------------- |
| 1 | XBOX | Xbox |
| 2 | PLAYSTATION_5 | PlayStation 5 |
| 3 | PLAYSTATION_4 | PlayStation 4 |
## Endpoints
List Applications
Returns a list of [application](#application-object) objects that the current user has.
###### Query String Params
| Field | Type | Description |
| ----------------------- | ------- | ----------------------------------------------------------------------------------------- |
| with_team_applications? | boolean | Whether to include applications that a [team](/resources/team) the user is a part of owns |
List Applications with Assets
Returns a list of [application](#application-object) objects that the current user has, additionally including the application's assets.
###### Query String Params
| Field | Type | Description |
| ----------------------- | ------- | ----------------------------------------------------------------------------------------- |
| with_team_applications? | boolean | Whether to include applications that a [team](/resources/team) the user is a part of owns |
###### Response Body
| Field | Type | Description |
| ------------ | ---------------------------------------------------------------------------- | ------------------------------- |
| applications | array[[application](#application-object)] | The applications the user has |
| assets | map[snowflake, array[[application asset](#application-asset-object) object]] | The assets for each application |
###### Example Response
```json
{
"applications": [
{
"id": "891436243903728565",
"name": "Lightbulb",
"icon": "546242649e3b09a97af7e8f29983837b",
"description": "💡 Let there be light",
"summary": "",
"type": null,
"is_monetized": false,
"is_verified": false,
"is_discoverable": false,
"cover_image": "75bc61df60fc74c46b32fde3532f662b",
"deeplink_uri": "https://google.com/search?q=lightbulbs+near+me",
"hook": true,
"guild_id": "1029315212005888060",
"storefront_available": false,
"bot_public": true,
"bot_require_code_grant": false,
"terms_of_service_url": "https://google.com/search?q=lightbulbs+near+me",
"privacy_policy_url": "https://google.com/search?q=lightbulbs+near+me",
"integration_types_config": {
"0": {},
"1": {}
},
"verify_key": "852634a9ed80c0c5ac81e3c46d4b10a05400cb71898ea0484e7b63ac3a27096a",
"owner": {
"id": "1110738998453837384",
"username": "team1110738998453837384",
"global_name": null,
"avatar": null,
"avatar_decoration_data": null,
"discriminator": "0000",
"public_flags": 1024,
"primary_guild": null,
"flags": 1024
},
"flags": 27959296,
"redirect_uris": ["http://localhost:5000/callback"],
"rpc_application_state": 0,
"store_application_state": 1,
"verification_state": 1,
"interactions_endpoint_url": null,
"interactions_event_types": [],
"interactions_version": 1,
"integration_public": true,
"integration_require_code_grant": false,
"explicit_content_filter": 1,
"discoverability_state": 1,
"discovery_eligibility_flags": 36830,
"monetization_state": 1,
"role_connections_verification_url": "https://google.com/search?q=lightbulbs+near+me",
"internal_guild_restriction": 1,
"bot": {
"id": "891436243903728565",
"username": "Lightbulb",
"global_name": null,
"avatar": "546242649e3b09a97af7e8f29983837b",
"avatar_decoration_data": null,
"discriminator": "5312",
"public_flags": 0,
"primary_guild": null,
"bot": true
},
"approximate_guild_count": 100,
"approximate_user_install_count": 1000,
"max_participants": -1,
"embedded_activity_config": {
"activity_preview_video_asset_id": "1131721726514954381",
"supported_platforms": ["web", "android", "ios"],
"default_orientation_lock_state": 1,
"tablet_default_orientation_lock_state": 1,
"requires_age_gate": false,
"legacy_responsive_aspect_ratio": false,
"premium_tier_requirement": null,
"free_period_starts_at": null,
"free_period_ends_at": null,
"client_platform_config": {
"web": {
"label_type": 0,
"label_until": null,
"release_phase": "in_development"
},
"android": {
"label_type": 0,
"label_until": null,
"release_phase": "in_development"
},
"ios": {
"label_type": 0,
"label_until": null,
"release_phase": "in_development"
}
},
"shelf_rank": 2147483647,
"has_csp_exception": false,
"displays_advertisements": false
},
"tags": ["", "100W", "EnergyStar", "LED"]
}
],
"assets": {
"891436243903728565": [
{
"id": "1223782285833273507",
"type": 1,
"name": "embedded_background"
},
{
"id": "1223782287091564634",
"type": 1,
"name": "embedded_cover"
}
]
}
}
```
Create Application
Creates a new application. Returns an [application](#application-object) object on success. Users can have a maximum of 50 applications, with each team able to have a maximum of 25.
###### JSON Params
| Field | Type | Description |
| -------------- | ---------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| name | string | The name of the application |
| type? | integer | The [type of the application](#application-type) (only `CREATOR_MONETIZATION` is supported) |
| team_id? | snowflake | The ID of the [team](/resources/team) to create this application under |
| description? | ?string | The description of the application |
| icon? | ?[image data](/reference#cdn-data) | The application's icon |
| cover_image? | ?[image data](/reference#cdn-data) | The application's default rich presence invite cover image |
| flags? | integer | the [application's flags](#application-flags) (only `GATEWAY_GUILD_MEMBERS_LIMITED`, `GATEWAY_PRESENCE_LIMITED`, and `GATEWAY_MESSAGE_CONTENT_LIMITED` can be set) |
| guild_id? | ?snowflake | The ID of the guild linked to the application |
| redirect_uris? | ?array[string] | The whitelisted URLs for redirecting to during [OAuth2 authorization](/topics/oauth2) (max 10) |
| deeplink_uri? | ?string | The URL used for deep linking during [OAuth2 authorization](/topics/oauth2) on mobile devices |
Get Application
Returns an [application](#application-object) object for the given ID. User must be the owner of the application or member of the owning team.
Get Current Application
Returns the [application](#application-object) object associated with the requestor.
This endpoint is not usable by user accounts.
Modify Application
Modifies an application. User must be the owner of the application or developer of the owning team. Returns the updated [application](#application-object) object on success.
###### JSON Params
| Field | Type | Description |
| ---------------------------------------- | ------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| name? | string | The name of the application |
| description? | ?string | The description of the application |
| icon? | ?[image data](/reference#cdn-data) | The application's icon |
| cover_image? | ?[image data](/reference#cdn-data) | The application's default rich presence invite cover image |
| flags? | integer | The [application's flags](#application-flags) (only `PUBLIC_OAUTH2_CLIENT`, `GATEWAY_GUILD_MEMBERS_LIMITED`, `GATEWAY_PRESENCE_LIMITED`, and `GATEWAY_MESSAGE_CONTENT_LIMITED` can be set) |
| guild_id? | ?snowflake | The ID of the guild linked to the application |
| developer_ids? | ?array[snowflake] | The IDs of the companies that developed the application |
| publisher_ids? | ?array[snowflake] | The IDs of the companies that published the application |
| rpc_origins? | ?array[string] | The whitelisted RPC origin URLs for the application, if RPC is enabled |
| redirect_uris? | ?array[string] | The whitelisted URLs for redirecting to during [OAuth2 authorization](/topics/oauth2) (max 10) |
| deeplink_uri? | ?string | The URL used for deep linking during [OAuth2 authorization](/topics/oauth2) on mobile devices |
| integration_public? | boolean | Whether only the application owner can add the integration |
| integration_require_code_grant? | boolean | Whether the integration will only be added upon completion of a full OAuth2 token exchange |
| bot_public? **(deprecated)** | boolean | Whether only the application owner can add the bot |
| bot_require_code_grant? **(deprecated)** | boolean | Whether the application's bot will only be added upon completion of a full OAuth2 token exchange |
| terms_of_service_url? | ?string | The URL to the application's terms of service |
| privacy_policy_url? | ?string | The URL to the application's privacy policy |
| role_connections_verification_url | ?string | The role connection verification entry point of the integration; when configured, this will render the application as a verification method in guild role verification configuration |
| interactions_endpoint_url? | string | The URL of the application's [interactions endpoint](/interactions/receiving-and-responding#receiving-an-interaction) |
| interactions_version? | integer | The [version of the application's interactions endpoint implementation](#application-interactions-version) |
| interactions_event_types? ^1^ | ?array[string] | The enabled [Gateway events](/gateway/gateway-events) to send to the interaction endpoint |
| event_webhooks_status? | integer | Whether [event webhooks are enabled](#event-webhooks-status) |
| event_webhooks_url? | string | The URL of the application's event webhooks endpoint |
| event_webhooks_types? | array[string] | The enabled [event webhook types](#event-webhooks-type) to send to the event webhooks endpoint |
| explicit_content_filter? | integer | [Whether uploaded media content](#explicit-content-filter-level) used in application commands is scanned and detected for explicit content |
| tags? | ?array[string] | Tags describing the content and functionality of the application (max 20 characters, max 5) |
| install_params? | ?[application install params](#application-install-params-object) object | The default in-app authorization link for the integration |
| custom_install_url? | ?string | The default custom authorization link for the integration |
| integration_types_config? | map[integer, ?[application integration type configuration](#application-integration-type-configuration-structure) object] | The configuration for each [integration type](#application-integration-type) supported by the application |
| connection_entrypoint_url? | string | The URL which users will be directed to when connecting their account in the application to their Discord account |
| discoverability_state? | integer | The current [application directory discoverability state](#application-discoverability-state) of the application (only `NOT_DISCOVERABLE` and `DISCOVERABLE` is supported) |
| monetization_state? | integer | The current [application monetization state](#application-monetization-state) of the application (only `NONE` and `ENABLED` is supported) |
| max_participants? | ?integer | The maximum possible participants in the application's embedded activity (-1 for no limit) |
^1^ The sending of Gateway events over the interactions endpoint requires [interactions version 2](#application-interactions-version).
Modify Current Application
Modifies the requestor's application information. Returns the updated [application](#application-object) object on success.
This endpoint is not usable by user accounts.
###### JSON Params
| Field | Type | Description |
| ---------------------------------- | ------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| description? | ?string | The description of the application |
| icon? | ?[image data](/reference#cdn-data) | The application's icon |
| cover_image? | ?[image data](/reference#cdn-data) | The application's default rich presence invite cover image |
| flags? | integer | The [application's flags](#application-flags) (only `GATEWAY_GUILD_MEMBERS_LIMITED`, `GATEWAY_PRESENCE_LIMITED`, and `GATEWAY_MESSAGE_CONTENT_LIMITED` can be set) |
| rpc_origins? | ?array[string] | The whitelisted RPC origin URLs for the application, if RPC is enabled |
| deeplink_uri? | ?string | The URL used for deep linking during [OAuth2 authorization](/topics/oauth2) on mobile devices |
| role_connections_verification_url? | ?string | The role connection verification entry point of the integration; when configured, this will render the application as a verification method in guild role verification configuration |
| interactions_endpoint_url? | ?string | The URL of the application's [interactions endpoint](/interactions/receiving-and-responding#receiving-an-interaction) |
| interactions_version? | integer | The [version of the application's interactions endpoint implementation](#application-interactions-version) |
| interactions_event_types? ^1^ | ?array[string] | The enabled [Gateway events](/gateway/gateway-events) to send to the interaction endpoint |
| explicit_content_filter? | integer | [Whether uploaded media content](#explicit-content-filter-level) used in application commands is scanned and detected for explicit content |
| tags? | ?array[string] | Tags describing the content and functionality of the application (max 20 characters, max 5) |
| install_params? | ?[application install params](#application-install-params-object) object | The default in-app authorization link for the integration |
| custom_install_url? | ?string | The default custom authorization link for the integration |
| integration_types_config? | map[integer, ?[application integration type configuration](#application-integration-type-configuration-structure) object] | The configuration for each [integration type](#application-integration-type) supported by the application |
| connection_entrypoint_url? | string | The URL which users will be directed to when connecting their account in the application to their Discord account |
| max_participants? | ?integer | The maximum possible participants in the application's embedded activity (-1 for no limit) |
Delete Application
Deletes an application permanently. User must be the owner of the application or owning team. Returns a 204 empty response on success.
Transfer Application
Transfers ownership of an application to a [team](/resources/team). User must be the owner of the application or owning team. Returns an [application](#application-object) object on success.
###### JSON Params
| Field | Type | Description |
| ------- | --------- | ------------------------------------------- |
| team_id | snowflake | The ID of the team to transfer ownership to |
Reset Application Secret
Resets the application's client secret. This revokes all previous secrets and returns a new secret. User must be the owner of the application or developer of the owning team.
###### Response Body
| Field | Type | Description |
| ------ | ------ | ---------------------------------------- |
| secret | string | The client secret key of the application |
###### Example Response
```json
{
"secret": "937it3ow87i4ery69876wqire"
}
```
List Application Testers
Returns a list of [whitelisted user](#whitelisted-user-structure) objects representing the invited testers for the given application ID. User must be the owner of the application or member of the owning team.
###### Whitelisted User Structure
| Field | Type | Description |
| ----- | -------------------------------------------------- | ------------------------------------------------------------------ |
| user | partial [user](/resources/user#user-object) object | The user that is whitelisted for the application |
| state | integer | The [state of the whitelisted user](#application-membership-state) |
###### Application Membership State
| Value | Name | Description |
| ----- | -------- | -------------------------------------------------------------------------- |
| 1 | INVITED | The user has been invited to the application but has not yet accepted |
| 2 | ACCEPTED | The user has accepted the invitation to the application and is whitelisted |
Add Application Tester
Adds a user to the application's list of testers. User must be the owner of the application or developer of the owning team. Returns a [whitelisted user](#whitelisted-user-structure) object on success.
You must be friends with the user you are inviting.
Applications may have a maximum of 50 whitelisted users.
###### JSON Params
| Field | Type | Description |
| ------------------ | ------- | ------------------------------------ |
| username | string | The username of the user to add |
| discriminator? ^1^ | ?string | The discriminator of the user to add |
^1^ Not applicable for migrated users. See the [section on Discord's new username system](/resources/user#unique-usernames) for more information.
Accept Application Tester Invitation
Accepts an application tester invitation received via email. Invited users will receive an email with a link that redirects to the official Discord client with a verification token present in the URL's query (e.g. `https://discord.com/oauth2/allowlist/accept?token=h9sYyrafnMhhObX4nGi9VOugCa9CSt`). Returns a 204 empty response on success.
###### Query String Params
| Field | Type | Description |
| ----- | ------ | ----------------------------------- |
| token | string | The verification token from the URL |
Remove Application Tester
Removes a user from the application's list of testers. User must be the owner of the application or developer of the owning team. Returns a 204 empty response on success.
Create Application Bot
Creates and attaches a bot to the given application ID. User must be the owner of the application or developer of the owning team.
All newly-created applications have a bot attached by default, so this endpoint is only useful for older applications.
###### Response Body
| Field | Type | Description |
| ----- | ------- | ------------------------------------------------ |
| token | ?string | The token of the bot, if a bot was newly created |
###### Example Response
```json
{
"token": "NzIyNDUwMzAzOTE5NTg3NDA5.GRj2Bt.cPbrvvjxglZXK4dTcIPDMvfq0LxJcilsIYW01A"
}
```
Modify Application Bot
Modifies the application's bot. User must be the owner of the application or developer of the owning team. Returns the updated [user](/resources/user#user-object) object on success.
###### JSON Params
| Field | Type | Description |
| --------- | ---------------------------------- | ------------------------------------- |
| username? | string | The user's username (2-32 characters) |
| avatar? | ?[image data](/reference#cdn-data) | The user's avatar |
| banner? | ?[image data](/reference#cdn-data) | The user's banner |
Reset Application Bot Token
Resets the application's bot token. This revokes all previous tokens and returns a new token. User must be the owner of the application or developer of the owning team.
###### Response Body
| Field | Type | Description |
| ----- | ------ | -------------------- |
| token | string | The token of the bot |
Request Application Gateway Intents
Submits a request for Gateway intents for a verified bot. User must be the owner of the application or developer of the owning team. Returns a 204 empty response on success.
###### JSON Params
| Field | Type | Description |
| ------------------------------------------------------------------------------- | -------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| application_description | string | The description of the application (50-2000 characters) |
| intents_flags_requested? | integer | The [application flags](#application-flags) representing the requested Gateway intents (only `GATEWAY_PRESENCE`, `GATEWAY_GUILD_MEMBERS`, and `GATEWAY_MESSAGE_CONTENT` are supported) |
| intents_gateway_presence_use_case_description? ^1^ | ?string | The use case for requesting the presence intent (50-2000 characters) |
| intents_gateway_presence_use_case_supplemental_material_description? ^1^ | ?string | The supplemental material for the requested Gateway presence intent (5-2000 characters) |
| intents_gateway_presence_store_off_platform? ^1^ | ?boolean | Whether the application stores presence data off-platform |
| intents_gateway_presence_retention? | ?boolean | Whether the application retains presence data for 30 days or less |
| intents_gateway_presence_encrypted? | ?boolean | Whether the application encrypts stored presence data at rest |
| intents_gateway_presence_opt_out_stored? | ?boolean | Whether application users can opt out of having their presence data stored |
| intents_gateway_presence_contact_deletion? ^1^ | ?string | How application users can request the deletion of their presence data (25-2000 characters) |
| intents_gateway_guild_members_use_case_description? ^1^ | ?string | The use case for requesting the guild members intent (50-2000 characters) |
| intents_gateway_guild_members_use_case_supplemental_material_description? ^1^ | ?string | The supplemental material for the requested Gateway guild members intent (5-2000 characters) |
| intents_gateway_guild_members_store_off_platform? ^1^ | ?boolean | Whether the application stores guild member data off-platform |
| intents_gateway_guild_members_retention? | ?boolean | Whether the application retains guild member datafor 30 days or less |
| intents_gateway_guild_members_encrypted? | ?boolean | Whether the application encrypts stored guild member data at rest |
| intents_gateway_guild_members_contact_deletion? | ?string | How application users can request the deletion of their guild member data (25-2000 characters) |
| intents_gateway_message_content_use_case_description? ^1^ | ?string | The use case for requesting the message content intent (50-2000 characters) |
| intents_gateway_message_content_use_case_supplemental_material_description? ^1^ | ?string | The supplemental material for the requested Gateway message content intent (5-2000 characters) |
| intents_gateway_message_content_store_off_platform? ^1^ | ?boolean | Whether the application stores message content data off-platform |
| intents_gateway_message_content_retention? | ?boolean | Whether the application retains message content data for 30 days or less |
| intents_gateway_message_content_encrypted? | ?boolean | Whether the application encrypts stored message content data at rest |
| intents_gateway_message_content_opt_out_stored? | ?boolean | Whether application users can opt out of having their message content data stored |
| intents_gateway_message_content_ai_training? | ?boolean | Whether the application uses message content data for AI training |
| intents_gateway_message_content_privacy_policy_public? | ?boolean | Whether the application has a public privacy policy detailing how message content data is used |
| intents_gateway_message_content_privacy_policy_location? | ?string | Where the application's privacy policy can be found (25-2000 characters) |
| intents_gateway_message_content_privacy_policy_example? | ?string | A link to or screenshots of the application's privacy policy (25-2000 characters) |
| intents_gateway_message_content_contact_deletion? | ?string | How application users can request the deletion of their message content data (25-2000 characters) |
^1^ Required if the corresponding intent is requested.
Get Application Discoverability State
Returns information about the application's eligibility for application directory. User must be the owner of the application or member of the owning team.
###### Response Body
| Field | Type | Description |
| --------------------------- | -------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------- |
| discoverability_state | integer | The current application directory [discoverability state](#application-discoverability-state) of the application |
| discovery_eligibility_flags | integer | The current application directory [eligibility flags](#application-discovery-eligibility-flags) for the application |
| bad_commands | array[[application command](/interactions/application-commands#application-command-object) object] | Not safe for work commands that are not allowed in the application directory |
Query Application Test Mode
Queries whether the user can use test mode for the application. Test mode allows completing purchases without payment. User must be the owner of the application or developer of the owning team. Returns a 204 empty response on success.
List Embedded Activities
Returns the embedded activities available globally or in a particular guild.
###### Query String Params
| Field | Type | Description |
| --------- | --------- | ---------------------------------------- |
| guild_id? | snowflake | The ID to return embedded activities for |
###### Response Body
| Field | Type | Description |
| ------------ | -------------------------------------------------------------------------- | ----------------------------------------------------------- |
| activities | array[[embedded activity config](#embedded-activity-config-object) object] | The available embedded activities |
| applications | array[partial [application](#application-object) object] | Applications representing the available embedded activities |
| assets | map[snowflake, array[[application asset](#application-asset-object)]] | The assets for each application |
Set Application Embeddability
Modifies whether the application is an embedded activity or not (determined by the [`EMBEDDED` flag](#application-flags)). User must be the owner of the application or developer of the owning team. Returns a 204 empty response on success.
###### JSON Params
| Field | Type | Description |
| -------- | ------- | ----------------------------------- |
| embedded | boolean | Whether the application is embedded |
Get Embedded Activity Config
Returns the [embedded activity config](#embedded-activity-config-object) object for the given application ID. User must be the owner of the application or member of the owning team.
Modify Embedded Activity Config
Modifies the embedded activity config for the given application ID. User must be the owner of the application or developer of the owning team. Returns the updated [embedded activity config](#embedded-activity-config-object) object on success.
###### JSON Params
| Field | Type | Description |
| --------------------------------------- | ----------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------- |
| activity_preview_video_asset_id? | ?snowflake | The ID of the application asset to preview the activity with |
| supported_platforms? | ?array[string] | The [platforms this activity is supported on](#embedded-activity-platform-type) |
| default_orientation_lock_state? | integer | The default [orientation lock state](#embedded-activity-orientation-lock-state-type) for the activity on mobile |
| tablet_default_orientation_lock_state? | integer | The default [orientation lock state](#embedded-activity-orientation-lock-state-type) for the activity on tablets |
| requires_age_gate? | boolean | Whether the activity is age gated |
| free_period_starts_at? **(deprecated)** | ?ISO8601 timestamp | When the current free period for the activity starts, if any |
| free_period_ends_at? **(deprecated)** | ?ISO8601 timestamp | When the current free period for the activity ends, if any |
| client_platform_config? | map[string, [embedded activity platform config](#embedded-activity-platform-config-structure) object] | The release configuration for the activity on each [platform](#embedded-activity-platform-type) |
| shelf_rank? | integer | The rank of the activity in the activity shelf sort order |
List Embedded Activity Instances
Returns the currently active activity instances in a channel for the application. Useful for preventing unwanted activity sessions.
This endpoint is not usable by user accounts.
This endpoint is deprecated. It is replaced by [Get Embedded Activity Instance](#get-embedded-activity-instance).
###### Response Body
| Field | Type | Description |
| --------- | ------------------------------------------------------------------------------- | ---------------------------------------------- |
| instances | array[[channel activity instance](#channel-activity-instance-structure) object] | The embedded activity instances in the channel |
###### Channel Activity Instance Structure
| Field | Type | Description |
| -------------- | ---------------- | --------------------------------------------------------------------------- |
| application_id | snowflake | The ID of the application |
| instance_id | string | The [composite ID](#embedded-activity-instance-id) of the activity instance |
| channel_id | snowflake | The ID of the channel the activity is running in |
| guild_id? | snowflake | The ID of the guild the activity is running in |
| users | array[snowflake] | The IDs of the users participating in the activity |
Get Embedded Activity Instance
Returns an active activity instance for the application. Useful for preventing unwanted activity sessions.
This endpoint is not usable by user accounts.
###### Response Body
| Field | Type | Description |
| -------------- | -------------------------------------------------------------------------- | --------------------------------------------------------------------------- |
| application_id | snowflake | The ID of the application |
| instance_id | string | The [composite ID](#embedded-activity-instance-id) of the activity instance |
| launch_id | string | The ID of the activity instance |
| location | [embedded activity location](#embedded-activity-location-structure) object | The location the activity instance is running in |
| users | array[snowflake] | The IDs of the users participating in the activity |
Launch Embedded Activity
Launches an embedded activity in a channel. Joins an existing activity instance if one exists, otherwise creates a new instance.
Requires the `USE_EMBEDDED_ACTIVITIES` permission, as well as the `USE_EXTERNAL_APPS` permission if the activity application is not authorized to the guild. Returns a 204 empty response on success.
When possible, this should instead be done [creating an interaction](/interactions/receiving-and-responding#create-interaction) with an [Entry Point command](/interactions/application-commands#entry-point-commands).
An accompanying application command invocation will be sent to the channel if the user has the `USE_APPLICATION_COMMANDS` permission.
###### JSON Params
| Field | Type | Description |
| ---------- | ------ | ------------------------------------------------- |
| session_id | string | The session ID of the user launching the activity |
Leave Embedded Activity Instance
Leaves an embedded activity instance. Returns an empty object on success.
###### JSON Params
| Field | Type | Description |
| ---------- | ------ | ----------------------------------------------- |
| session_id | string | The session ID of the user leaving the activity |
Get Application Proxy Config
Returns the application's [activity proxy config](#application-proxy-config-object) object for the given application ID. User must be the owner of the application or member of the owning team.
Modify Application Proxy Config
Replaces the activity proxy config for the given application ID. User must be the owner of the application or developer of the owning team. Returns the updated [application proxy config](#application-proxy-config-object) object on success.
Notes:
- URL mappings can utilize any protocol, so the protocol should be omitted from the `target` field.
- Parameter matching is supported in both the `prefix` and `target` fields. For example, you can map `/server/{id}` to `server-{id}.example.com`.
- Because of how URL globbing works, the order of the mappings is important. The most specific mappings should be at the top of the list as the first match is used. For example, if you have `/foo` and `/foo/bar`, you must place the URL `/foo/bar` before `/foo` or else the mapping for `/foo/bar` will never be reached.
###### JSON Params
| Field | Type | Description |
| ------- | ------------------------------------------------------------------------------- | ---------------------------- |
| url_map | array[[application proxy mapping](#application-proxy-mapping-structure) object] | The URLs mapped to the proxy |
List OAuth2 Application Assets
Returns a list of [application assets](#application-asset-object) for the given application ID.
###### Query String Params
| Field | Type | Description |
| -------- | ------- | -------------------------------------------------------- |
| nocache? | boolean | Whether to bypass cache for the response (default false) |
Create OAuth2 Application Asset
Creates a new application asset for the given application ID. User must be the owner of the application or developer of the owning team. Returns an [application asset](#application-asset-object) object on success.
Due to caching, it may take a while for the asset to be retrievable after creation.
###### JSON Params
| Field | Type | Description |
| ----- | --------------------------------- | ------------------------------------------------ |
| name | string | The name of the asset |
| type | integer | The [type of the asset](#application-asset-type) |
| image | [image data](/reference#cdn-data) | The asset's image |
Delete OAuth2 Application Asset
Deletes an application asset permanently. User must be the owner of the application or developer of the owning team. Returns a 204 empty response on success.
Proxy Application Assets
Proxies a list of URLs for the given application ID. Returns a list of [external asset](#external-asset-structure) objects on success.
###### JSON Params
| Field | Type | Description |
| ----- | ------------- | --------------------------------------------------------- |
| urls | array[string] | The URLs of the assets to proxy (max 256 characters, 1-2) |
###### External Asset Structure
| Field | Type | Description |
| ------------------- | ------ | -------------------------------------------------------------------------- |
| url | string | The URL of the asset |
| external_asset_path | string | The path to the asset on the media proxy (`https://media.discordapp.net/`) |
###### Example External Asset
```json
[
{
"url": "https://google.com/favicon.ico",
"external_asset_path": "external/OCZzr1eoglei1yFsfSMClt6B95EI9W-dOhq7fbnn5aY/https/google.com/favicon.ico"
}
]
```
Get Application Assets
Returns a list of [application assets](#application-asset-object) for the given application ID. User must be the owner of the application or developer of the owning team.
Upload Application Asset
Creates attachment URLs to upload the intended attachments directly to Discord's GCP storage bucket. Returns an array of [cloud attachment](/topics/cloud-uploads#cloud-attachment-object) objects. See [Cloud Uploads](/topics/cloud-uploads) topic for more information.
###### JSON Params
| Field | Type | Description |
| --------- | ------- | -------------------------------------------- |
| filename | string | The name of the file being uploaded |
| file_size | integer | The size of the file being uploaded in bytes |
Create Application Asset
Creates an application asset. User must be the owner of the application or developer of the owning team. Returns the created [application asset](#application-asset-object) on success.
###### JSON Params
| Field | Type | Description |
| ----------------- | ------- | -------------------------------------------------------- |
| key | string | The name of the file being uploaded |
| uploaded_filename | integer | The size of the file being uploaded in bytes |
| visibility? | ?string | The [visibility](#application-asset-object) of the asset |
Update Application Asset
Updates an application asset. User must be the owner of the application or developer of the owning team.Returns the updated [application asset](#application-asset-object) on success.
###### JSON Params
| Field | Type | Description |
| ------------------ | ------- | --------------------------------------------------------- |
| uploaded_filename? | string | The name of the file pre-uploaded to Discord's GCP bucket |
| visibility? | ?string | The [visibility](#application-asset-object) of the asset |
Delete Application Asset
Deletes an application asset. User must be the owner of the application or developer of the owning team. Returns a 204 empty response on success.
Create Application Attachment
Uploads an ephemeral attachment to the application. Must be a `multipart/form-data` body. Requires the [`EMBEDDED` application flag](#application-flags).
###### Form Params
| Field | Type | Description |
| ----- | ------------- | ---------------------------------------------------------- |
| file | file contents | The image file to upload, must be a JPEG, PNG, or GIF file |
###### Response Body
| Field | Type | Description |
| ---------- | --------------------------------------------------------- | -------------------------------- |
| attachment | [attachment](/resources/message#attachment-object) object | The created ephemeral attachment |
Get Partial Application
Returns a partial [application](#application-object) object for the given ID with all public application fields.
###### Query String Params
| Field | Type | Description |
| ----------- | ------- | ------------------------------------------------------------------------------------------------ |
| with_guild? | boolean | Whether to include the guild object in the response if the guild is discoverable (default false) |
List Partial Applications
Returns a list of partial [application](#application-object) objects for the given IDs.
###### Query String Params
| Field | Type | Description |
| --------------- | ---------------- | ------------------------------------------------------------- |
| application_ids | array[snowflake] | The IDs of the applications to fetch; unknown IDs are ignored |
Get RPC Application
Returns a partial [application](#application-object) object for the given ID with RPC-related fields.
List Application Disclosures
Returns an object representing additional safety disclosures for the application.
###### Response Body
| Field | Type | Description |
| ----------------- | -------------- | --------------------------------------------------------------------------------------- |
| disclosures | array[integer] | The [disclosures](#application-disclosure-type) of the application |
| acked_disclosures | array[integer] | The [disclosures](#application-disclosure-type) that have been acknowledged by the user |
| all_acked | boolean | Whether all disclosures have been acknowledged by the user |
###### Application Disclosure Type
| Value | Name | Description |
| ----- | -------------------------------- | ------------------------------------------------------------------------------------------------------------ |
| 0 | UNSPECIFIED_DISCLOSURE | Unspecified disclosure |
| 1 | IP_LOCATION | Application may access the user's IP address |
| 2 | DISPLAYS_ADVERTISEMENTS | Application may display advertisements |
| 3 | PARTNER_SDK_DATA_SHARING_MESSAGE | Application's game uses the social layer SDK's messaging features, which surface in-game messages on Discord |
###### Example Response
```json
{
"disclosures": [1, 2],
"acked_disclosures": [1, 2],
"all_acked": true
}
```
Acknowledge Application Disclosures
Acknowledges a list of disclosures for the application.
###### JSON Params
| Field | Type | Description |
| ----------- | -------------- | --------------------------------------------------------------------------- |
| disclosures | array[integer] | The [disclosures](#application-disclosure-type) to acknowledge for the user |
###### Response Body
| Field | Type | Description |
| ----------- | -------------- | --------------------------------------------------------------------------------------- |
| disclosures | array[integer] | The [disclosures](#application-disclosure-type) that have been acknowledged by the user |
List Guild Applications
Returns a list of [application](#application-object) objects attached to the given guild ID. Requires the `MANAGE_GUILD` permission.
An application is considered attached to a guild if the [application's `guild_id` field](#application-object) is set to the guild's ID.
###### Query String Params
| Field | Type | Description |
| ----------------- | --------- | -------------------------------------------------------------------------- |
| type? | integer | The [type of applications](#application-type) to return |
| include_team? ^1^ | boolean | Whether to include team information for owned applications (default false) |
| channel_id? | snowflake | The ID of the channel to filter by (TODO: what the fuck does this do) |
^1^ You must own the application or be a member of the owning team to receive this information.
Report Unverified Application
Reports a game not detected and tracked to Discord. Returns an unverified application object on success.
###### JSON Params
| Field | Type | Description |
| ------------------------ | -------------------------------------------------------------------- | --------------------------------------------------------------------- |
| report_version? | integer | The version of the report (currently 3) |
| name | string | The name of the application (2-100 characters) |
| icon | string | The MD5 hash of the application's icon (32 characters) |
| os | string | The [operating system](#operating-system) the application is found on |
| executable? | string | The executable of the application (max 1024 characters) |
| publisher? | string | The publisher of the application (2-100 characters) |
| distributor_application? | [application distributor](#application-distributor-structure) object | The distributor of the application SKU |
###### Application Distributor Structure
| Field | Type | Description |
| ----------- | ------ | --------------------------------------------------------------- |
| distributor | string | The [application distributor](/resources/game#distributor-type) |
| sku? | string | The SKU of the application (max 256 characters) |
###### Operating System
| Value | Description |
| ------ | ----------- |
| win32 | Windows |
| darwin | macOS |
| linux | Linux |
###### Response Body
| Field | Type | Description |
| ------------ | ------------- | ---------------------------------------------------------------------- |
| name | string | The name of the application |
| hash | string | The unique hash of the application |
| missing_data | array[string] | The [missing data](#application-missing-data-type) for the application |
###### Application Missing Data Type
| Value | Description |
| ----- | ------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| icon | The application's icon hash is not found and should be uploaded using the [Upload Unverified Application Icon](#upload-unverified-application-icon) endpoint |
###### Example Response
```json
{
"name": "Alien Simulator",
"hash": "0312ce2c94e1fa8257fefbade4587fb3",
"missing_data": ["icon"]
}
```
Upload Unverified Application Icon
Uploads an unverified application's icon to Discord. Returns a 204 empty response on success.
###### JSON Params
| Field | Type | Description |
| ---------------- | --------------------------------- | ---------------------------------- |
| application_name | string | The name of the application |
| application_hash | string | The unique hash of the application |
| icon | [image data](/reference#cdn-data) | The application's icon |
List User Application Role Connections
Returns a list of [application role connection](#application-role-connection-object) objects for the user.
Get User Application Role Connection
Returns an [application role connection](#application-role-connection-object) object for the user, without optional fields.
This endpoint is only usable with an OAuth2 access token with the `role_connections.write` scope for the application specified in the path.
Modify User Application Role Connection
Replaces an application's role connection for the user. Returns the updated [application role connection](#application-role-connection-object) object on success.
This endpoint is only usable with an OAuth2 access token with the `role_connections.write` scope for the application specified in the path.
All parameters to this endpoint are optional and nullable. Omitting or setting a `null` value will set it to default.
###### JSON Params
| Field | Type | Description |
| ------------------ | ------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| platform_name? | string | The vanity name of the platform a bot has connected (max 50 characters) |
| platform_username? | string | The username on the platform a bot has connected (max 100 characters) |
| metadata? | map[string, string] | Object mapping [application role connection metadata](#application-role-connection-metadata-object) keys to their `string`-ified value (max 100 characters) for the user on the platform a bot has connected |
List Application Managed Links
Returns a list of [activity link](#activity-link-object) objects for the given application ID. User must be the owner of the application or developer of the owning team.
Create Application Managed Link
Creates a new activity managed link. User must be the owner of the application or developer of the owning team. Returns an [activity link](#activity-link-object) object on success.
###### JSON Params
| Field | Type | Description |
| ----------- | --------------------------------- | ------------------------------------------------------ |
| custom_id? | ?string | A custom id for the activity link (1-256 characters) |
| description | string | The description of the activity link (1-64 characters) |
| image | [image data](/reference#cdn-data) | The activity link asset |
| title | string | The title of the activity link (1-32 characters) |
Get Application Managed Link
Returns an [activity link](#activity-link-object) object for the given ID.
Update Application Managed Link
Updates the specified activity link for the given application ID. User must be the owner of the application or developer of the owning team. Returns an [activity link](#activity-link-object) object on success.
Delete Application Managed Link
Deletes the specified activity link for the given application ID. User must be the owner of the application or developer of the owning team. Returns a 204 empty response on success.
Create Application Quick Link
Creates a new activity quick link. Returns an [activity link](#activity-link-object) object on success.
When using OAuth2, quick links can be only created for the application that the access token belongs to.
###### JSON Params
| Field | Type | Description |
| ----------- | --------------------------------- | ------------------------------------------------------ |
| custom_id? | ?string | A custom id for the activity link (1-256 characters) |
| description | string | The description of the activity link (1-64 characters) |
| image | [image data](/reference#cdn-data) | The activity link asset |
| title | string | The title of the activity link (1-32 characters) |
Get Application Quick Link
Returns an [activity link](#activity-link-object) object for the given ID.
Get Application Verification Eligibility
Checks if an application is eligible to apply for verification. Returns an empty 204 response on success.
This endpoint is deprecated. Applications now verify using the [automated verification process](#verify-application).
Verify Application
Verifies an application and allows it to scale past 100 servers. Returns a 204 empty response on success. User must be the owner of the owning team.
The application must meet the following criteria to be eligible for verification:
- It must belong to a team
- It must not contain any harmful or bad language in its name, description, commands or role connection metadata
- It must have links to its Terms of Service and Privacy Policy
- It must have an install link
- All its team members must have a verified email and MFA set up, with the team owner additionally having to undergo identity verification
List Social SDK Releases
Returns the currently available social SDK releases.
###### Response Body
| Field | Type | Description |
| -------------- | -------------------------------------------------------------- | ----------------------------- |
| releases | array[[social SDK release](#social-sdk-release-object) object] | The SDK releases |
| latest_version | string | The latest version of the SDK |
Get Social SDK Release
Returns a [social SDK release](#social-sdk-release-object) object for the given version.
Enable Social SDK
Enables social SDK features for the given application, applying the [`SOCIAL_LAYER_INTEGRATION_LIMITED` application flag](#application-flags). Returns a 204 empty response on success.
###### JSON Params
| Field | Type | Description |
| ---------------------- | ------- | -------------------------------------------------------------- |
| name | string | The name of the company (1-100 characters) |
| business_email | string | The company business email (max 320 characters) |
| game_or_studio_name? | string | The name of the company (max 100 characters) |
| game_or_studio_url? | string | The URL of the company (max 512 characters) |
| email_updates_consent? | boolean | Whether to receive emails about the social SDK (default false) |
List Application External Identity Provider Configurations
Returns a list of [application external identity provider configuration](#application-external-identity-provider-configuration-structure) objects for the given application.
Create Application External Identity Provider Configuration
Creates or updates a configuration for the given external identity provider type.
###### JSON Params
| Field | Type | Description |
| --------------- | ----------------------------------------------------------------------------------------------------------------------- | -------------------------------------------- |
| clients | array[[application external identity provider client](#application-external-identity-provider-client-structure) object] | The provider clients |
| oidc_issuer_url | ?string | The primary URL of the OpenID Connect Issuer |
Remove Application External Identity Provider Configuration
Removes the given external identity provider. Returns a 204 empty response on success.
Get Application Undeletable Reason
Returns a reason for why an application cannot be deleted.
###### Response Body
| Field | Type | Description |
| ---------- | -------- | ----------------------------------------------------------------------------------- |
| deletable? | ?boolean | Whether the application is deletable (default false) |
| reason? | ?integer | The [reason](#application-undeletable-reason) why the application cannot be deleted |
---
# Store
Link: https://docs.discord.food/resources/store
Discord store resources have a long and convoluted history.
The store was originally built to support game developers selling games and in-game items on Discord, as well as GameSDK features.
While this was deprecated soon after, the store infrastructure remained in place, fully functional.
It was then used internally to power the Discord Nitro subscription service, as well as other ventures such as the now-defunct paid sticker packs.
Now, it has been repurposed to support guild and application monetization features, such as guild products and application subscriptions.
As Discord has returned to gaming with the release of the Social SDK, it is now again being used to support sales of in-game items.
While the store infrastructure is still in use, most of the new features being built with it offer newer APIs to manage and interact with them.
Certain new features may require using these new APIs to function properly, and may not be fully compatible with the older store APIs, even though
they are using [SKUs](#sku-object) and [store listings](#store-listing-object) under the hood.
### SKU Object
A purchasable item or group of items in Discord.
###### SKU Structure
SKU objects can either be localized or unlocalized. Localized SKUs only serialize strings and pricing for the user's location, while unlocalized SKUs serialize all strings and pricing for all locales.
All objects serialized in the SKU inherit this behavior.
| Field | Type | Description |
| ----------------------------------------- | ------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------- |
| id | snowflake | The ID of the SKU |
| type | integer | The [type of SKU](#sku-type) |
| application_id | snowflake | The ID of the application the SKU belongs to |
| application? | partial [application](/resources/application#application-object) | The application the SKU belongs to |
| product_line | ?integer | The [product line](#sku-product-line) the SKU belongs to |
| product_id? | snowflake | The ID of the storefront product the SKU is for |
| flags | integer | The [SKU flags](#sku-flags) |
| name | [localized string](/reference#localized-string) | The name of the SKU |
| summary? | [localized string](/reference#localized-string) | The summary of the SKU |
| description? | [localized string](/reference#localized-string) | The description of the SKU |
| legal_notice? | [localized string](/reference#localized-string) | The legal notice for the SKU |
| slug | string | The URL slug of the SKU |
| thumbnail_asset_id? | snowflake | The ID of the store asset for the SKU's thumbnail |
| dependent_sku_id? | ?snowflake | The ID of the prerequisite required to buy this SKU |
| bundled_skus? | array[[SKU](#sku-object) object] | The SKUs that are included when purchasing this SKU |
| bundled_sku_ids? | array[snowflake] | The IDs of the SKUs that are included when purchasing this SKU |
| access_type | integer | The [access level](#sku-access-type) of the SKU |
| manifest_labels? | ?array[snowflake] | The IDs of the manifest labels associated with the SKU |
| features | array[integer] | The [features](#sku-feature) of the SKU |
| locales? | array[string] | The [locales](/reference#locales) the SKU is available in (default `en-US`) |
| genres? | array[integer] | The [genres](#sku-genre) of the SKU |
| available_regions? | array[string] | The [ISO 3166-1 alpha-2](https://en.wikipedia.org/wiki/ISO_3166-1_alpha-2) country codes where the SKU is available |
| content_rating? ^1^ | [content rating](#content-rating-structure) object | The content rating of the SKU |
| content_rating_agency? ^1^ | integer | The [agency](#content-rating-agency) that assigned the content rating |
| content_ratings? ^2^ | map[integer, [content rating](#content-rating-structure) object] | The content ratings of the SKU per [agency](#content-rating-agency) |
| system_requirements? | map[integer, [system requirements](#system-requirements-structure) object] | The system requirements for each [operating system](#operating-system) the SKU supports |
| price? ^1^ | [SKU price](#sku-price-structure) object | The price of the SKU |
| price_tier? ^2^ | integer | The [base price](#list-store-price-tiers) of the SKU |
| price? ^2^ | map[string, integer] | Localized pricing overrides per lower-cased [ISO 4217](https://en.wikipedia.org/wiki/ISO_4217) currency code |
| sale_price_tier? ^2^ | integer | The [sale price](#list-store-price-tiers) of the SKU |
| sale_price? ^2^ | map[string, integer] | Localized sale pricing overrides per lower-cased [ISO 4217](https://en.wikipedia.org/wiki/ISO_4217) currency code |
| created_at ^3^ | ISO8601 datetime | When the SKU was created |
| updated_at ^3^ | ISO8601 datetime | When the SKU was last updated |
| release_date? | ISO8601 date | When the SKU will be released |
| preorder_approximate_release_date? | string | When the developer has indicated the SKU will be released for preorders |
| preorder_released_at? | ISO8601 datetime | When the SKU was released for preorders |
| external_purchase_url? | string | An external URL to purchase the SKU |
| external_sku_strategies? **(deprecated)** | map[integer, [external SKU strategy](#external-sku-strategy-structure) object] | Sale strategies per [payment gateway](/resources/billing#payment-gateway) supported |
| eligible_payment_gateways? | array[integer] | The [payment gateways](/resources/billing#payment-gateway) the SKU can be purchased with |
| premium | boolean | Whether the SKU is a premium user perk |
| show_age_gate | boolean | Whether to show an age gate when purchasing the SKU |
| restricted? ^1^ | boolean | Whether the SKU is restricted in the user's region |
| exclusive? | boolean | Whether the SKU is exclusively available on Discord |
| deleted? | boolean | Whether the SKU has been soft-deleted |
| tenant_metadata? | [tenant metadata](#tenant-metadata-structure) object | Tenant metadata for the SKU |
| powerup_metadata? | [guild powerup metadata](#guild-powerup-metadata-structure) object | Guild powerup metadata for the SKU |
| orbs_reward? | integer | The amount of Orbs the SKU grants |
^1^ Only included for localized SKUs.
^2^ Only included for unlocalized SKUs.
^3^ Values have only been tracked since `2025-08-05T20:53:39.133830+00:00`. Earlier SKUs will have this field set to this timestamp. See the [snowflake format documentation](/reference#snowflake-format) for a more accurate creation timestamp.
###### SKU Type
| Value | Name | Description |
| ----- | ------------------ | --------------------------- |
| 1 | DURABLE_PRIMARY | Primary durable item |
| 2 | DURABLE | Durable item |
| 3 | CONSUMABLE | Consumable item |
| 4 | BUNDLE | Bundle of items |
| 5 | SUBSCRIPTION | Subscription item |
| 6 | SUBSCRIPTION_GROUP | Group of subscription items |
###### SKU Product Line
| Value | Name | Description |
| ----- | ---------------------- | ----------------------------------------- |
| 1 | PREMIUM | Premium (Nitro) subscription |
| 2 | PREMIUM_GUILD | Premium guild (boosting) subscription |
| 3 | ACTIVITY_IAP | Embedded activity in-app purchase |
| 4 | GUILD_ROLE | Guild role subscription or ticketed event |
| 5 | GUILD_PRODUCT | Guild product |
| 6 | APPLICATION | Application item |
| 7 | COLLECTIBLES | Discord collectible |
| 8 | TENURE_REWARD | Premium tenure reward |
| 9 | QUEST_IN_GAME_REWARD | In-game quest reward |
| 10 | QUEST_REWARD_CODE | Quest reward code |
| 11 | FRACTIONAL_PREMIUM | Fractional premium subscription |
| 12 | VIRTUAL_CURRENCY | Virtual currency (Orbs) |
| 13 | GUILD_POWERUP | Guild powerup |
| 14 | SOCIAL_LAYER_GAME_ITEM | Social SDK game item |
###### SKU Flags
| Value | Name | Description |
| --------- | ---------------------------------- | ------------------------------------------------------------------- |
| 1 \<\< 0 | PREMIUM_PURCHASE | SKU is available for free to premium users |
| 1 \<\< 1 | HAS_FREE_PREMIUM_CONTENT | SKU has free content for premium users |
| 1 \<\< 2 | AVAILABLE | SKU is available for purchase |
| 1 \<\< 3 | PREMIUM_AND_DISTRIBUTION | SKU is available for free to premium users and purchasable normally |
| 1 \<\< 4 | STICKER | SKU is a paid sticker pack |
| 1 \<\< 5 | GUILD_ROLE | SKU is a guild role subscription or ticketed event |
| 1 \<\< 6 | AVAILABLE_FOR_SUBSCRIPTION_GIFTING | SKU is a giftable Discord premium subscription |
| 1 \<\< 7 | APPLICATION_GUILD_SUBSCRIPTION | SKU is an application subscription for guilds |
| 1 \<\< 8 | APPLICATION_USER_SUBSCRIPTION | SKU is an application subscription for users |
| 1 \<\< 9 | CREATOR_MONETIZATION | SKU is a guild creator monetization product |
| 1 \<\< 10 | GUILD_PRODUCT | SKU is a guild product |
| 1 \<\< 11 | AVAILABLE_FOR_APPLICATION_GIFTING | SKU is a giftable application product |
###### SKU Access Type
| Value | Name | Description |
| ----- | -------------- | -------------------------------- |
| 1 | FULL | SKU is fully accessible |
| 2 | EARLY_ACCESS | SKU is in early access |
| ~~3~~ | ~~VIP_ACCESS~~ | ~~SKU has limited availability~~ |
###### SKU Feature
| Value | Name | Description |
| ----- | -------------------- | ------------------------------ |
| 1 | SINGLE_PLAYER | Single player game |
| 2 | ONLINE_MULTIPLAYER | Online multiplayer game |
| 3 | LOCAL_MULTIPLAYER | Local multiplayer game |
| 4 | PVP | Player versus player game |
| 5 | LOCAL_COOP | Local cooperative multiplayer |
| 6 | CROSS_PLATFORM | Cross-platform play supported |
| 7 | RICH_PRESENCE | Rich presence integration |
| 8 | DISCORD_GAME_INVITES | Discord game invites supported |
| 9 | SPECTATOR_MODE | Spectator mode supported |
| 10 | CONTROLLER_SUPPORT | Controller support |
| 11 | CLOUD_SAVES | Cloud saves supported |
| 12 | ONLINE_COOP | Online cooperative multiplayer |
| 13 | SECURE_NETWORKING | Secure networking supported |
###### SKU Genre
| Value | Name | Description |
| ----- | --------------------- | ------------------------------------------ |
| 1 | ACTION | Action |
| 2 | ACTION_RPG | Action RPG |
| 3 | BRAWLER | Brawler |
| 4 | HACK_AND_SLASH | Hack and Slash |
| 5 | PLATFORMER | Platformer |
| 6 | STEALTH | Stealth |
| 7 | SURVIVAL | Survival |
| 8 | ADVENTURE | Adventure |
| 9 | ACTION_ADVENTURE | Action Adventure |
| 10 | METROIDVANIA | Metroidvania |
| 11 | OPEN_WORLD | Open World |
| 12 | PSYCHOLOGICAL_HORROR | Psychological Horror |
| 13 | SANDBOX | Sandbox |
| 14 | SURVIVAL_HORROR | Survival Horror |
| 15 | VISUAL_NOVEL | Visual Novel |
| 16 | DRIVING_RACING | Driving / Racing |
| 17 | VEHICULAR_COMBAT | Vehicular Combat |
| 18 | MASSIVELY_MULTIPLAYER | Massively Multiplayer |
| 19 | MMORPG | MMORPG |
| 20 | ROLE_PLAYING | Role-Playing |
| 21 | DUNGEON_CRAWLER | Dungeon Crawler |
| 22 | ROGUELIKE | Roguelike |
| 23 | SHOOTER | Shooter |
| 24 | LIGHT_GUN | Light Gun |
| 25 | SHOOT_EM_UP | Shoot 'Em Up |
| 26 | FPS | First-Person Shooter |
| 27 | DUAL_JOYSTICK_SHOOTER | Dual-Joystick Shooter |
| 28 | SIMULATION | Simulation |
| 29 | FLIGHT_SIMULATOR | Flight Simulator |
| 30 | TRAIN_SIMULATOR | Train Simulator |
| 31 | LIFE_SIMULATOR | Life Simulator |
| 32 | FISHING | Fishing |
| 33 | SPORTS | Sports |
| 34 | BASEBALL | Baseball |
| 35 | BASKETBALL | Basketball |
| 36 | BILLIARDS | Billiards |
| 37 | BOWLING | Bowling |
| 38 | BOXING | Boxing |
| 39 | FOOTBALL | Football |
| 40 | GOLF | Golf |
| 41 | HOCKEY | Hockey |
| 42 | SKATEBOARDING_SKATING | Skateboarding / Skating |
| 43 | SNOWBOARDING_SKIING | Snowboarding / Skiing |
| 44 | SOCCER | Soccer |
| 45 | TRACK_FIELD | Track & Field |
| 46 | SURFING_WAKEBOARDING | Surfing / Wakeboarding |
| 47 | WRESTLING | Wrestling |
| 48 | STRATEGY | Strategy |
| 49 | FOUR_X | 4X (explore, expand, exploit, exterminate) |
| 50 | ARTILLERY | Artillery |
| 51 | RTS | Real-Time Strategy |
| 52 | TOWER_DEFENSE | Tower Defense |
| 53 | TURN_BASED_STRATEGY | Turn-Based Strategy |
| 54 | WARGAME | Wargame |
| 55 | MOBA | Multiplayer Online Battle Arena |
| 56 | FIGHTING | Fighting |
| 57 | PUZZLE | Puzzle |
| 58 | CARD_GAME | Card Game |
| 59 | EDUCATION | Education |
| 60 | FITNESS | Fitness |
| 61 | GAMBLING | Gambling |
| 62 | MUSIC_RHYTHM | Music / Rhythm |
| 63 | PARTY_MINI_GAME | Party / Mini Game |
| 64 | PINBALL | Pinball |
| 65 | TRIVIA_BOARD_GAME | Trivia / Board Game |
| 66 | TACTICAL | Tactical |
| 67 | INDIE | Indie |
| 68 | ARCADE | Arcade |
| 69 | POINT_AND_CLICK | Point-and-Click |
###### Content Rating Structure
| Field | Type | Description |
| ----------- | -------------- | ------------------------------------------------- |
| rating | integer | The [content rating](#content-rating-agency) |
| descriptors | array[integer] | The [content descriptors](#content-rating-agency) |
###### Content Rating Agency
| Value | Name | Description | Content Rating | Content Descriptor |
| ----- | ---- | ----------------------------------- | ------------------------------------------- | --------------------------------------------------- |
| 1 | ESRB | Entertainment Software Rating Board | [ESRB Content Rating](#esrb-content-rating) | [ESRB Content Descriptor](#esrb-content-descriptor) |
| 2 | PEGI | Pan European Game Information | [PEGI Content Rating](#pegi-content-rating) | [PEGI Content Descriptor](#pegi-content-descriptor) |
###### ESRB Content Rating
| Value | Name | Description |
| ----- | ----------------- | --------------------------- |
| 1 | EVERYONE | Suitable for all ages |
| 2 | EVERYONE_TEN_PLUS | Suitable for ages 10 and up |
| 3 | TEEN | Suitable for ages 13 and up |
| 4 | MATURE | Suitable for ages 17 and up |
| 5 | ADULTS_ONLY | Suitable for ages 18 and up |
| 6 | RATING_PENDING | Rating is pending |
###### PEGI Content Rating
| Value | Name | Description |
| ----- | -------- | --------------------------- |
| 1 | THREE | Suitable for all ages |
| 2 | SEVEN | Suitable for ages 7 and up |
| 3 | TWELVE | Suitable for ages 12 and up |
| 4 | SIXTEEN | Suitable for ages 16 and up |
| 5 | EIGHTEEN | Suitable for ages 18 and up |
###### ESRB Content Descriptor
| Value | Name | Description |
| ----- | ---------------------- | ---------------------------- |
| 1 | ALCOHOL_REFERENCE | References to alcohol |
| 2 | ANIMATED_BLOOD | Animated blood |
| 3 | BLOOD | Blood |
| 4 | BLOOD_AND_GORE | Blood and gore |
| 5 | CARTOON_VIOLENCE | Cartoon violence |
| 6 | COMIC_MISCHIEF | Comic mischief |
| 7 | CRUDE_HUMOR | Crude humor |
| 8 | DRUG_REFERENCE | References to drugs |
| 9 | FANTASY_VIOLENCE | Fantasy violence |
| 10 | INTENSE_VIOLENCE | Intense violence |
| 11 | LANGUAGE | Use of strong language |
| 12 | LYRICS | Lyrics |
| 13 | MATURE_HUMOR | Mature humor |
| 14 | NUDITY | Nudity |
| 15 | PARTIAL_NUDITY | Partial nudity |
| 16 | REAL_GAMBLING | Real gambling |
| 17 | SEXUAL_CONTENT | Sexual content |
| 18 | SEXUAL_THEMES | Sexual themes |
| 19 | SEXUAL_VIOLENCE | Sexual violence |
| 20 | SIMULATED_GAMBLING | Simulated gambling |
| 21 | STRONG_LANGUAGE | Strong language |
| 22 | STRONG_LYRICS | Strong lyrics |
| 23 | STRONG_SEXUAL_CONTENT | Strong sexual content |
| 24 | SUGGESTIVE_THEMES | Suggestive themes |
| 25 | TOBACCO_REFERENCE | References to tobacco |
| 26 | USE_OF_ALCOHOL | Use of alcohol |
| 27 | USE_OF_DRUGS | Use of drugs |
| 28 | USE_OF_TOBACCO | Use of tobacco |
| 29 | VIOLENCE | Violence |
| 30 | VIOLENT_REFERENCES | Violent references |
| 31 | IN_GAME_PURCHASES | In-game purchases |
| 32 | USERS_INTERACT | User interaction |
| 33 | SHARES_LOCATION | Location sharing |
| 34 | UNRESTRICTED_INTERNET | Unrestricted internet access |
| 35 | MILD_BLOOD | Mild blood |
| 36 | MILD_CARTOON_VIOLENCE | Mild cartoon violence |
| 37 | MILD_FANTASY_VIOLENCE | Mild fantasy violence |
| 38 | MILD_LANGUAGE | Mild language |
| 39 | MILD_LYRICS | Mild lyrics |
| 40 | MILD_SEXUAL_THEMES | Mild sexual themes |
| 41 | MILD_SUGGESTIVE_THEMES | Mild suggestive themes |
| 42 | MILD_VIOLENCE | Mild violence |
| 43 | ANIMATED_VIOLENCE | Animated violence |
###### PEGI Content Descriptor
| Value | Name | Description |
| ----- | -------------- | ---------------------------- |
| 1 | VIOLENCE | Depictions of violence |
| 2 | BAD_LANGUAGE | Use of bad language |
| 3 | FEAR | Scenes that may frighten |
| 4 | GAMBLING | Depictions of gambling |
| 5 | SEX | Depictions of sexual content |
| 6 | DRUGS | Depictions of drugs |
| 7 | DISCRIMINATION | Depictions of discrimination |
###### System Requirements Structure
| Field | Type | Description |
| ------------ | ----------------------------------------------------------- | ----------------------------------- |
| minimum? | [system requirement](#system-requirements-structure) object | The minimum system requirements |
| recommended? | [system requirement](#system-requirements-structure) object | The recommended system requirements |
###### System Requirement Structure
| Field | Type | Description |
| ------------------------- | ----------------------------------------------- | ---------------------------------------- |
| ram? | integer | The amount of RAM in megabytes |
| disk? | integer | The amount of disk space in megabytes |
| operating_system_version? | [localized string](/reference#localized-string) | The required operating system version |
| cpu? | [localized string](/reference#localized-string) | The required CPU |
| gpu? | [localized string](/reference#localized-string) | The required GPU |
| sound_card? | [localized string](/reference#localized-string) | The required sound card |
| directx? | [localized string](/reference#localized-string) | The required DirectX version |
| network? | [localized string](/reference#localized-string) | The required network connectivity status |
| notes? | [localized string](/reference#localized-string) | Additional notes |
###### Operating System
| Value | Name | Description |
| ----- | ------- | ----------- |
| 1 | WINDOWS | Windows OS |
| 2 | MACOS | macOS |
| 3 | LINUX | Linux |
###### SKU Price Structure
| Field | Type | Description |
| ----------------- | -------------------------------------------------------------- | -------------------------------------------------------------------------------- |
| currency | string | The lower-cased [ISO 4217](https://en.wikipedia.org/wiki/ISO_4217) currency code |
| currency_exponent | integer | The exponent to convert the amount to the displayed currency unit |
| amount | integer | The price amount in the smallest currency unit |
| sale_amount? | integer | The sale price amount in the smallest currency unit |
| sale_percentage? | integer | The percentage discount of the sale price |
| premium? | map[integer, [premium price](#premium-price-structure) object] | The price for premium users per [premium type](/resources/user#premium-type) |
###### Premium Price Structure
| Field | Type | Description |
| ---------- | ------- | ---------------------------------------------- |
| amount | integer | The price amount in the smallest currency unit |
| percentage | integer | The percentage discount for premium users |
###### External SKU Strategy Structure
| Field | Type | Description |
| --------- | ------------------- | ---------------------------------------------------------------- |
| type | integer | The [type of external SKU strategy](#external-sku-strategy-type) |
| metadata? | map[string, string] | Additional metadata for the external SKU strategy |
###### External SKU Strategy Type
| Value | Name | Description |
| ----- | ------------- | -------------------------- |
| 1 | CONSTANT | Regular pricing |
| 2 | APPLE_STICKER | Apple sticker pack pricing |
###### Tenant Metadata Structure
| Field | Type | Description |
| ------------------- | ---------------------------------------------------------------------------- | --------------------------- |
| guild_monetization? | [guild monetization metadata](#guild-monetization-metadata-structure) object | Guild monetization data |
| social_layer? | [social layer metadata](#social-layer-metadata-structure) object | Social layer game item data |
###### Guild Monetization Metadata Structure
| Field | Type | Description |
| ------------ | ------------------------------------------------------------------------------ | ---------------------------- |
| powerup? | [guild powerup metadata](#guild-powerup-metadata-structure) object | Guild powerup metadata |
| game_server? | [game server powerup metadata](#game-server-powerup-metadata-structure) object | Game server powerup metadata |
###### Guild Powerup Metadata Structure
| Field | Type | Description |
| ----------------------- | ---------------------------------------------------------------------------------- | ------------------------------------------------------------------- |
| boost_price | integer | The number of boosts the powerup costs |
| purchase_limit | integer | The maximum number of entitlements a guild can have for the powerup |
| guild_features | [guild premium features](/resources/guild#guild-premium-features-structure) object | The features granted by the powerup |
| category_type | string | The [type of guild powerup](#guild-powerup-category-type) |
| static_image_url | string | URL of the static banner image for the powerup |
| animated_image_url | string | URL of the animated banner image for the powerup |
| store_removal_date? ^1^ | ?ISO8601 datetime | When the powerup will be removed from the store |
^1^ Only included on [store listing](#store-listing-object) objects.
###### Game Server Powerup Metadata Structure
| Field | Type | Description |
| ------------------- | ---------------------------------------------------------------------------------- | ---------------------------------------------------------------------------- |
| boost_price | integer | The number of boosts the powerup costs |
| purchase_limit | integer | The maximum number of entitlements a guild can have for the powerup |
| guild_features | [guild premium features](/resources/guild#guild-premium-features-structure) object | The features granted by the powerup |
| category_type | string | The [type of guild powerup](#guild-powerup-category-type) |
| available_providers | array[string] | The available providers (currently only `SHOCKBYTE`) |
| memory | integer | The amount of RAM in megabytes that the game server provides |
| cpu | integer | The amount of CPU cores that the game server provides |
| storage | integer | The amount of storage in gigabytes that the game server provides |
| max_slots | integer | Maximum amount of players that can connect to the game server |
| memory_string | string | Human-readable amount of RAM that the game server provides |
| player_string | string | Human-readable maximum amount of players that can connect to the game server |
###### Guild Powerup Category Type
| Value | Description |
| ----------- | --------------------------------------------------- |
| level | Guild [premium tier](/resources/guild#premium-tier) |
| perk | Additional guild perk |
| game_server | Game server attached to the guild |
###### Example Game Server Powerup Metadata Structure
```json
{
"boost_price": 5,
"purchase_limit": 1,
"guild_features": {
"features": ["GAME_SERVERS"],
"additional_emoji_slots": 0,
"additional_sticker_slots": 0,
"additional_sound_slots": 0
},
"category_type": "game_server",
"available_providers": ["SHOCKBYTE"],
"memory": 8192,
"cpu": 2,
"storage": 100,
"max_slots": 40,
"memory_string": "8GB",
"player_string": "40+"
}
```
###### Social Layer Metadata Structure
| Field | Type | Description |
| ------------------------------- | ------------------------------------------------------------------- | ---------------------------------------------------- |
| carousel_items | array[[store carousel item](#store-carousel-item-structure) object] | The carousel items for the listing |
| label | string | The label for the listing |
| expires_at | ?ISO8601 datetime | When the listing expires |
| card_image_asset_id? | snowflake | The store asset ID for the card image |
| card_background_image_asset_id? | snowflake | The store asset ID for the card background image |
| price_tier? | integer | The [base price](#list-store-price-tiers) of the SKU |
###### Example SKU
```json
{
"id": "1333912750274904064",
"type": 3,
"product_line": 11,
"dependent_sku_id": null,
"application_id": "521842831262875670",
"manifest_labels": null,
"access_type": 1,
"name": "3-Day Nitro Credit",
"features": [],
"release_date": null,
"premium": false,
"slug": "3-day-nitro-credit",
"flags": 4,
"show_age_gate": false,
"price": {
"amount": 1400,
"currency": "discord_orb",
"currency_exponent": 0,
"premium": {
"2": {
"amount": 1400,
"percentage": 0
}
}
},
"tenant_metadata": {},
"created_at": "2025-08-05T20:53:39.133830+00:00",
"updated_at": "2025-08-05T20:53:39.135755+00:00"
}
```
### Store Listing Object
A listing for a marketable item on Discord. Tied to a single SKU.
###### Store Listing Structure
Store listing objects can either be localized or unlocalized. Localized listings only serialize strings and pricing for the user's location, while unlocalized listings serialize all strings and pricing for all locales.
All objects serialized in the listing inherit this behavior.
| Field | Type | Description |
| ------------------------ | -------------------------------------------------------------------------- | --------------------------------------------------- |
| id | snowflake | The ID of the listing |
| sku | [SKU](#sku-object) object | The SKU associated with the listing |
| child_skus? | array[[SKU](#sku-object) object] | The child SKUs associated with the category listing |
| alternative_skus? | array[[SKU](#sku-object) object] | Alternative SKUs for the listing |
| summary | [localized string](/reference#localized-string) | A summary of the listing |
| description? | [localized string](/reference#localized-string) | A description of the listing |
| tagline? | ?[localized string](/reference#localized-string) | A tagline for the listing |
| flavor_text? | ?string | Flavor text for the listing |
| benefits? | ?array[[store listing benefit](#store-listing-benefit-structure) object] | The benefits of the listing |
| published? ^1^ | boolean | Whether the listing is published |
| carousel_items? | ?array[[store carousel item](#store-carousel-item-structure) object] | The carousel items for the listing |
| staff_notes? | [store note](#store-note-structure) object | Notes from staff about the listing |
| guild? | ?partial [guild](/resources/guild#guild-object) object | The public guild associated with the listing |
| assets? | array[[store asset](#store-asset-structure) object] | The store assets for the listing |
| thumbnail? | [store asset](#store-asset-structure) object | The thumbnail for the listing |
| preview_video? | [store asset](#store-asset-structure) object | The preview video for the listing |
| header_background? | [store asset](#store-asset-structure) object | The header background for the listing |
| header_logo_dark_theme? | [store asset](#store-asset-structure) object | The dark theme header logo for the listing |
| header_logo_light_theme? | [store asset](#store-asset-structure) object | The light theme header logo for the listing |
| box_art? | [store asset](#store-asset-structure) object | The box art for the listing |
| hero_background? | [store asset](#store-asset-structure) object | The hero background for the listing |
| hero_video? | [store asset](#store-asset-structure) object | The hero video for the listing |
| entitlement_branch_id? | ?snowflake | The application branch ID granted by the listing |
| published_at? | ISO8601 datetime | When the listing was published |
| unpublished_at? | ISO8601 datetime | When the listing was unpublished |
| powerup_metadata? ^2^ | partial [guild powerup metadata](#guild-powerup-metadata-structure) object | The guild powerup metadata for the listing |
^1^ Not included in contexts that are impossible for an unpublished listing to be in.
^2^ Only includes the `category_type`, `static_image_url`, `animated_image_url`, and `store_removal_date` fields.
###### Store Listing Benefit Structure
| Field | Type | Description |
| ----------- | ---------------------------------------------------------- | ------------------------------ |
| id | snowflake | The ID of the benefit |
| name | string | The name of the benefit |
| description | string | The description of the benefit |
| icon | [store listing icon](#store-listing-icon-structure) object | The icon for the benefit |
###### Store Listing Icon Structure
| Field | Type | Description |
| ------------------ | --------- | -------------------------------------------- |
| type | integer | The [type of icon](#store-listing-icon-type) |
| store_asset_id ^1^ | snowflake | The store asset ID for the icon |
| emoji ^2^ | string | The unicode emoji for the icon |
^1^ Only included if `type` is `STORE_ASSET`.
^2^ Only included if `type` is `EMOJI`.
###### Store Listing Icon Type
| Value | Name | Description |
| ----- | ----------- | ----------------------- |
| 1 | STORE_ASSET | Icon is a store asset |
| 2 | EMOJI | Icon is a unicode emoji |
###### Store Carousel Item Structure
| Field | Type | Description |
| --------------------- | ---------- | ------------------------------------- |
| youtube_video_id? ^1^ | ?string | The YouTube video ID for the item |
| asset_id? ^1^ | snowflake | The store asset ID for the item |
| thumbnail_asset_id? | snowflake | The store asset ID for the thumbnail |
| background_asset_id? | ?snowflake | The store asset ID for the background |
| label? | string | The label for the item |
| label_icon_asset_id? | snowflake | The store asset ID for the label icon |
^1^ One of `youtube_video_id` or `asset_id` must be provided.
###### Store Note Structure
| Field | Type | Description |
| ------- | --------------------------------------------------- | -------------------------- |
| user | ?partial [user](/resources/user#user-object) object | The user who made the note |
| content | string | The note content |
###### Example Store Listing
```json
{
"id": "983874530717990912",
"summary": { "default": "Support Discord and get sweet chat perks." },
"sku": {
"id": "978380684370378762",
"type": 5,
"product_line": 1,
"dependent_sku_id": null,
"application_id": "521842831262875670",
"manifest_labels": null,
"access_type": 1,
"name": { "default": "Nitro Basic" },
"features": [],
"release_date": null,
"premium": false,
"slug": "nitro-basic",
"flags": 68,
"tenant_metadata": {},
"created_at": "2025-08-05T20:53:39.133830+00:00",
"updated_at": "2025-08-05T20:53:39.135755+00:00"
},
"description": { "default": "Support Discord and get sweet chat perks." },
"published": true,
"thumbnail": { "id": "1039257000355307530", "size": 333286, "mime_type": "image/png", "width": 834, "height": 471 },
"benefits": []
}
```
### Subscription Plan Object
A recurring payment to maintain entitlement to an SKU.
###### Subscription Plan Structure
| Field | Type | Description |
| ----------------------------- | -------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------- |
| id | snowflake | The ID of the subscription plan |
| name | string | The name of the subscription plan |
| sku_id | snowflake | The ID of the SKU the plan belongs to |
| interval | integer | The [interval](#subscription-interval) of the plan |
| interval_count | integer | The number of intervals per billing cycle |
| tax_inclusive | boolean | Whether the plan's prices are tax inclusive |
| price ^1^ **(deprecated)** | integer | The price amount in the smallest currency unit |
| currency ^1^ **(deprecated)** | string | The lower-cased [ISO 4217](https://en.wikipedia.org/wiki/ISO_4217) currency code of the plan's price |
| prices ^1^ | map[integer, [subscription prices](#subscription-prices-structure) object] | The prices for the plan per [purchase type](#subscription-plan-purchase-type) |
| price ^2^ | map[string, integer] | The price for the plan per lower-cased [ISO 4217](https://en.wikipedia.org/wiki/ISO_4217) currency code |
^1^ Only included when fetched from the [List Published Subscription Plans](#list-published-subscription-plans) or [List Bulk Published Subscription Plans](#list-bulk-published-subscription-plans) endpoints.
^1^ Only included when fetched from the [List Subscription Plans](#list-subscription-plans) endpoint.
###### Partial Subscription Plan Structure
| Field | Type | Description |
| -------------- | --------- | -------------------------------------------------- |
| id | snowflake | The ID of the subscription plan |
| name | string | The name of the subscription plan |
| sku_id | snowflake | The ID of the SKU the plan belongs to |
| interval | integer | The [interval](#subscription-interval) of the plan |
| interval_count | integer | The number of intervals per billing cycle |
| tax_inclusive | boolean | Whether the plan's prices are tax inclusive |
###### Subscription Prices Structure
| Field | Type | Description |
| --------------------- | ----------------------------------------------------------------------------------- | -------------------------------------------------- |
| country_prices | [country prices](#country-prices-structure) object | The prices for the plan for the given country |
| payment_source_prices | map[snowflake, array[[unit price](/resources/payment#unit-price-structure) object]] | The prices for the plan per user payment source ID |
###### Country Prices Structure
| Field | Type | Description |
| ------------ | ------------------------------------------------------------------- | --------------------------------------------------------------------------------------- |
| country_code | string | The [ISO 3166-1 alpha-2](https://en.wikipedia.org/wiki/ISO_3166-1_alpha-2) country code |
| prices | array[[unit price](/resources/payment#unit-price-structure) object] | The prices for the plan in the given country |
###### Subscription Interval
| Value | Name | Description |
| ----- | ----- | -------------------- |
| 1 | MONTH | Monthly subscription |
| 2 | YEAR | Yearly subscription |
| 3 | DAY | Daily subscription |
###### Subscription Plan Purchase Type
| Value | Name | Description |
| ----- | --------------------- | -------------------------------- |
| 0 | DEFAULT | Default pricing |
| 1 | GIFT | Gift purchase pricing |
| 2 | SALE | Sale pricing |
| 3 | PREMIUM_TIER_1 | Nitro Classic subscriber pricing |
| 4 | PREMIUM_TIER_2 | Nitro subscriber pricing |
| 5 | MOBILE | Mobile purchase pricing |
| 6 | PREMIUM_TIER_0 | Nitro Basic subscriber pricing |
| 7 | MOBILE_PREMIUM_TIER_2 | Mobile Nitro subscriber pricing |
###### Example Subscription Plan
```json
{
"id": "944265636643602432",
"name": "None 6 Month",
"interval": 1,
"interval_count": 6,
"tax_inclusive": true,
"sku_id": "628379670982688768",
"currency": "usd",
"price": 0,
"price_tier": null,
"prices": {
"0": {
"country_prices": {
"country_code": "CA",
"prices": [{ "currency": "usd", "amount": 0, "exponent": 2 }]
},
"payment_source_prices": {}
}
}
}
```
### Store Asset Object
An image or video associated with a store resource.
###### Store Asset Structure
| Field | Type | Description |
| ------------------- | --------- | ------------------------------------------------------------------ |
| id | snowflake | The ID of the asset |
| application_id? ^2^ | snowflake | The ID of the application |
| size | integer | The size of the asset in bytes |
| mime_type | string | The asset's [media type](https://en.wikipedia.org/wiki/Media_type) |
| filename ^1^ | string | The filename of the asset |
| width | integer | The width of the asset in pixels |
| height | integer | The height of the asset in pixels |
^1^ Only included when fetched from the [List Application Store Assets](#list-application-store-assets) or [Create Application Store Asset](#create-application-store-asset) endpoints.
^2^ Only included when fetched from the [List Games](/resources/game#list-games) or [Get Guild Role Subscriptions Settings](/resources/guild#get-guild-role-subscriptions-settings) endpoints.
###### Example Store Asset
```json
{
"id": "1059634086995574874",
"size": 4161529,
"mime_type": "image/gif",
"filename": "kitties.gif",
"width": 464,
"height": 512
}
```
### EULA Object
An End User License Agreement represents a legal agreement between the application owner and the end user.
###### EULA Structure
| Field | Type | Description |
| ------- | --------- | ----------------------- |
| id | snowflake | The ID of the EULA |
| name | string | The name of the EULA |
| content | string | The content of the EULA |
### Storefront Object
A collection of store listings in a unified showcase.
###### Storefront Structure
| Field | Type | Description |
| -------------------------- | ----------------------------------------------------------------------- | ---------------------------------------------- |
| application_id | snowflake | The ID of the application |
| application? | partial [application](/resources/application#application-object) object | The application |
| title | string | The title of the storefront |
| logo_asset_id? | snowflake | The ID of the logo store asset |
| light_theme_logo_asset_id? | snowflake | The ID of the logo store asset for light theme |
| pages | array[[storefront page](#storefront-page-structure) object] | The pages of the storefront |
| store_listings | array[[store listing](#store-listing-object) object] | The store listings |
| assets | array[[store asset](#store-asset-object) object] | The store assets |
| storefront_pricing? | [storefront prices](#storefront-prices-object) object | The storefront prices |
###### Storefront Page Structure
| Field | Type | Description |
| -------------- | --------------------------------------------------------------------------- | ------------------------------------------------ |
| title? | string | The title of the page (max 256 characters) |
| leaderboard? | [storefront leaderboard](#storefront-leaderboard-structure) object | The leaderboard on the page |
| sku_ids | array[snowflake] | The IDs of the SKUs on the page (max 100) |
| custom_sku_ids | array[string] | The IDs of the custom SKUs on the page (max 100) |
| sections? | array[[storefront page section](#storefront-page-section-structure) object] | The sections on the page (max 5) |
###### Storefront Leaderboard Structure
| Field | Type | Description |
| -------------------------- | --------- | ------------------------------------------------------- |
| title? | string | The title of the leaderboard (max 256 characters) |
| description? | string | The description of the leaderboard (max 512 characters) |
| background_image_asset_id? | snowflake | The ID of the background image store asset |
###### Storefront Page Section Structure
| Field | Type | Description |
| -------------- | ---------------- | -------------------------------------------------------- |
| title? | string | The title of the page section (max 256 characters) |
| sku_ids | array[snowflake] | The IDs of the SKUs on the page section (max 100) |
| custom_sku_ids | array[string] | The IDs of the custom SKUs on the page section (max 100) |
### Storefront Collection Object
A collection of storefront products.
###### Storefront Collection Structure
| Field | Type | Description |
| --------------- | ----------------- | --------------------------------------------- |
| id | snowflake | The ID of the storefront collection |
| application_id | snowflake | The ID of the application |
| name | string | The name of the storefront collection |
| description | string | The description of the storefront collection |
| product_ids | array[snowflake] | The IDs of the products in the collection |
| created_at | ISO8601 timestamp | When the storefront collection was created |
| updated_at | ISO8601 timestamp | When the storefront collection was updated |
| tenant_metadata | object | Tenant metadata for the storefront collection |
### Storefront Product Object
An abstraction around SKUs for modern marketplace items on Discord.
###### Storefront Product Structure
| Field | Type | Description |
| --------------- | -------------------------------------------------------------------- | ----------------------------------------- |
| id | snowflake | The ID of the product |
| application_id | snowflake | The ID of the application |
| sku_ids | array[snowflake] | The ID of the plan SKUs |
| name | string | The name of the product |
| options | array[[product option](#product-option-structure) object] | The plan options |
| created_at | ISO8601 timestamp | When the product was created |
| updated_at | ISO8601 timestamp | When the product was updated |
| tenant_metadata | [product tenant metadata](#product-tenant-metadata-structure) object | Tenant metadata for the product |
| skus | array[[product SKU](#product-sku-structure) object] | The plan SKUs associated with the product |
###### Product Option Structure
| Field | Type | Description |
| ------------- | ------------- | --------------------------- |
| name | string | The name of the option |
| option_values | array[string] | The possible option choices |
###### Product Tenant Metadata Structure
| Field | Type | Description |
| ------------------- | -------------------------------------------------------------------------------------------- | ----------------------- |
| guild_monetization? | [guild monetization product metadata](#guild-monetization-product-metadata-structure) object | Guild monetization data |
###### Guild Monetization Product Metadata Structure
| Field | Type | Description |
| ------------ | ---------------------------------------------------------------------------------------------- | ---------------------------- |
| game_server? | [game server powerup product metadata](#game-server-powerup-product-metadata-structure) object | Game server powerup metadata |
###### Game Server Powerup Product Metadata Structure
| Field | Type | Description |
| --------------------------------- | ------------------------------------------------------------------------- | ------------------------------------------------------------------------------ |
| instructions | [game server instructions](#game-server-instructions-structure) structure | The instructions for joining the game server |
| deactivation_cooldown_period_days | integer | Duration (in days) until the game server can be disabled |
| game_application_id | snowflake | The ID of the game application |
| provider | string | The [type of game server provider](/resources/guild#game-server-provider-type) |
| disabled | boolean | Whether the game server product is disabled |
| early_access | boolean | Whether the game server product is in early access |
| can_market | boolean | Whether the game server product can be marketed |
###### Game Server Instructions Structure
| Field | Type | Description |
| ----- | ------------- | ------------------------------- |
| pc | array[string] | The instructions for PC players |
###### Product SKU Structure
| Field | Type | Description |
| ------------------ | ---------------------------------------------------------------------------- | -------------------------------------------------------- |
| id | snowflake | The ID of the SKU |
| type | integer | The [type of SKU](#sku-type) |
| product_line | integer | The [product line](#sku-product-line) the SKU belongs to |
| application_id | snowflake | The ID of the application the SKU belongs to |
| name | string | The name of the SKU |
| thumbnail_asset_id | ?snowflake | The ID of the store asset for the SKU's thumbnail |
| slug | string | The URL slug of the SKU |
| premium | boolean | Whether the SKU is a premium user perk |
| selected_options | array[[product SKU option](#product-sku-option-structure) object] | The selected options |
| product_id | snowflake | The ID of the storefront product the SKU is for |
| position | integer | The position of the SKU |
| tenant_metadata | [product SKU tenant metadata](#product-sku-tenant-metadata-structure) object | Tenant metadata for the SKU |
###### Product SKU Option Structure
| Field | Type | Description |
| ------------ | ------ | ----------------------- |
| option_name | string | The name of the option |
| option_value | string | The value of the option |
###### Product SKU Tenant Metadata Structure
| Field | Type | Description |
| -------------- | ----------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------- |
| boost_price | integer | The number of boosts the powerup costs |
| purchase_limit | integer | The maximum number of entitlements a guild can have for the powerup |
| category_type | string | The [type of guild powerup](#guild-powerup-category-type) (currently only `game_server`) |
| plan_features | array[[product SKU plan feature](#product-sku-plan-feature-structure) object] | The SKU plan features |
###### Product SKU Plan Feature Structure
| Field | Type | Description |
| ----------- | ------ | ---------------------------- |
| title | string | The plan feature title |
| description | string | The plan feature description |
###### Example Product
```json
{
"id": "1458532555463589978",
"application_id": "1340102344645283891",
"sku_ids": ["1458532555463589979", "1460419709630677042", "1460419709630677043"],
"name": "Hytale",
"options": [
{
"name": "Memory",
"option_values": ["5", "8", "12"]
}
],
"created_at": "2026-01-07T18:47:39.455084+00:00",
"updated_at": "2026-02-27T18:40:56.037576+00:00",
"tenant_metadata": {
"guild_monetization": {
"game_server": {
"instructions": {
"pc": [
"Open Hytale.",
"Click on **Servers**.",
"Click on **Add Server**.",
"Paste your server IP address, enter a server name and click **Add Server**.",
"Double click your server in the list to join."
]
},
"deactivation_cooldown_period_days": 7,
"game_application_id": "1458530944955973852",
"provider": "shockbyte",
"disabled": false,
"early_access": true,
"can_market": true
}
}
},
"skus": [
{
"id": "1458532555463589979",
"type": 2,
"product_line": 13,
"application_id": "1340102344645283891",
"name": "Starter Plan",
"thumbnail_asset_id": null,
"slug": "starter-plan",
"premium": false,
"selected_options": [
{
"option_name": "Memory",
"option_value": "5"
}
],
"product_id": "1458532555463589978",
"position": 0,
"tenant_metadata": {
"boost_price": 5,
"purchase_limit": 1,
"category_type": "game_server",
"plan_features": [
{
"title": "4+",
"description": "Players"
},
{
"title": "5GB",
"description": "RAM"
},
{
"title": "3",
"description": "vCPUs"
}
]
}
}
]
}
```
### Storefront Prices Object
###### Storefront Prices Structure
| Field | Type | Description |
| --------------------- | ---------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------- |
| sku_price_map | map[snowflake, [storefront SKU pricing](#storefront-sku-pricing-structure) object] | A mapping of SKU IDs to their pricing |
| pricing_result_id_map | map[snowflake, map[integer, [storefront pricing result](#storefront-pricing-result-structure) object]] | A mapping of pricing result IDs to mapping of [storefront purchase type](#storefront-purchase-type) to storefront pricing results |
| reward_result_id_map | map[snowflake, map[integer, [storefront promotion reward](#storefront-promotion-reward-structure) object]] | A mapping of reward result IDs to mapping of [storefront purchase type](#storefront-purchase-type) to discounts |
###### Storefront SKU Pricing Structure
| Field | Type | Description |
| ------------------------ | ---------------- | ----------------------------- |
| pricing_result_id | snowflake | The ID of the pricing result |
| storefront_promotion_ids | array[snowflake] | The ID of the promotions |
| reward_result_ids | array[snowflake] | The IDs of the reward results |
###### Storefront Pricing Result Structure
| Field | Type | Description |
| ---------- | ----------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| user_price | array[[unit price](/resources/payment#unit-price-structure) object] | The price for the user |
| prices | map[integer, map[integer, array[[unit price](/resources/payment#unit-price-structure) object]]] | A mapping of [price set assignment purchase type](#price-set-assignment-purchase-type) to mapping of [price variant type](#storefront-price-variant-type) to the prices |
###### Storefront Promotion Reward Structure
| Field | Type | Description |
| ------ | ------- | --------------------------------------------------------------------- |
| type | integer | The [type of the promotion reward](#storefront-promotion-reward-type) |
| amount | integer | How much the discount is |
###### Storefront Purchase Type
| Value | Name | Description |
| ----- | ------------- | --------------------------------------------- |
| 0 | SELF_PURCHASE | The user is purchasing an item for themselves |
| 1 | GIFT | The user is purchasing item as a gift |
###### Price Set Assignment Purchase Type
| Value | Name | Description |
| ----- | --------------------- | ----------------- |
| 0 | BASE | Base |
| 1 | PREMIUM_TIER_0 | Nitro Basic |
| 2 | PREMIUM_TIER_1 | Nitro Classic |
| 3 | PREMIUM_TIER_2 | Nitro |
| 4 | MOBILE | Mobile |
| 5 | MOBILE_PREMIUM_TIER_2 | Mobile with Nitro |
| 6 | GIFT | Gift |
###### Storefront Price Variant Type
| Value | Name | Description |
| ----- | ---------- | -------------------------- |
| 0 | NORMAL | The price is normal |
| 1 | DISCOUNTED | The price is with discount |
###### Storefront Promotion Reward Type
| Value | Name | Description |
| ----- | -------- | ----------- |
| 1 | DISCOUNT | Discount |
## Endpoints
List Application SKUs
Returns a list of [SKU](#sku-object) objects for the given application. User must be the owner of the application or member of the owning team.
###### Query String Params
| Field | Type | Description |
| ------------------ | ------- | --------------------------------------------------------------------------------------- |
| country_code? | string | The [ISO 3166-1 alpha-2](https://en.wikipedia.org/wiki/ISO_3166-1_alpha-2) country code |
| localize? | boolean | Whether to localize the SKUs for the user's location (default true) |
| with_bundled_skus? | boolean | Whether to include bundled SKUs within SKU objects in the response (default false) |
Create SKU
Creates a new SKU. Returns the created [SKU](#sku-object) object on success. Requires an application with access to the store or monetization. User must be the owner of the application or member of the owning team.
###### JSON Params
| Field | Type | Description |
| -------------------- | -------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------- |
| type | integer | The [type of SKU](#sku-type) |
| application_id | snowflake | The ID of the application the SKU belongs to |
| name | [localized string](/reference#localized-string) | The name of the SKU (1-256 characters) |
| flags? | integer | The [SKU flags](#sku-flags) (only `AVAILABLE` can be set) |
| legal_notice? | [localized string](/reference#localized-string) | The legal notice for the SKU (max 1024 characters) |
| dependent_sku_id? | snowflake | The ID of the prerequisite required to buy this SKU |
| bundled_skus? | array[snowflake] | The IDs of the SKUs that are included when purchasing this SKU |
| access_type? | integer | The [access level](#sku-access-type) of the SKU |
| manifest_labels? | array[snowflake] | The IDs of the manifest labels associated with the SKU |
| features? | array[integer] | The [features](#sku-feature) of the SKU |
| locales? | array[string] | The [locales](/reference#locales) the SKU is available in |
| genres? | array[integer] | The [genres](#sku-genre) of the SKU |
| content_ratings? | map[integer, [content rating](#content-rating-structure) object] | The content ratings of the SKU per [agency](#content-rating-agency) |
| system_requirements? | map[integer, [system requirements](#system-requirements-structure) object] | The system requirements for each [operating system](#operating-system) the SKU supports |
| price_tier? | integer | The [base price](#list-store-price-tiers) of the SKU |
| price? | map[string, integer] | Localized pricing overrides per lower-cased [ISO 4217](https://en.wikipedia.org/wiki/ISO_4217) currency code |
| sale_price_tier? | integer | The [sale price](#list-store-price-tiers) of the SKU |
| sale_price? | map[string, integer] | Localized sale pricing overrides per lower-cased [ISO 4217](https://en.wikipedia.org/wiki/ISO_4217) currency code |
| release_date? | ISO8601 date | When the SKU will be released |
Get SKU
Returns a [SKU](#sku-object) object for the given SKU ID. User must own the SKU's application or be a member of the owning team.
###### Query String Params
| Field | Type | Description |
| ------------- | ------- | --------------------------------------------------------------------------------------- |
| country_code? | string | The [ISO 3166-1 alpha-2](https://en.wikipedia.org/wiki/ISO_3166-1_alpha-2) country code |
| localize? | boolean | Whether to localize the SKUs for the user's location (default true) |
Modify SKU
Modifies an existing SKU. Returns the modified [SKU](#sku-object) object on success. User must own the SKU's application or be a developer of the owning team.
###### JSON Params
| Field | Type | Description |
| -------------------- | -------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------- |
| name? | [localized string](/reference#localized-string) | The name of the SKU (1-256 characters) |
| flags? | integer | The [SKU flags](#sku-flags) (only `AVAILABLE` can be set) |
| legal_notice? | [localized string](/reference#localized-string) | The legal notice for the SKU (max 1024 characters) |
| dependent_sku_id? | snowflake | The ID of the prerequisite required to buy this SKU |
| bundled_skus? | array[snowflake] | The IDs of the SKUs that are included when purchasing this SKU |
| access_type? | integer | The [access level](#sku-access-type) of the SKU |
| manifest_labels? | array[snowflake] | The IDs of the manifest labels associated with the SKU |
| features? | array[integer] | The [features](#sku-feature) of the SKU |
| locales? | array[string] | The [locales](/reference#locales) the SKU is available in |
| genres? | array[integer] | The [genres](#sku-genre) of the SKU |
| content_ratings? | map[integer, [content rating](#content-rating-structure) object] | The content ratings of the SKU per [agency](#content-rating-agency) |
| system_requirements? | map[integer, [system requirements](#system-requirements-structure) object] | The system requirements for each [operating system](#operating-system) the SKU supports |
| price_tier? | integer | The [base price](#list-store-price-tiers) of the SKU |
| price? | map[string, integer] | Localized pricing overrides per lower-cased [ISO 4217](https://en.wikipedia.org/wiki/ISO_4217) currency code |
| sale_price_tier? | integer | The [sale price](#list-store-price-tiers) of the SKU |
| sale_price? | map[string, integer] | Localized sale pricing overrides per lower-cased [ISO 4217](https://en.wikipedia.org/wiki/ISO_4217) currency code |
| release_date? | ISO8601 date | When the SKU will be released |
List SKU Store Listings
Returns a list of [store listing](#store-listing-object) objects for the given SKU ID. User must own the SKU's application or be a member of the owning team.
###### Query String Params
| Field | Type | Description |
| ------------- | ------- | --------------------------------------------------------------------------------------- |
| country_code? | string | The [ISO 3166-1 alpha-2](https://en.wikipedia.org/wiki/ISO_3166-1_alpha-2) country code |
| localize? | boolean | Whether to localize the SKUs for the user's location (default true) |
Create Store Listing
Creates a new store listing. Returns the created [store listing](#store-listing-object) object on success. User must own the SKU's application or be a member of the owning team.
###### JSON Params
| Field | Type | Description |
| --------------------------------- | -------------------------------------------------------------------- | ------------------------------------------------------------------------ |
| application_id | snowflake | The ID of the application the listing belongs to |
| sku_id | snowflake | The ID of the SKU the listing is associated with |
| child_sku_ids? | array[snowflake] | The IDs of the child SKUs associated with the category listing (max 100) |
| summary | [localized string](/reference#localized-string) | A summary of the listing (1-1024 characters) |
| description | [localized string](/reference#localized-string) | A description of the listing (1-8192 characters) |
| tagline? | [localized string](/reference#localized-string) | A tagline for the listing (max 1024 characters) |
| published? | boolean | Whether the listing is published (default false) |
| carousel_items? ^1^ | ?array[[store carousel item](#store-carousel-item-structure) object] | The carousel items for the listing |
| guild_id? | snowflake | The ID of the public guild associated with the listing |
| thumbnail_asset_id? | snowflake | The store asset ID for the thumbnail of the listing |
| preview_video_asset_id? | snowflake | The store asset ID for the preview video of the listing |
| header_background_asset_id? | snowflake | The store asset ID for the header background |
| header_logo_dark_theme_asset_id? | snowflake | The store asset ID for the dark theme header logo of the listing |
| header_logo_light_theme_asset_id? | snowflake | The store asset ID for the light theme header logo of the listing |
| box_art_asset_id? | snowflake | The store asset ID for the box art of the listing |
| hero_background_asset_id? | snowflake | The store asset ID for the hero background of the listing |
| hero_video_asset_id? | snowflake | The store asset ID for the hero video of the listing |
^1^ Only `youtube_video_id` or `asset_id` can be set.
Get Store Listing
Returns a [store listing](#store-listing-object) object for the given listing ID. User must own the listing's application or be a member of the owning team.
###### Query String Params
| Field | Type | Description |
| ------------- | ------- | --------------------------------------------------------------------------------------- |
| country_code? | string | The [ISO 3166-1 alpha-2](https://en.wikipedia.org/wiki/ISO_3166-1_alpha-2) country code |
| localize? | boolean | Whether to localize the SKUs for the user's location (default true) |
Modify Store Listing
Modifies an existing store listing. Returns the modified [store listing](#store-listing-object) object on success. User must own the listing's application or be a developer of the owning team.
###### JSON Params
| Field | Type | Description |
| --------------------------------- | -------------------------------------------------------------------- | ------------------------------------------------------------------------ |
| child_sku_ids? | array[snowflake] | The IDs of the child SKUs associated with the category listing (max 100) |
| summary? | [localized string](/reference#localized-string) | A summary of the listing (1-1024 characters) |
| description? | [localized string](/reference#localized-string) | A description of the listing (1-8192 characters) |
| tagline? | [localized string](/reference#localized-string) | A tagline for the listing (max 1024 characters) |
| published? | boolean | Whether the listing is published |
| carousel_items? ^1^ | ?array[[store carousel item](#store-carousel-item-structure) object] | The carousel items for the listing |
| guild_id? | snowflake | The ID of the public guild associated with the listing |
| thumbnail_asset_id? | snowflake | The store asset ID for the thumbnail of the listing |
| preview_video_asset_id? | snowflake | The store asset ID for the preview video of the listing |
| header_background_asset_id? | snowflake | The store asset ID for the header background |
| header_logo_dark_theme_asset_id? | snowflake | The store asset ID for the dark theme header logo of the listing |
| header_logo_light_theme_asset_id? | snowflake | The store asset ID for the light theme header logo of the listing |
| box_art_asset_id? | snowflake | The store asset ID for the box art of the listing |
| hero_background_asset_id? | snowflake | The store asset ID for the hero background of the listing |
| hero_video_asset_id? | snowflake | The store asset ID for the hero video of the listing |
^1^ Only `youtube_video_id` or `asset_id` can be set.
Delete Store Listing
Deletes an existing store listing. Returns a 204 empty response on success. User must own the listing's application or be a member of the owning team.
List Application Published Store Listings
Returns a list of published [store listing](#store-listing-object) objects for the given application ID.
###### Query String Params
| Field | Type | Description |
| -------------- | --------- | --------------------------------------------------------------------------------------- |
| application_id | snowflake | The application ID to get the listings for |
| guild_id? | snowflake | The guild ID to fetch hidden listings for |
| country_code? | string | The [ISO 3166-1 alpha-2](https://en.wikipedia.org/wiki/ISO_3166-1_alpha-2) country code |
| localize? | boolean | Whether to localize the SKUs for the user's location (default true) |
Get Application Primary Store Listing
Returns a [store listing](#store-listing-object) object for the primary SKU of the given application ID.
###### Query String Params
| Field | Type | Description |
| ------------- | ------- | --------------------------------------------------------------------------------------- |
| country_code? | string | The [ISO 3166-1 alpha-2](https://en.wikipedia.org/wiki/ISO_3166-1_alpha-2) country code |
| localize? | boolean | Whether to localize the SKUs for the user's location (default true) |
List Bulk Application Primary Store Listing
Returns a list of [store listing](#store-listing-object) objects for the primary SKU of the given application IDs.
###### Query String Params
| Field | Type | Description |
| --------------- | ---------------- | --------------------------------------------------------------------------------------- |
| application_ids | array[snowflake] | The application IDs to get the listings for (1-100) |
| country_code? | string | The [ISO 3166-1 alpha-2](https://en.wikipedia.org/wiki/ISO_3166-1_alpha-2) country code |
| localize? | boolean | Whether to localize the SKUs for the user's location (default true) |
Get SKU Published Store Listing
Returns the [store listing](#store-listing-object) object for the given SKU ID.
###### Query String Params
| Field | Type | Description |
| ------------- | ------- | --------------------------------------------------------------------------------------- |
| country_code? | string | The [ISO 3166-1 alpha-2](https://en.wikipedia.org/wiki/ISO_3166-1_alpha-2) country code |
| localize? | boolean | Whether to localize the SKUs for the user's location (default true) |
List Subscription Plans
Returns a list of [subscription plan](#subscription-plan-object) objects for the given SKU ID. User must own the SKU's application or be a member of the owning team.
List Published Subscription Plans
Returns a list of published [subscription plan](#subscription-plan-object) objects for the given SKU ID.
###### Query String Params
| Field | Type | Description |
| ------------------------ | --------- | --------------------------------------------------------------------------------------- |
| include_unpublished? ^1^ | boolean | Whether to include unpublished subscription plans (default false) |
| revenue_surface? | integer | The [revenue surface](#revenue-surface), used for analytics |
| country_code? | string | The [ISO 3166-1 alpha-2](https://en.wikipedia.org/wiki/ISO_3166-1_alpha-2) country code |
| payment_source_id? | snowflake | The ID of the payment source to get prices for |
^1^ To access unpublished subscription plans, the user must own the SKU's application or be a member of the owning team.
###### Revenue Surface
| Value | Name | Description |
| ----- | --------- | ---------------------- |
| 0 | DISCOVERY | Subscription discovery |
| 1 | CHECKOUT | Subscription checkout |
List Bulk Published Subscription Plans
Returns a list of published [subscription plan](#subscription-plan-object) objects for the given SKU IDs.
###### Query String Params
| Field | Type | Description |
| ------------------------ | ---------------- | --------------------------------------------------------------------------------------- |
| sku_ids | array[snowflake] | The SKU IDs to get the subscription plans for (1-16) |
| include_unpublished? ^1^ | boolean | Whether to include unpublished subscription plans (default false) |
| revenue_surface? | integer | The [revenue surface](#revenue-surface), used for analytics |
| country_code? | string | The [ISO 3166-1 alpha-2](https://en.wikipedia.org/wiki/ISO_3166-1_alpha-2) country code |
| payment_source_id? | snowflake | The ID of the payment source to get prices for |
^1^ To access unpublished subscription plans, the user must own the SKUs' application or be a member of the owning team.
Get Subscription Group Listing By Subscription Plan
Returns the information about the role subscription group for the given subscription plan ID.
###### Response Body
| Field | Type | Description |
| ------------------------- | --------------------------------------------------------------------- | -------------------------------------- |
| id | snowflake | The ID of the store listing |
| application_id | ?snowflake | The ID of the application |
| sku_flags | integer | The [SKU flags](#sku-flags) |
| published | boolean | Whether the store listing is published |
| name? | string | The name of the SKU |
| description? | string | The description of the SKU |
| subscription_listings_ids | array[snowflake] | The IDs of the subscription listings |
| subscription_listings | array[[subscription listing](#subscription-listing-structure) object] | The subscription listings |
###### Subscription Listing Structure
| Field | Type | Description |
| ---------------------- | ------------------------------------------------------------------------ | -------------------------------------- |
| id | snowflake | The ID of the SKU |
| application_id | ?snowflake | The ID of the application |
| published | boolean | Whether the listing is published |
| soft_deleted | boolean | Whether the listing is soft-deleted |
| sku_flags | integer | The [SKU flags](#sku-flags) |
| image_asset? | [store asset](#store-asset-object) object | The thumbnail for the listing |
| subscription_plans | array[[subscription plan](#subscription-plan-object) object] | The subscription plans for the listing |
| store_listing_benefits | ?array[[store listing benefit](#store-listing-benefit-structure) object] | The benefits of the listing |
Get SKU Purchase Preview
Returns an [invoice](/resources/payment#invoice-object) object representing a purchase preview for the given SKU ID.
###### Query String Params
| Field | Type | Description |
| ------------------------- | --------- | -------------------------------------------------------------------------------------------- |
| payment_source_id? | snowflake | The ID of the payment source to pay with |
| currency? | string | The lower-cased [ISO 4217](https://en.wikipedia.org/wiki/ISO_4217) currency code to price in |
| sku_subscription_plan_id? | snowflake | The ID of the subscription plan to purchase (required for subscription SKUs) |
| gift? | boolean | Whether the purchase is a gift (default false) |
| test_mode? | boolean | Whether the purchase is in test mode (default false) |
| load_id? | string | A client-generated UUID used to identify the current checkout session |
Create SKU Purchase
Creates a new purchase for the given SKU ID. Fires an [Entitlement Create](/gateway/gateway-events#entitlement-create) and [Payment Update](/gateway/gateway-events#payment-update) Gateway event.
###### JSON Params
| Field | Type | Description |
| ------------------------- | ----------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------- |
| payment_source_id? | snowflake | The ID of the payment source to pay with |
| payment_source_token? | ?string | The token used to authorize with the payment source |
| return_url? ^1^ | ?string | TThe URL to redirect to after payment is complete (max 2048 characters) |
| country_code? | string | The [ISO 3166-1 alpha-2](https://en.wikipedia.org/wiki/ISO_3166-1_alpha-2) country code |
| currency? | string | The lower-cased [ISO 4217](https://en.wikipedia.org/wiki/ISO_4217) currency code |
| sku_subscription_plan_id? | snowflake | The ID of the subscription plan to purchase (required for subscription SKUs) |
| gift? | boolean | Whether the purchase is a gift (default false) |
| gift_info_options? | [gift info options](#gift-info-options-structure) object | Additional metadata for gift purchases |
| test_mode? | boolean | Whether the purchase is in test mode (default false) |
| expected_amount? ^2^ | integer | The expected amount to be charged in the smallest currency unit |
| expected_currency? ^2^ | string | The expected currency for the purchase in lower-cased [ISO 4217](https://en.wikipedia.org/wiki/ISO_4217) format |
| purchase_token ^2^ | string | The purchase token of the payment client (max 1024 characters) |
| gateway_checkout_context? | ?[gateway checkout context](/resources/billing#gateway-checkout-context-structure) object | The context for the gateway checkout, if applicable |
| load_id | string | A client-generated UUID used to identify the current checkout session, used for purchase deduplication |
^1^ If required, this URL is typically set to the [Create Billing Popup Bridge Redirect](/resources/billing#create-billing-popup-bridge-redirect) endpoint with a `response_type` of `return`, which redirects the user back to the Discord client for handling.
^2^ If the actual currency or amount charged does not match these expected values, the purchase will fail.
^3^ See the section on [payment clients](/resources/payment#payment-clients) for more information.
###### Gift Info Options Structure
| Field | Type | Description |
| --------------- | ---------------- | ------------------------------------------------------------------------------------------------------ |
| gift_style? | ?integer | The [style of the gift code](/resources/entitlement#gift-style) |
| recipient_id? | snowflake | The ID of the user to directly send the gift to |
| custom_message? | ?string | A custom message to include with the gift (max 190 characters) |
| emoji_id? | ?snowflake | The ID of a guild's custom emoji |
| emoji_name? | ?string | The unicode character of the emoji |
| sound_id? | ?snowflake | The ID of the default soundboard sound to play with the gift |
| reward_sku_ids? | array[snowflake] | The IDs of the promotional SKUs the gifter chooses to redeem as a reward for purchasing a gift (max 1) |
###### Response Body
| Field | Type | Description |
| ----------------------- | ---------------------------------------------------------------------------------- | ------------------------------------------------ |
| entitlements | array[[entitlement](/resources/entitlement#entitlement-object) object] | The entitlements granted by the purchase |
| library_applications? | array[library application object] | The library applications granted by the purchase |
| applied_user_discounts? | array[[user discount offer](/resources/billing#user-discount-offer-object) object] | The user discount offers applied to the purchase |
| gift_code? | string | The gift code created by the purchase |
List Application Store Assets
Returns a list of [store asset](#store-asset-structure) objects for the given application ID. User must be the owner of the application or member of the owning team.
Create Application Store Asset
Uploads a new store asset for the given application ID. Returns the created [store asset](#store-asset-structure) object on success. User must be the owner of the application or developer of the owning team.
###### Form Params
| Field | Type | Description |
| ----- | ------------- | --------------------------- |
| files | file contents | Contents of the store asset |
Delete Application Store Asset
Deletes the store asset with the given ID. Returns a 204 empty response on success. User must be the owner of the application or member of the owning team.
List Store Price Tiers
Returns a list of integers representing the available store price tiers.
###### Query String Params
| Field | Type | Description |
| ---------------- | ------- | ------------------------------------------------------- |
| price_tier_type? | integer | The [type of price tiers](#price-tier-type) to retrieve |
###### Price Tier Type
| Value | Name | Description |
| ----- | ------------------------ | ------------------------------------------------ |
| 1 | GUILD_ROLE_SUBSCRIPTIONS | Price tiers to use with guild role subscriptions |
| 2 | GUILD_PRODUCTS | Price tiers to use with guild products |
Get Store Price Tier
Returns a map of lower-cased [ISO 4217](https://en.wikipedia.org/wiki/ISO_4217) currency codes to integer prices representing localized pricing for the given price tier.
Get EULA
Returns a [EULA](#eula-object) object for the given ID.
Get Application Store Layout
Returns the store layout of the given application ID.
###### Response Body
| Field | Type | Description |
| ------------------ | ------------------------------------------------------------ | --------------------------------------- |
| subscriptions | array[[store listing](#store-listing-object) object] | The listings the users can subscribe to |
| otps | array[[store listing](#store-listing-object) object] | The listings the users can purchase |
| subscription_plans | array[[subscription plan](#subscription-plan-object) object] | The subscription plans |
Modify Application Storefront Publish States
Modifies the SKU publishing states for the given application and SKU IDs.
###### JSON Params
| Field | Type | Description |
| ------------- | ---------------- | ----------------------------------------------------------- |
| publish_state | integer | The [publish state](#storefront-publish-state) for the SKUs |
| sku_ids | array[snowflake] | The IDs of the SKUs to modify publish state for (1-255) |
###### Storefront Publish State
| Value | Name | Description |
| ----- | -------------------- | ------------------------------------------- |
| 1 | UNPUBLISHED | The SKUs are unpublished |
| 2 | PUBLISHED_HIDDEN | The SKUs are published but hidden in the UI |
| 3 | PUBLISHED_STOREFRONT | The SKUs are published and shown in the UI |
###### Response Body
| Field | Type | Description |
| --------------------- | ---------------------------------------------------- | ------------------------ |
| store_layout_sku_ids? | array[snowflake] | The store layout SKU IDs |
| store_listings? | array[[store listing](#store-listing-object) object] | The store listings |
Get Consumable SKU Pricing
Returns the pricing information for a consumable SKU. These are currently as follows:
- HD Streaming (1285377810587979827)
- Confetti (1316162456959057920)
###### Response Body
| Field | Type | Description |
| ----- | ---------------------------------------- | ----------------------------------- |
| price | [SKU price](#sku-price-structure) object | The pricing information for the SKU |
Get HD Streaming Consumable
Returns the active HD streaming potion entitlement for the user.
###### Response Body
| Field | Type | Description |
| ----------- | ---------------------------------------------------------------- | ----------------------------------- |
| entitlement | ?[entitlement](/resources/entitlement#entitlement-object) object | The active HD streaming entitlement |
Apply HD Streaming Consumable
Applies an HD streaming potion to a voice channel. Returns a 204 empty response on success. Fires a [Channel Update](/gateway/gateway-events#channel-update) Gateway event.
###### JSON Params
| Field | Type | Description |
| ---------- | --------- | --------------------------------------- |
| channel_id | snowflake | The ID of the voice channel to apply to |
Get Confetti Consumable
Returns the active confetti potion entitlement for the user.
###### Response Body
| Field | Type | Description |
| ----------- | ---------------------------------------------------------------- | -------------------------------------- |
| entitlement | ?[entitlement](/resources/entitlement#entitlement-object) object | The active confetti potion entitlement |
| num_potions | integer | Number of unused potions left |
Apply Confetti Consumable
Applies a confetti potion to a message. To use custom emoji, you must encode it in the format `name:id` with the emoji name and emoji ID. Returns a 204 empty response on success. Fires a [Message Update](/gateway/gateway-events#message-update) Gateway event.
###### JSON Params
| Field | Type | Description |
| ---------- | --------- | ----------------------------------------------------- |
| channel_id | snowflake | The ID of the channel the message is in |
| message_id | snowflake | The ID of the message to apply the confetti potion to |
| emoji_name | string | Unicode emoji or custom emoji name and ID |
Get Virtual Currency Balance
Returns the current user's Orbs balance.
###### Response Body
| Field | Type | Description |
| ------- | ------- | --------------------------- |
| balance | integer | Amount of Orbs the user has |
Redeem Virtual Currency
Purchases a SKU using virtual currency. Returns a list of [entitlement](/resources/entitlement#entitlement-object) objects granted to the current user.
Fires [Payment Update](/gateway/gateway-events#payment-update), [Virtual Currency Balance Update](/gateway/gateway-events#virtual-currency-balance-update), [Entitlement Create](/gateway/gateway-events#entitlement-create), and [Entitlement Update](/gateway/gateway-events#entitlement-update) Gateway events.
###### JSON Params
| Field | Type | Description |
| ------------------- | ------ | --------------------------------------------------------------------- |
| checkout_session_id | string | A client-generated UUID used to identify the current checkout session |
Get Application Storefront for Premium Button
Returns information about store listing, relevant SKUs, and subscription plans.
###### Response Body
| Field | Type | Description |
| ------------------- | ------------------------------------------------------------ | ---------------------- |
| skus? | array[[SKU](#sku-object) object] | The relevant SKUs |
| store_listings | array[[store listing](#store-listing-object) object] | The store listings |
| subscription_plans? | array[[subscription plan](#subscription-plan-object) object] | The subscription plans |
Get Storefront Collection
Returns information about collection for the given collection ID.
###### Query String Params
| Field | Type | Description |
| ----------------------------------- | --------- | --------------------------------------------------------------------------------------- |
| country_code? | string | The [ISO 3166-1 alpha-2](https://en.wikipedia.org/wiki/ISO_3166-1_alpha-2) country code |
| guild_id? | snowflake | The guild ID to fetch the storefront collection for |
| include_unpublished_products? ^1^ | boolean | Whether to include unpublished products (default false) |
| include_unpublished_collection? ^1^ | boolean | Whether to return collection even if unpublished (default false) |
^1^ Only usable by Discord employees.
###### Response Body
| Field | Type | Description |
| ---------- | -------------------------------------------------------------- | ------------------------------ |
| collection | [storefront collection](#storefront-collection-object) object | The collection |
| products | array[[storefront product](#storefront-product-object) object] | The products in the collection |
Get Storefront Product
Returns a [storefront product](#storefront-product-object) object for the given product ID.
Get Storefront Product By SKU ID
Returns an associated [storefront product](#storefront-product-object) object for the given SKU ID.
List Storefront Products By SKU ID
Returns associated [storefront product](#storefront-product-object) objects for the given SKU IDs.
###### Query String Params
| Field | Type | Description |
| ------- | ---------------- | ------------------------------------------- |
| sku_ids | array[snowflake] | The SKU IDs to get the products for (1-100) |
###### Response Body
| Field | Type | Description |
| -------- | -------------------------------------------------------------- | ------------ |
| products | array[[storefront product](#storefront-product-object) object] | The products |
List Storefront SKU Prices
Returns prices for the given storefront SKUs.
###### Query String Params
| Field | Type | Description |
| ------- | ---------------- | ----------------------------------------- |
| sku_ids | array[snowflake] | The SKU IDs to get the prices for (1-100) |
###### Response Body
| Field | Type | Description |
| ---------- | ------------------------------------------------------------------------------------ | ------------------------------------ |
| sku_prices | map[snowflake, partial [subscription prices](#subscription-prices-structure) object] | A mapping of SKU IDs to their prices |
Get Guild Application Storefront
Returns a [storefront](#storefront-object) object for the application linked to the given guild ID.
List Social Layer SKUs
Returns a list of [SKU](#sku-object) objects related to in-game items for the given application. Requires a partner application with access to the social layer SDK and monetization. User must be the owner of the application or member of the owning team.
Create Social Layer SKU
Creates a new SKU for in-game item. Returns the created [SKU](#sku-object) object on success. Requires a partner application with access to the social layer SDK and monetization. User must be the owner of the application or member of the owning team.
###### JSON Params
| Field | Type | Description |
| ---------- | ------- | ---------------------------------------------------- |
| name | string | The name of the SKU (max 256 characters) |
| price_tier | integer | The [base price](#list-store-price-tiers) of the SKU |
Get Application Storefront
Returns a [storefront](#storefront-object) object for the given application ID.
Modify Application Storefront
Modifies the application's storefront. Returns the modified [storefront](#storefront-object) object on success. User must be the owner of the application or developer of the owning team.
###### JSON Params
| Field | Type | Description |
| -------------------------- | ----------------------------------------------------------- | ------------------------------------------------ |
| title | string | The title of the storefront (max 256 characters) |
| logo_asset_id? | ?snowflake | The ID of the logo store asset |
| light_theme_logo_asset_id? | ?snowflake | The ID of the logo store asset for light theme |
| pages | array[[storefront page](#storefront-page-structure) object] | The pages of the storefront (max 5) |
Delete Application Storefront
Deletes the application's storefront. Returns a 204 empty response on success. User must be the owner of the application or developer of the owning team.
Get Guild Application SKU Storefront
Returns the storefront associated with the given SKU ID.
This endpoint is deprecated. It is replaced by [Get Application SKU Storefront](#get-application-sku-storefront).
###### Response Body
| Field | Type | Description |
| ------------------- | ------------------------------------------------------------ | ----------------------- |
| store_listing | [store listing](#store-listing-object) object | The store listing |
| assets | array[[store asset](#store-asset-object) object] | The store assets |
| storefront_metadata | [storefront metadata](#storefront-metadata-structure) object | The storefront metadata |
| storefront_pricing | [storefront prices](#storefront-prices-object) object | The storefront prices |
###### Storefront Metadata Structure
| Field | Type | Description |
| -------------------------- | --------- | ---------------------------------------------- |
| logo_asset_id? | snowflake | The ID of the logo store asset |
| light_theme_logo_asset_id? | snowflake | The ID of the logo store asset for light theme |
Get Application SKU Storefront
Returns the storefront associated with the given SKU ID.
###### Query String Parameters
| Field | Type | Description |
| -------------------- | ------- | --------------------------------------------------------------------------------------- |
| with_google_sku_ids? | boolean | Whether to include Google Play SKU ID mappings (default false) |
| country_code? | string | The [ISO 3166-1 alpha-2](https://en.wikipedia.org/wiki/ISO_3166-1_alpha-2) country code |
| payment_gateway? | integer | The [payment gateway](/resources/billing#payment-gateway) (only `APPLE` is allowed) |
###### Response Body
| Field | Type | Description |
| ------------------- | ------------------------------------------------------------ | ----------------------- |
| store_listing | [store listing](#store-listing-object) object | The store listing |
| assets | array[[store asset](#store-asset-object) object] | The store assets |
| storefront_metadata | [storefront metadata](#storefront-metadata-structure) object | The storefront metadata |
| storefront_pricing | [storefront prices](#storefront-prices-object) object | The storefront prices |
Get Guild Application Storefront Announcement
Returns the most recent announcement on the storefront for the application linked to the given guild ID.
###### Response Body
| Field | Type | Description |
| ------------------------- | --------- | ------------------------------------------ |
| id | snowflake | The ID of the announcement |
| application_id | snowflake | The ID of the application |
| application_name | string | The name of the application |
| asset_id | snowflake | The ID of the announcement store asset |
| background_image_asset_id | snowflake | The ID of the background image store asset |
###### Example Response
```json
{
"id": "1461677124166483968",
"application_id": "1346069614634864772",
"application_name": "Marvel Rivals",
"asset_id": "1461676869303664640",
"background_image_asset_id": "1461676874102214730"
}
```
Check Social Layer SKU Purchase Eligibility By Guild
Creates a [`SOCIAL_LAYER_SKU_PURCHASE_ELIGIBILITY`](/interactions/receiving-and-responding#interaction-type) interaction used to check whether the user is eligible to purchase a social layer SKU.
This endpoint is deprecated. It is replaced by [Check Social Layer SKU Purchase Eligibility](#check-social-layer-sku-purchase-eligibility).
###### Response Body
| Field | Type | Description |
| -------------- | --------- | --------------------------------- |
| interaction_id | snowflake | The ID of the created interaction |
Check Social Layer SKU Purchase Eligibility
Creates a [`SOCIAL_LAYER_SKU_PURCHASE_ELIGIBILITY`](/interactions/receiving-and-responding#interaction-type) interaction used to check whether the user is eligible to purchase a social layer SKU.
###### Response Body
| Field | Type | Description |
| -------------- | --------- | --------------------------------- |
| interaction_id | snowflake | The ID of the created interaction |
Get Social Layer Storefront Config
Returns the promotion currently running for Social Layer integrated storefronts.
###### Response Body
| Field | Type | Description |
| ---------------------- | --------------------------------------------------------------- | ----------------------------------------- |
| promotional_sku_ids | array[snowflake] | The IDs of the promotional store listings |
| promotion_end_datetime | ?ISO8601 timestamp | When the promotion ends |
| storefronts | array[[storefront config](#storefront-config-structure) object] | The storefronts |
###### Storefront Config Structure
| Field | Type | Description |
| ------------------------------------ | ------------- | -------------------------------------------------------------------------------------------------------------------- |
| guild_id | snowflake | The ID of the guild |
| application_id | snowflake | The ID of the application |
| game_id | snowflake | The ID of the game |
| collectibles_shop_navigation_enabled | boolean | Whether navigation is enabled in the game collectible shop |
| excluded_platforms | array[string] | The [platforms](#storefront-platform-type) that the game does not support account linking for accepting purchases on |
| disable_mobile_account_linking | boolean | Whether account linking is disabled on mobile |
###### Storefront Platform Type
| Value | Description |
| ----------- | ----------- |
| desktop | Desktop |
| xbox | Xbox |
| playstation | PlayStation |
Get Social Layer Storefront Eligibilities
Returns a mapping of application IDs to [storefront eligibility](#storefront-eligibility-structure) objects.
###### Storefront Eligibility Structure
| Field | Type | Description |
| ----------- | ------- | ------------------------------------------------------------- |
| is_eligible | boolean | Whether the application is eligible for setting up storefront |
---
# Promotions
Link: https://docs.discord.food/resources/promotion
Promotions are special offers that users can redeem for various benefits, such as discounts or free trials. Outbound promotions are offers to third-party services, while inbound promotions are in-platform offers sponsored by third-party services.
### Promotion Object
###### Promotion Structure
| Field | Type | Description |
| --------------------------------------- | ------------------------------------------------------------------------------------ | --------------------------------------------------------------------------------------------------------------------------------------------- |
| id | snowflake | The ID of the promotion |
| trial_id? | snowflake | The ID of the subscription trial associated with the promotion |
| start_date | ISO8601 timestamp | When the promotion starts |
| end_date | ISO8601 timestamp | When the promotion ends |
| outbound_redemption_end_date? | ISO8601 timestamp | When the promotion's redemption period ends |
| inbound_header_text? | string | The title of the inbound promotion |
| inbound_body_text? | string | The description of the inbound promotion |
| inbound_help_center_link? | string | The help center link of the inbound promotion |
| outbound_title? | string | The title of the outbound promotion |
| outbound_redemption_modal_body? | string | The description of the outbound promotion |
| outbound_terms_and_conditions? | string | The terms and conditions of the promotion |
| outbound_redemption_page_link? ^1^ | string | The redemption page to claim the outbound promotion |
| outbound_redemption_url_format? ^1^ ^2^ | string | The redemption page to claim the outbound promotion |
| flags? | integer | The [promotion's flags](#promotion-flags) |
| inbound_restricted_countries? | array[string] | The [ISO 3166-1 alpha-2](https://en.wikipedia.org/wiki/ISO_3166-1_alpha-2) codes of countries that the inbound promotion is not available in |
| outbound_restricted_countries? | array[string] | The [ISO 3166-1 alpha-2](https://en.wikipedia.org/wiki/ISO_3166-1_alpha-2) codes of countries that the outbound promotion is not available in |
| promotion_type | integer | The [type of promotion](#promotion-type) |
| partner_id? | string | The [type of promotion partner](#promotion-partner-type) |
| marketing_components? | array[[promotion marketing component](#promotion-marketing-component-object) object] | The components used in marketing |
^1^ Only either `outbound_redemption_page_link` or `outbound_redemption_url_format` will be present.
^2^ This field is a formatted string. `{code}` should be replaced with the claimed `code`.
###### Promotion Flags
| Value | Name | Description |
| -------- | ------------------------------------- | ------------------------------------------------ |
| 1 \<\< 5 | IS_BLOCKED_IOS | Promotion is not shown on iOS |
| 1 \<\< 6 | IS_OUTBOUND_REDEEMABLE_BY_TRIAL_USERS | Promotion is redeemable by trial user |
| 1 \<\< 7 | SUPPRESS_NOTIFICATION | Notifications about the promotion are suppressed |
###### Promotion Type
| Value | Name | Description |
| ----- | -------------------- | ------------------------------ |
| 0 | THIRD_PARTY | Third-party promotion |
| 1 | BOGO | BOGO promotion |
| 3 | THIRD_PARTY_INBOUND | Third-party inbound promotion |
| 4 | THIRD_PARTY_OUTBOUND | Third-party outbound promotion |
| 5 | MARKETING_MOMENT | Marketing moment |
| 6 | GIFT_PROMOTION | Gift promotion |
###### Promotion Partner Type
| Value | Description |
| ------------ | --------------------------------------------- |
| steelseries | [SteelSeries](https://steelseries.com/) |
| kontrolfreek | [KontrolFreek](https://www.kontrolfreek.com/) |
### Promotion Marketing Component Object
###### Promotion Marketing Component Structure
| Field | Type | Description |
| -------------- | --------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| component_type | integer | The [type of marketing component](#promotion-marketing-component-type) |
| id | integer | The ID of the component |
| promotion_id | snowflake | The ID of the promotion |
| properties | string | The base64-encoded serialized [PremiumMarketingComponentProperties](https://github.com/discord-userdoccers/discord-protos/blob/master/discord_protos/premium_marketing/v1/PremiumMarketingComponentProperties.proto) protobuf |
###### Promotion Marketing Component Type
| Value | Name | Description |
| ----- | --------------------- | ---------------------- |
| 0 | ANNOUNCEMENT_MODAL | Annonucement modal |
| 1 | PREMIUM_TAB | Premium tab |
| 2 | MARKETING_PAGE_BANNER | Marketing page banner |
| 3 | PAYMENT_MODAL_BANNER | Payment modal banner |
| 4 | MOBILE_BOTTOM_SHEET | Bottom sheet on mobile |
### Claimed Promotion Object
###### Claimed Promotion Structure
| Field | Type | Description |
| ---------- | ------------------------------------- | -------------------------------------------- |
| code | string | The code of the claimed promotion |
| user_id | snowflake | The ID of the user who claimed the promotion |
| claimed_at | ISO8601 timestamp | When the promotion was claimed at |
| promotion | [promotion](#promotion-object) object | The promotion |
## Endpoints
List Outbound Promotions
Returns a list of [promotion](#promotion-object) objects the current user is eligible for.
###### Query String Params
| Field | Type | Description |
| --------- | ------- | -------------------------------------------------------------- |
| locale? | string | The [language](/reference#locales) to return promotions in |
| platform? | integer | The [platform](#promotion-platform-type) to get promotions for |
###### Promotion Platform Type
| Value | Name | Description |
| ----- | ------- | ----------- |
| 0 | DESKTOP | Desktop |
| 1 | MOBILE | Mobile |
List Promotions
Returns a list of [promotion](#promotion-object) objects the current user is eligible for.
###### Query String Params
| Field | Type | Description |
| --------- | ------- | -------------------------------------------------------------- |
| locale? | string | The [language](/reference#locales) to return promotions in |
| platform? | integer | The [platform](#promotion-platform-type) to get promotions for |
List BOGO Promotions
Same as above, except only returns promotions of type [`BOGO`](#promotion-type).
###### Query String Params
| Field | Type | Description |
| ------- | ------ | ---------------------------------------------------------- |
| locale? | string | The [language](/reference#locales) to return promotions in |
List Claimed Promotions
Returns a list of [claimed promotion](#claimed-promotion-object) for the current user.
###### Query String Params
| Field | Type | Description |
| ------- | ------ | ---------------------------------------------------------- |
| locale? | string | The [language](/reference#locales) to return promotions in |
Claim Promotion
Claims a promotion. Returns a [claimed promotion](#claimed-promotion-object) object on success.
---
# Relationships
Link: https://docs.discord.food/resources/relationships
Relationships in Discord are used to represent friendships, pending friend requests, and blocked users. Game relationships are used to distinguish special bonds created while in-game.
Users may have a maximum of 1,000 friends and 5,000 blocked users.
### Relationship Object
A relationship between the current user and another user.
###### Relationship Structure
| Field | Type | Description |
| ---------------------- | ------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------- |
| id | string | The ID of the target user |
| type | integer | The [type](#relationship-type) of relationship |
| user | partial [user](/resources/user#user-object) | The target user |
| nickname | ?string | The nickname of the user in this relationship (1-32 characters) |
| is_spam_request? | boolean | Whether the friend request was flagged as spam (default false) |
| stranger_request? | boolean | Whether the friend request was sent by a user without a mutual friend or small mutual guild (default false) |
| user_ignored | boolean | Whether the target user has been [ignored](https://support.discord.com/hc/en-us/articles/28084948873623) by the current user |
| origin_application_id? | ?snowflake | The ID of the application that created the relationship |
| since? | ISO8601 timestamp | When the user requested a relationship |
| has_played_game? ^1^ | boolean | Whether the target user has authorized the same application the current user's session is associated with |
| note? | string | The personalized note written when creating the friend request |
^1^ Only available in [OAuth2 contexts](/gateway/using-gateway#oauth2-and-the-gateway).
###### Relationship Type
| Value | Name | Description |
| ----- | ---------------- | -------------------------------------------------------- |
| 0 | NONE | No relationship exists |
| 1 | FRIEND | The user is a friend |
| 2 | BLOCKED | The user is blocked |
| 3 | INCOMING_REQUEST | The user has sent a friend request to the current user |
| 4 | OUTGOING_REQUEST | The current user has sent a friend request to the user |
| 5 | IMPLICIT | The user is an affinity of the current user |
| ~~6~~ | ~~SUGGESTION~~ | ~~The user is a friend suggestion for the current user~~ |
###### Example Relationship
```json
{
"id": "852892297661906993",
"type": 3,
"nickname": null,
"user_ignored": false,
"user": {
"id": "852892297661906993",
"username": "alien",
"global_name": "Alien",
"avatar": "14733482e560d9267c0a414b21b2fb8d",
"discriminator": "0",
"public_flags": 64,
"avatar_decoration_data": null,
"primary_guild": null
},
"is_spam_request": false,
"since": "2023-02-10T01:58:05.348000+00:00",
"stranger_request": false,
"note": "Saw you flying by..."
}
```
### Game Relationship Object
An in-game relationship between the current user and another user, created using the social layer SDK.
###### Game Relationship Structure
| Field | Type | Description |
| -------------- | ------------------------------------------- | --------------------------------------------------------------------- |
| id | string | The ID of the target user |
| application_id | snowflake | The ID of the application whose game the relationship originated from |
| type | integer | The [type](#game-relationship-type) of relationship |
| user ^1^ | partial [user](/resources/user#user-object) | The target user |
| since | ISO8601 timestamp | When the user requested a relationship |
| dm_access_type | integer | The [DM access level](#dm-access-type) for the relationship |
| user_id | snowflake | The ID of the current user |
^1^ Not included when fetching game relationships via OAuth2.
###### Game Relationship Type
This enum is a subset of the [relationship type](#relationship-type) enum, supporting only `FRIEND`, `INCOMING_REQUEST`, and `OUTGOING_REQUEST`.
###### DM Access Type
The values of this enum are currently unknown. Help us by figuring them out and [submitting a pull request](https://github.com/discord-userdoccers/discord-userdoccers/edit/master/pages/resources/relationships.mdx)!
###### Example Game Relationship
```json
{
"user_id": "852892297661906993",
"application_id": "1237856342484717650",
"id": "1001086404203389018",
"type": 1,
"since": "2025-01-22T00:26:18.616000+00:00",
"dm_access_type": 0,
"user": {
"id": "1001086404203389018",
"username": ".dziurwa",
"global_name": "Dziurwa💕",
"avatar": "f6c0363fbab45668fcf8f88fea56db9c",
"avatar_decoration_data": null,
"discriminator": "0",
"public_flags": 4210944,
"primary_guild": null
}
}
```
### Friend Suggestion Object
A friend suggestion for the current user.
###### Friend Suggestion Structure
| Field | Type | Description |
| ----------------------------- | ----------------------------------------------------------------------------- | ------------------------------------------------------------------------- |
| suggested_user | partial [user](/resources/user#user-object) object | The suggested user |
| reasons | array[[friend suggestion reason](#friend-suggestion-reason-structure) object] | The sources of the suggestion |
| from_suggested_user_contacts? | boolean | Whether the suggested user has the current user in their contacts |
| mutual_friends_count? | integer | The number of mutual friends the current user has with the suggested user |
| contact_names? | array[string] | Contact names associated with the suggested user |
###### Friend Suggestion Reason Structure
| Field | Type | Description |
| -------- | ------- | ------------------------------------------------------------------------------------------------- |
| type | integer | The [type of reason](#friend-suggestion-reason-type) |
| platform | string | The [platform that the suggestion originated from](/resources/connected-accounts#connection-type) |
| name | string | The user's name on the platform |
###### Friend Suggestion Reason Type
| Value | Name | Description |
| ----- | --------------- | ---------------------------------------- |
| 1 | EXTERNAL_FRIEND | The user is a friend on another platform |
###### Example Friend Suggestion
```json
{
"suggested_user": {
"id": "852892297661906993",
"username": "alien",
"global_name": "Alien",
"avatar": "14733482e560d9267c0a414b21b2fb8d",
"discriminator": "0",
"public_flags": 64,
"avatar_decoration_data": null,
"primary_guild": null
},
"reasons": [
{
"type": 1,
"platform_type": "contacts",
"name": "Gnarpy"
}
]
}
```
## Endpoints
List Relationships
Returns a list of [relationship](#relationship-object) objects for the current user.
For OAuth2 requests, only relationships of type `FRIEND` are returned.
Send Friend Request
Sends a friend request to another user, which can be accepted by creating a new relationship of type `FRIEND`.
Returns a 204 empty response on success. Fires a [Relationship Add](/gateway/gateway-events#relationship-add) Gateway event.
Clients should not use this endpoint to create many friend requests in a short period of time.
Suspicious friend request activity may be flagged by Discord and require [additional verification steps](/resources/user#required-action-type) or lead to immediate account termination.
###### JSON Params
| Field | Type | Description |
| ----------------- | ------- | ------------------------------------------------------------------------ |
| username | string | The username of the user to send a friend request to |
| discriminator ^1^ | ?string | The discriminator of the user to send a friend request to |
| note? | ?string | A personalized note to send with the friend request (max 120 characters) |
^1^ `null` for migrated users. See the [section on Discord's new username system](/resources/user#unique-usernames) for more information.
Create Relationship
Creates a relationship with another user. Returns a 204 empty response on success. Fires a [Relationship Add](/gateway/gateway-events#relationship-add) Gateway event.
Clients should not use this endpoint to create many friend requests in a short period of time.
Suspicious friend request activity may be flagged by Discord and require [additional verification steps](/resources/user#required-action-type) or lead to immediate account termination.
###### JSON Params
| Field | Type | Description |
| ------------------------- | ------- | --------------------------------------------------------------------------------------------------------------------------------- |
| type? | integer | The [relationship type](#relationship-type) to create (defaults to -1, which accepts an existing or creates a new friend request) |
| from_friend_suggestion? | boolean | Whether the relationship was created from a friend suggestion (default false) |
| confirm_stranger_request? | boolean | Whether the user consents to accepting a stranger's friend request (default false) |
| note? | ?string | A personalized note to send with the friend request (max 120 characters) |
Ignore User
[Ignores](https://support.discord.com/hc/en-us/articles/28084948873623) a user. Returns a 204 empty response on success. Fires a [Relationship Add](/gateway/gateway-events#relationship-add) or [Relationship Update](/gateway/gateway-events#relationship-update) Gateway event.
Unignore User
Unignores a user. Returns a 204 empty response on success. Fires a [Relationship Update](/gateway/gateway-events#relationship-update) or [Relationship Remove](/gateway/gateway-events#relationship-remove) Gateway event.
Modify Relationship
Modifies a relationship to another user. Returns a 204 empty response on success. Fires a [Relationship Update](/gateway/gateway-events#relationship-update) Gateway event.
###### JSON Params
| Field | Type | Description |
| ------------- | ------ | --------------------------------------------------------------- |
| nickname? ^1^ | string | The nickname of the user in this relationship (1-32 characters) |
^1^ Only applicable to relationships of type `FRIEND`.
Remove Relationship
Removes a relationship with another user. Returns a 204 empty response on success. Fires a [Relationship Remove](/gateway/gateway-events#relationship-remove) Gateway event.
Bulk Remove Relationships
Removes multiple relationships. Returns a 204 empty response on success. May fire multiple [Relationship Remove](/gateway/gateway-events#relationship-remove) Gateway events.
###### Query String Params
| Field | Type | Description |
| --------------------------- | ------- | --------------------------------------------------------------------------------------------------------------------------------------- |
| relationship_type? | integer | Remove relationships with this [relationship type](#relationship-type) (default `INCOMING_REQUEST`, only `INCOMING_REQUEST` is allowed) |
| only_spam? **(deprecated)** | boolean | Whether to remove relationships that were flagged as spam (default false) |
###### JSON Params
| Field | Type | Description |
| -------- | -------------- | -------------------------------------------------------------------------------------------------- |
| filters? | array[integer] | The [relationship removal filters](#relationship-removal-filter) to match against, using AND logic |
###### Relationship Removal Filter
| Value | Name | Description |
| ----- | ------- | ------------------------------------------ |
| 1 | SPAM | Friend requests flagged by Discord as spam |
| 2 | IGNORED | Ignored users |
Bulk Add Relationships
Adds multiple relationships from [contact sync](/resources/connected-accounts#update-external-friend-list-entries). May fire multiple [Relationship Add](/gateway/gateway-events#relationship-add) Gateway events.
###### JSON Params
| Field | Type | Description |
| -------- | ---------------- | ---------------------------------------------------------------------------------------------------- |
| user_ids | array[snowflake] | IDs of users to add |
| token | string | The [contact sync](/resources/connected-accounts#update-external-friend-list-entries) bulk add token |
###### Response Body
| Field | Type | Description |
| ------------------- | ---------------- | -------------------------------------------------- |
| failed_requests | array[snowflake] | IDs of the users who could not be friend requested |
| successful_requests | array[snowflake] | IDs of the users who were friend requested |
List Game Relationships
Returns a list of [game relationship](#game-relationship-object) objects for the current user.
For OAuth2 requests, only game relationships originating from the same application as the requestor are returned.
Send Game Friend Request
Sends a game friend request to another user, which can be accepted in-game by [creating a new game relationship of type `FRIEND`](#create-game-relationship), or [by the user independently](#create-game-relationship-by-application).
Returns a 204 empty response on success. Fires a [Game Relationship Add](/gateway/gateway-events#game-relationship-add) Gateway event.
This endpoint is only usable with an OAuth2 access token with the `relationships.write` scope.
The target user must have the same application as the requestor authorized to create a game relationship.
###### JSON Params
| Field | Type | Description |
| -------- | ------ | --------------------------------------------------------- |
| username | string | The username of the user to send a game friend request to |
Create Game Relationship
Creates a game relationship with another user. Returns a 204 empty response on success. Fires a [Game Relationship Add](/gateway/gateway-events#game-relationship-add) Gateway event.
This endpoint is only usable with an OAuth2 access token with the `relationships.write` scope.
The target user must have the same application as the requestor authorized to create a game relationship.
| Field | Type | Description |
| ----- | ------- | -------------------------------------------------------------------------------------------------------------------------------------- |
| type? | integer | The [relationship type](#game-relationship-type) to create (defaults to -1, which accepts an existing or creates a new friend request) |
Create Game Relationship by Application
Accepts a game relationship from another user on a specific application. Returns a 204 empty response on success. Fires a [Game Relationship Add](/gateway/gateway-events#game-relationship-add) Gateway event.
| Field | Type | Description |
| ----- | ------- | ------------------------------------------------------------------------------------- |
| type? | integer | The [relationship type](#game-relationship-type) to create (only `FRIEND` is allowed) |
Remove Game Relationship
Removes a game relationship with another user. Returns a 204 empty response on success. Fires a [Game Relationship Remove](/gateway/gateway-events#game-relationship-remove) Gateway event.
This endpoint is only usable with an OAuth2 access token with the `relationships.write` scope.
Remove Game Relationship by Application
Removes a game relationship with another user. Returns a 204 empty response on success. Fires a [Game Relationship Remove](/gateway/gateway-events#game-relationship-remove) Gateway event.
List Friend Suggestions
Returns a list of [friend suggestion](#friend-suggestion-object) objects for the current user.
Remove Friend Suggestion
Removes a friend suggestion for the current user. Returns a 204 empty response on success. Fires a [Friend Suggestion Delete](/gateway/gateway-events#friend-suggestion-delete) Gateway event.
---
# Invites
Link: https://docs.discord.food/resources/invite
Invites are used by users to join a guild or group DM, or to add a user to their friends list.
### Temporary Invites
Temporary invites (indicated by the [`temporary` field](#invite-object)) grant non-permanent access to a guild. Upon [accepting a temporary invite](#accept-invite), the user is added to the guild and can interact with it unconditionally until all of their sessions are disconnected. If the user does not have an active session at the time of accepting the invite, they will be removed after the next time they disconnect.
If the user is granted a role after accepting a temporary invite, they will become permanent members of the guild.
###### Guest Invites
Guest invites (indicated by the [`flags` field](#invite-object)), similar to temporary invites, also grant non-permanent access to a guild. However, unlike temporary invites, upon [accepting a guest invite](#accept-invite), the user does not become a member of the guild. The session ID provided during acceptance is dispatched a [Guild Create](/gateway/gateway-events#guild-create) event containing only the channel the invite was for, and the user receives no other guild-specific events (except for [Guild Delete](/gateway/gateway-events#guild-delete) when they are removed). Guest access only allows using a subset of endpoints required for interacting with voice channels, and access is removed after the user disconnects from the voice channel.
### Invite Object
A code that when used, adds a user to a guild or group DM channel, or creates a relationship between two users.
###### Invite Structure
| Field | Type | Description |
| ------------------------------- | --------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------- |
| code | string | The invite code (unique ID) |
| type | integer | The [type of invite](#invite-type) |
| channel | ?partial [channel](/resources/channel#channel-object) object | The channel this invite is for; `null` for friend invites that did not have a DM channel created |
| guild_id? | snowflake | The ID of the guild this invite is for |
| guild? | [invite guild](#invite-guild-object) object | The guild this invite is for |
| profile? | [guild profile](/resources/discovery#guild-profile-object) object | The profile of the guild this invite is for |
| inviter? | partial [user](/resources/user#user-object) object | The user who created the invite |
| flags? | integer | The [invite's flags](#invite-flags) |
| target_type? | integer | The [type of target](#invite-target-type) for this guild invite |
| target_user? | partial [user](/resources/user#user-object) object | The user whose stream to display for this voice channel stream invite |
| target_application? | partial [application](/resources/application#application-object) object | The embedded application to open for this voice channel embedded application invite |
| roles? ^5^ | array[partial [role](/resources/guild#role-object) object] | The roles to grant to the invitee upon acceptance |
| approximate_member_count? ^1^ | integer | Approximate count of total members in the guild or group DM |
| approximate_presence_count? ^1^ | integer | Approximate count of non-offline members in the guild |
| expires_at | ?ISO8601 timestamp | The expiry date of the invite, if it expires |
| guild_scheduled_event? | [guild scheduled event](/resources/guild-scheduled-event#guild-scheduled-event-object) object | Guild scheduled event data, only included if `guild_scheduled_event_id` contains a valid guild scheduled event ID |
| new_member? ^2^ | boolean | Whether the user is a new member of the guild |
| show_verification_form? ^2^ | boolean | Whether the user should be shown the guild's [member verification](/resources/guild#member-verification-object) form |
| is_nickname_changeable? ^3^ | boolean | Whether the @everyone role has the `CHANGE_NICKNAME` permission in the guild this invite is for |
| target_users_job_status? ^4^ | [invite target users job](#invite-target-users-job-object) object | The status of the target users file processing job for the given invite |
^1^ Only included when fetched from the [Get Invite](#get-invite) endpoint with `with_counts` set to `true`. Also included when fetched from the [Accept Invite](#accept-invite) endpoint on [non-previewable guilds](/resources/guild#guild-previewing).
^2^ Only included when fetched from the [Accept Invite](#accept-invite) endpoint. Note that `new_member` is erroneously set to `true` for non-guild invites and is missing when accepting an invite to a [non-previewable guild](/resources/guild#guild-previewing).
^3^ Only included when fetched from the [Get Invite](#get-invite) endpoint with `with_permissions` set to `true`.
^4^ Only included when fetched from the [List Guild Invites](#list-guild-invites) endpoint.
^5^ Partial role objects contain `id`, `name`, `position`, `color`, `colors`, `icon`, and `unicode_emoji`
###### Invite Type
| Value | Name | Description |
| ----- | -------- | ---------------------------------------------------------------------------------------- |
| 0 | GUILD | Joins the user to a [guild](/resources/guild#guild-object) |
| 1 | GROUP_DM | Joins the user to a [group DM](/resources/channel#channel-object) |
| 2 | FRIEND | Adds the user as a [friend](/resources/relationships#relationship-object) to the inviter |
###### Invite Target Type
| Value | Name | Description |
| ----- | ---------------------- | ------------------------------------------------------------------------------------------------------------ |
| 1 | STREAM | The invite is for a stream in a [voice channel](/resources/channel#channel-object) |
| 2 | EMBEDDED_APPLICATION | The invite is for an embedded application (activity) in a [voice channel](/resources/channel#channel-object) |
| 3 | ROLE_SUBSCRIPTIONS ^1^ | The invite redirects to the role subscriptions page within a [guild](/resources/guild#guild-object) |
| 4 | CREATOR_PAGE ^1^ | The invite originates from the creator page of a [guild](/resources/guild#guild-object) |
| 5 | LOBBY ^1^ | The invite is for a lobby member |
^1^ Invites with these target types are not returned in the [List Guild Invites](#list-guild-invites) and [List Channel Invites](#list-channel-invites) endpoints.
They are also not deletable through [Delete Invite](#delete-invite).
###### Invite Flags
| Value | Name | Description |
| -------- | --------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------- |
| 1 \<\< 0 | IS_GUEST_INVITE | Invite grants one-time access to a voice channel in the guild |
| 1 \<\< 1 | IS_VIEWED | Invite has been viewed by any user (has been retrieved using [Get Invite](#get-invite)) |
| 1 \<\< 2 | IS_ENHANCED | Unknown |
| 1 \<\< 3 | IS_APPLICATION_BYPASS | Invite bypasses [guild join requests](/resources/guild#guild-join-request-object) and adds the user directly to the guild with `pending` set to `false` |
###### Example Invite Object
```json
{
"type": 0,
"code": "jvuBeT38",
"inviter": {
"id": "852892297661906993",
"username": "alien",
"avatar": "05145cc5646fbcba277b6d5ea2030610",
"discriminator": "0",
"public_flags": 4194432,
"banner": null,
"accent_color": null,
"global_name": "Alien",
"avatar_decoration_data": null,
"primary_guild": null
},
"expires_at": "2023-07-22T18:30:11+00:00",
"guild": {
"id": "1046920999469330512",
"name": "Alien Network",
"splash": "b40e61f7730b8781b9a551964570e0cc",
"banner": "a_98d07f130569f17e8352df80c3a2bc2b",
"description": "Where the 👽s 👽 and sometimes very 👽 things happen 😨.",
"icon": "66b0f4d96c145970fa9d96ada8afadf3",
"features": [],
"verification_level": 2,
"vanity_url_code": "alien",
"premium_subscription_count": 14,
"nsfw": false,
"nsfw_level": 0
},
"guild_id": "1046920999469330512",
"channel": {
"id": "1057241425793798144",
"type": 2,
"name": "alien noises"
},
"target_type": 2,
"target_application": {
"id": "880218394199220334",
"name": "Watch Together",
"icon": "ec48acbad4c32efab4275cb9f3ca3a58",
"description": "Create and watch a playlist of YouTube videos with your friends. Your choice to share the remote or not. ",
"type": null,
"is_monetized": false,
"is_verified": false,
"is_discoverable": false,
"cover_image": "3cc9446876ae9eec6e06ff565703c292",
"bot": {
"id": "880218394199220334",
"username": "Watch Together",
"avatar": "fe2b7fa334817b0346d57416ad75e93b",
"discriminator": "5319",
"public_flags": 0,
"bot": true,
"banner": null,
"accent_color": null,
"global_name": null,
"avatar_decoration_data": null,
"primary_guild": null
},
"summary": "",
"bot_public": false,
"bot_require_code_grant": false,
"terms_of_service_url": "https://discord.com/terms",
"privacy_policy_url": "https://discord.com/privacy",
"verify_key": "e2aaf50fbe2fd9d025ac669035f5efb89099931690fba9dc28efb7eaade7f96d",
"flags": 1179648,
"max_participants": -1,
"tags": ["Video Player", "Watch"],
"hook": true,
"storefront_available": false,
"embedded_activity_config": {
"activity_preview_video_asset_id": "1104184163201990836",
"supported_platforms": ["web", "ios", "android"],
"default_orientation_lock_state": 2,
"tablet_default_orientation_lock_state": 1,
"requires_age_gate": false,
"legacy_responsive_aspect_ratio": false,
"premium_tier_requirement": null,
"free_period_starts_at": null,
"free_period_ends_at": null,
"client_platform_config": {
"ios": { "label_type": 0, "label_until": null, "release_phase": "global_launch" },
"android": { "label_type": 0, "label_until": null, "release_phase": "global_launch" },
"web": { "label_type": 0, "label_until": null, "release_phase": "global_launch" }
},
"shelf_rank": 3,
"has_csp_exception": false,
"displays_advertisements": false
}
},
"approximate_member_count": 100,
"approximate_presence_count": 99,
"is_nickname_changeable": true
}
```
### Invite Metadata Object
Extra information about an invite, will extend the [invite](#invite-object) object.
###### Invite Metadata Structure
| Field | Type | Description |
| -------------- | ----------------- | ------------------------------------------------------------------------------------------------- |
| uses? ^1^ | integer | Number of times this invite has been used |
| max_uses? ^1^ | integer | Max number of times this invite can be used |
| max_age? | integer | Duration (in seconds) after which the invite expires (default 0) |
| temporary? ^2^ | boolean | Whether this invite only grants temporary membership (default false for unsupported invite types) |
| created_at | ISO8601 timestamp | When this invite was created |
^1^ This information is not tracked or returned for group DM invites. However, they always have a `max_uses` of 0.
^2^ [Temporary invites](#temporary-invites) are only supported for guilds.
###### Example Invite with Metadata Object
```json
{
"type": 0,
"code": "jvuBeT38",
"inviter": {
"id": "852892297661906993",
"username": "alien",
"avatar": "05145cc5646fbcba277b6d5ea2030610",
"discriminator": "0",
"public_flags": 4194432,
"banner": null,
"accent_color": null,
"global_name": "Alien",
"avatar_decoration_data": null,
"primary_guild": null
},
"max_age": 604800,
"created_at": "2023-07-15T18:30:11.047000+00:00",
"expires_at": "2023-07-22T18:30:11+00:00",
"guild": {
"id": "1046920999469330512",
"name": "Alien Network",
"splash": "b40e61f7730b8781b9a551964570e0cc",
"banner": "a_98d07f130569f17e8352df80c3a2bc2b",
"description": "Where the 👽s 👽 and sometimes very 👽 things happen 😨.",
"icon": "66b0f4d96c145970fa9d96ada8afadf3",
"features": [],
"verification_level": 2,
"vanity_url_code": "alien",
"nsfw_level": 0,
"nsfw": false,
"premium_subscription_count": 14,
"premium_tier": 3
},
"guild_id": "1046920999469330512",
"channel": {
"id": "1057241425793798144",
"type": 2,
"name": "alien noises"
},
"uses": 0,
"max_uses": 0,
"temporary": false
}
```
### Invite Guild Object
The guild an invite is for.
###### Invite Guild Structure
| Field | Type | Description |
| --------------------------- | ------------- | ------------------------------------------------------------------------------------ |
| id | snowflake | The ID of the guild |
| name | string | The name of the guild (2-100 characters) |
| icon | ?string | The guild's [icon hash](/reference#cdn-formatting) |
| description | ?string | The description for the guild (max 300 characters) |
| banner | ?string | The guild's [banner hash](/reference#cdn-formatting) |
| splash | ?string | The guild's [splash hash](/reference#cdn-formatting) |
| verification_level | integer | The [verification level](/resources/guild#verification-level) required for the guild |
| features | array[string] | Enabled [guild features](/resources/guild#guild-features) |
| vanity_url_code | ?string | The guild's vanity invite code |
| premium_subscription_count? | integer | The number of premium subscriptions (boosts) the guild currently has |
| premium_tier | integer | The guild's [premium tier](/resources/guild#premium-tier) (boost level) |
| nsfw **(deprecated)** | boolean | Whether the guild is considered NSFW (`EXPLICIT` or `AGE_RESTRICTED`) |
| nsfw_level | integer | The guild's [NSFW level](/resources/guild#nsfw-level) |
### Invite Target Users Job Object
The status of the target users file processing job for an invite.
###### Invite Target Users Job Structure
| Field | Type | Description |
| --------------- | ------------------ | ------------------------------------------------------------------------------------ |
| status | integer | The [status](#invite-target-users-job-status) of the job processing the target users |
| total_users | integer | The total number of user IDs in the target users file |
| processed_users | integer | The number of user IDs processed so far |
| created_at | ?ISO8601 timestamp | When the job was created |
| completed_at | ?ISO8601 timestamp | When the job was completed |
| error_message | ?string | An error message, if the job failed |
###### Invite Target Users Job Status
| Value | Name | Description |
| ----- | ----------- | ------------------------------------ |
| 0 | UNSPECIFIED | Job status is unspecified |
| 1 | PROCESSING | Job is currently being processed |
| 2 | COMPLETED | Job has been completed |
| 3 | FAILED | Job has failed (see `error_message`) |
## Endpoints
Get Invite
Returns an [invite](#invite-object) object for the given code.
Bots and users who have been blocked by the inviter cannot retrieve friend invites.
###### Query String Params
| Field | Type | Description |
| ------------------------- | --------- | ------------------------------------------------------------------------------------------------------------------------- |
| with_counts? | boolean | Whether the invite should contain approximate member counts (and partial recipients for group DM invites) (default false) |
| with_permissions? | boolean | Whether the invite should contain permission-related fields (default false) |
| guild_scheduled_event_id? | snowflake | The guild scheduled event to include with the invite |
List Invite Friend Members
Returns the user IDs of friends in the target guild. Always returns an empty array for group DMs and friend invites.
###### Response Body
| Field | Type | Description |
| ----------------- | ---------------- | --------------------------------------- |
| friend_member_ids | array[snowflake] | User IDs of friends in the target guild |
List Invite Target Users
Returns the IDs of the users allowed to see and accept the given invite. Invite must have a target users file associated with it. Requires the `MANAGE_GUILD` or `VIEW_AUDIT_LOG` permission if the requestor is not the inviter.
Return a CSV file with the header `user_id` and each user ID passed to [invite create](#create-channel-invite) on its own line.
Update Invite Target Users
Replaces the target users file associated with the given invite. Processing is done asynchronously. Invite must have been created with a target users file. Requires the `MANAGE_GUILD` permission if the requestor is not the inviter. Returns a 204 empty response on success.
###### Form Params
| Field | Type | Description |
| --------------------- | ------------- | --------------------------------------------------------------------- |
| target_users_file ^1^ | file contents | A CSV file with a single column of user IDs to restrict the invite to |
^1^ See [Uploading Files](/reference#uploading-files) for details.
Get Invite Target Users Job Status
Returns an [invite target users job](#invite-target-users-job-object) object for the given invite. Invite must have a target users file associated with it. Requires the `MANAGE_GUILD` or `VIEW_AUDIT_LOG` permission if the requestor is not the inviter.
Accept Invite
Accepts an invite to a [guild](#invite-guild-object), [group DM](/resources/channel#channel-object), or [DM](/resources/channel#channel-object). Returns an [invite](#invite-object) object on success. May fire a [Guild Create](/gateway/gateway-events#guild-create), [Guild Member Add](/gateway/gateway-events#guild-member-add), [Guild Join Request Create](/gateway/gateway-events#guild-join-request-create), [Channel Create](/gateway/gateway-events#channel-create), and/or [Relationship Add](/gateway/gateway-events#relationship-add) Gateway event.
Clients should not use this endpoint to join many guilds in a short period of time.
Suspicious guild join activity may be flagged by Discord and require [additional verification steps](/resources/user#required-action-type) or lead to immediate account termination.
Accepting an invite to a guild with the [`HUB` guild feature](/resources/guild#guild-features) will have no effect.
For OAuth2 requests, only guild invites are supported and the bot attached to the application must be a member of the guild the invite is for.
Users who have been blocked by the inviter cannot accept friend invites.
###### JSON Params
| Field | Type | Description |
| ----------- | ------ | ----------------------------------------------------------------------------------------- |
| session_id? | string | The session ID that is accepting the invite, required for [guest invites](#guest-invites) |
Delete Invite
Deletes an invite. Requires the `MANAGE_CHANNELS` permission on the channel this invite belongs to, or `MANAGE_GUILD` to remove any invite across the guild, if the invite is to a guild. Returns an [invite](#invite-object) object on success. May fire an [Invite Delete](/gateway/gateway-events#invite-delete) Gateway event.
List Guild Invites
Returns a list of [invite](#invite-object) objects for the guild. Requires the `MANAGE_GUILD` or `VIEW_AUDIT_LOG` permission. [Invite metadata](#invite-metadata-object) is included if the user has the `MANAGE_GUILD` permission.
List Channel Invites
Returns a list of [invite](#invite-object) objects (with [invite metadata](#invite-metadata-object)) for the channel. Only usable for guild channels and group DMs. Requires the `MANAGE_CHANNELS` permission if the channel is in a guild.
Create Channel Invite
Creates a new [invite](#invite-object) object for the channel. Only usable for guild channels and group DMs. Requires the `CREATE_INSTANT_INVITE` permission if the channel is in a guild. Returns an [invite](#invite-object) object (with [invite metadata](#invite-metadata-object)). Fires an [Invite Create](/gateway/gateway-events#invite-create) Gateway event if the channel is in a guild.
Users cannot create invites for managed group DMs.
In the case of a guild with the instant invite operation disabled by Discord, this endpoint will return an unexpected 204 empty response.
###### JSON/Form Params
| Field | Type | Description |
| ---------------------- | ---------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| flags? ^1^ | integer | The [invite's flags](#invite-flags) (only `IS_GUEST_INVITE` and `IS_APPLICATION_BYPASS` can be set) |
| max_age? ^2^ | integer | Number of seconds before expiry, or 0 for never (0-5184000, default 86400) |
| max_uses? | integer | Max number of uses or 0 for unlimited (0-100, default 0) |
| temporary? | boolean | Whether the invite only grants temporary membership (default false) |
| unique? | boolean | Whether to try to reuse a similar invite (useful for creating many unique one time use invites, default false) |
| target_type? | integer | The [type of target](#invite-target-type) for the invite |
| target_user_id? | snowflake | The ID of the user whose stream to display for the invite, required if `target_type` is `STREAM`; the user must be streaming in the channel |
| target_application_id? | snowflake | The ID of the embedded application to open for the invite, required if `target_type` is `EMBEDDED_APPLICATION`; the application must have the `EMBEDDED` flag |
| target_users_file? ^3^ | file contents | A CSV file with a single column of user IDs to restrict the invite to |
| role_ids? ^4^ | array[snowflake] | The IDs of the roles to grant to the invitee upon acceptance |
^1^ Creating an invite with the `APPLICATION_BYPASS` flag requires the `KICK_MEMBERS` permission.
^2^ For group DMs, `max_age` is the only supported parameter, and it accepts a value from 1 to 604800 (7 days).
^3^ Processing is done asynchronously. See [Uploading Files](/reference#uploading-files) for details.
^4^ Requires the `MANAGE_ROLES` permission. Cannot grant roles that are equal to or higher than the creator's highest role.
List User Invites
Returns a list of friend [invite](#invite-object) objects (with [invite metadata](#invite-metadata-object)) for the current user.
Create User Invite
Creates a new friend invite. Returns a friend [invite](#invite-object) object (with [invite metadata](#invite-metadata-object)) on success.
###### JSON Params
| Field | Type | Description |
| ----- | ------ | ------------------------------------------------------------- |
| code? | string | The pre-generated friend invite code to create an invite from |
Revoke User Invites
Revokes all of the current user's friend invites. Returns a list of revoked friend [invite](#invite-object) objects (with [invite metadata](#invite-metadata-object)) on success.
---
# Guilds
Link: https://docs.discord.food/resources/guild
Guilds in Discord represent an isolated collection of users and channels, and are often referred to as 'servers' in the UI.
### Guild Object
###### Guild Structure
| Field | Type | Description |
| -------------------------------------------- | ------------------------------------------------------------------------------------------ | ---------------------------------------------------------------------------------------------------------------------- |
| id | snowflake | The ID of the guild |
| name | string | The name of the guild (2-100 characters) |
| icon | ?string | The guild's [icon hash](/reference#cdn-formatting) |
| banner | ?string | The guild's [banner hash](/reference#cdn-formatting) |
| home_header | ?string | The guild's [home header hash](/reference#cdn-formatting), used in new member welcome |
| splash | ?string | The guild's [splash hash](/reference#cdn-formatting) |
| discovery_splash | ?string | The guild's [discovery splash hash](/reference#cdn-formatting) |
| owner_id | snowflake | The user ID of the guild's owner |
| application_id **(deprecated)** | ?snowflake | The application ID of the bot that created the guild |
| description | ?string | The description for the guild (max 300 characters) |
| region? **(deprecated)** | ?string | The main [voice region](/resources/voice#voice-region-object) ID of the guild |
| afk_channel_id | ?snowflake | The ID of the guild's AFK channel; this is where members in voice idle for longer than `afk_timeout` are moved |
| afk_timeout | integer | The AFK timeout of the guild (one of 60, 300, 900, 1800, 3600, in seconds) |
| widget_enabled? | boolean | Whether the guild widget is enabled |
| widget_channel_id? | ?snowflake | The channel ID that the widget will generate an invite to, if any |
| verification_level | integer | The [verification level](#verification-level) required for the guild |
| default_message_notifications | integer | Default [message notification level](#message-notification-level) for the guild |
| explicit_content_filter | integer | [Whose messages](#explicit-content-filter-level) are scanned and deleted for explicit content in the guild |
| features | array[string] | Enabled [guild features](#guild-features) |
| roles | array[[role](#role-object) object] | Roles in the guild |
| emojis | array[[emoji](/resources/emoji#emoji-object) object] | Custom guild emoji |
| stickers | array[[sticker](/resources/sticker#sticker-object) object] | Custom guild stickers |
| mfa_level | integer | Required [MFA level](#mfa-level) for administrative actions within the guild |
| system_channel_id | ?snowflake | The ID of the channel where system event messages, such as member joins and premium subscriptions (boosts), are posted |
| system_channel_flags | integer | The [flags](#system-channel-flags) that limit system event messages |
| rules_channel_id | ?snowflake | The ID of the channel where community guilds display rules and/or guidelines |
| public_updates_channel_id | ?snowflake | The ID of the channel where admins and moderators of community guilds receive notices from Discord |
| safety_alerts_channel_id | ?snowflake | The ID of the channel where admins and moderators of community guilds receive safety alerts from Discord |
| max_presences? | ?integer | The maximum number of presences for the guild (`null` is usually returned, apart from the largest of guilds) |
| max_members? | integer | The maximum number of members for the guild |
| vanity_url_code | ?string | The guild's vanity invite code |
| premium_tier | integer | The guild's [premium tier](#premium-tier) (boost level) |
| premium_subscription_count | integer | The number of premium subscriptions (boosts) the guild currently has |
| preferred_locale | string | The preferred locale of the guild; used in discovery and notices from Discord (default "en-US") |
| max_video_channel_users? | integer | The maximum number of users in a voice channel while someone has video enabled |
| max_stage_video_channel_users? ^1^ | integer | The maximum number of users in a stage channel while someone has video enabled |
| nsfw **(deprecated)** | boolean | Whether the guild is considered NSFW (`EXPLICIT` or `AGE_RESTRICTED`) |
| nsfw_level | integer | The [NSFW level](#nsfw-level) of the guild |
| owner_configured_content_level | ?integer | The owner-configured [NSFW level](#nsfw-level) of the guild |
| hub_type | ?integer | The [type of student hub](#hub-type) the guild is, if it is a student hub |
| premium_progress_bar_enabled | boolean | Whether the guild has the premium (boost) progress bar enabled |
| premium_progress_bar_enabled_user_updated_at | ?ISO8601 timestamp | When the guild premium (boost) progress bar was last enabled |
| latest_onboarding_question_id | ?snowflake | The ID of the guild's latest [onboarding prompt option](#onboarding-prompt-option-structure) |
| incidents_data | ?[automod incidents data](/resources/auto-moderation#automod-incidents-data-object) object | Information on the guild's AutoMod incidents |
| inventory_settings **(deprecated)** | ?[guild inventory settings](#guild-inventory-settings-structure) object | Settings for emoji packs |
| premium_features ^3^ | ?[guild premium features](#guild-premium-features-structure) object | The guild's powerup information |
| profile ^3^ | ?[guild identity](#guild-identity-structure) object | The guild's identity |
| approximate_member_count? ^2^ | integer | Approximate count of total members in the guild |
| approximate_presence_count? ^2^ | integer | Approximate count of non-offline members in the guild |
| official_message_color | ?integer | Color for guild official messages (client defaults to 0x3498db) |
| version? ^4^ | string | The version of the guild serialized as a stringified integer |
^1^ This limit also applies to stream viewers within the channel. The value is always 50 for premium tiers 0 to 1, 150 for premium tier 2, and `300 + 30 * (premium_subscription_count - 14)` for premium tier 3.
^2^ Only included when fetched from the [Get Guild](#get-guild) endpoint with `with_counts` set to `true`.
^3^ Only included in guild objects returned [over the Gateway](/gateway/gateway-events#guilds), through the [Join Guild](#join-guild) endpoint, or through [OAuth2](/topics/oauth2#advanced-bot-authorization).
^4^ Only included in guild objects returned [over the Gateway](/gateway/gateway-events#guilds).
###### Partial Guild Structure
| Field | Type | Description |
| ------------------------------- | ---------------------------------------------------------- | ------------------------------------------------------------------------------------- |
| id | snowflake | The ID of the guild |
| name | string | The name of the guild (2-100 characters) |
| icon | ?string | The guild's [icon hash](/reference#cdn-formatting) |
| description | ?string | The description for the guild (max 300 characters) |
| splash | ?string | The guild's [splash hash](/reference#cdn-formatting) |
| discovery_splash | ?string | The guild's [discovery splash hash](/reference#cdn-formatting) |
| home_header | ?string | The guild's [home header hash](/reference#cdn-formatting), used in new member welcome |
| features | array[string] | Enabled [guild features](#guild-features) |
| emojis? ^1^ | array[[emoji](/resources/emoji#emoji-object) object] | Custom guild emoji |
| stickers? ^1^ | array[[sticker](/resources/sticker#sticker-object) object] | Custom guild stickers |
| approximate_member_count? ^2^ | integer | Approximate number of total members in the guild |
| approximate_presence_count? ^2^ | integer | Approximate number of non-offline members in the guild |
^1^ Only included when fetched from the [Get Guild Preview](#get-guild-preview) endpoint.
^2^ Not included when fetched from the [Get Guild Basic](#get-guild-basic), [List Join Request Guilds](#list-join-request-guilds), or [Get Checkpoint](/resources/checkpoint#get-checkpoint) endpoints.
###### Guild Identity Structure
| Field | Type | Description |
| ----- | ------ | ------------------------------------------------- |
| tag | string | The tag of the guild (2-4 characters) |
| badge | string | The [guild badge hash](/reference#cdn-formatting) |
###### Guild Inventory Settings Structure
| Field | Type | Description |
| -------------------------- | ------- | ------------------------------------------------------------- |
| is_emoji_pack_collectible? | boolean | Allows everyone to collect and use the guild's emoji globally |
###### Guild Premium Features Structure
| Field | Type | Description |
| ------------------------ | ------------- | ---------------------------------------------------------------- |
| features | array[string] | Enabled [powerup-specific guild features](#guild-features) |
| additional_emoji_slots | integer | The number of additional emoji slots available to the guild |
| additional_sticker_slots | integer | The number of additional sticker slots available to the guild |
| additional_sound_slots | integer | The number of additional soundboard slots available to the guild |
###### Message Notification Level
| Value | Name | Description |
| ----- | ------------- | --------------------------------------------------------------------------------------------------------------------------- |
| 0 ^1^ | ALL_MESSAGES | Receive notifications for all messages |
| 1 | ONLY_MENTIONS | Receive notifications only for messages that @mention you |
| 2 ^2^ | NO_MESSAGES | Don't receive notifications |
| 3 ^2^ | INHERIT | Inherit value from guild settings when in a [channel override](/resources/user-settings#channel-override-structure) context |
^1^ Push notifications will not be received for `ALL_MESSAGES` for guilds with more than 2,500 members.
^2^ Only available inside a [user guild settings](/resources/user-settings#user-guild-settings-object) context.
###### Explicit Content Filter Level
| Value | Name | Description |
| ----- | --------------------- | ----------------------------------------------------------- |
| 0 | DISABLED | Media content will not be scanned |
| 1 | MEMBERS_WITHOUT_ROLES | Media content sent by members without roles will be scanned |
| 2 | ALL_MEMBERS | Media content sent by all members will be scanned |
###### MFA Level
| Value | Name | Description |
| ----- | -------- | --------------------------------------------------- |
| 0 | NONE | Guild has no MFA requirement for moderation actions |
| 1 | ELEVATED | Guild has a MFA requirement for moderation actions |
###### Verification Level
| Value | Name | Description |
| ----- | --------- | --------------------------------------------------------- |
| 0 | NONE | Unrestricted |
| 1 | LOW | Must have a verified email on file |
| 2 | MEDIUM | Must be registered on Discord for longer than 5 minutes |
| 3 | HIGH | Must be a member of the server for longer than 10 minutes |
| 4 | VERY_HIGH | Must have a verified phone number on file |
###### NSFW Level
| Value | Name | Description |
| ----- | -------------- | --------------------------------------------------------------------------- |
| 0 | DEFAULT | Guild is not yet rated by Discord |
| 1 | EXPLICIT | Guild has mature content only suitable for users over 18 |
| 2 | SAFE | Guild is safe for work |
| 3 | AGE_RESTRICTED | Guild has mildly mature content that may not be suitable for users under 18 |
###### Premium Tier
| Value | Name | Description |
| ----- | ------ | --------------------------------------------- |
| 0 | NONE | Guild has not unlocked any Server Boost perks |
| 1 | TIER_1 | Guild has unlocked Server Boost level 1 perks |
| 2 | TIER_2 | Guild has unlocked Server Boost level 2 perks |
| 3 | TIER_3 | Guild has unlocked Server Boost level 3 perks |
###### System Channel Flags
| Value | Name | Description |
| -------- | -------------------------------------------------------- | ------------------------------------------------------------- |
| 1 \<\< 0 | SUPPRESS_JOIN_NOTIFICATIONS | Suppress member join notifications |
| 1 \<\< 1 | SUPPRESS_PREMIUM_SUBSCRIPTIONS | Suppress premium subscription (boost) notifications |
| 1 \<\< 2 | SUPPRESS_GUILD_REMINDER_NOTIFICATIONS | Suppress guild setup tips |
| 1 \<\< 3 | SUPPRESS_JOIN_NOTIFICATION_REPLIES | Hide member join sticker reply buttons |
| 1 \<\< 4 | SUPPRESS_ROLE_SUBSCRIPTION_PURCHASE_NOTIFICATIONS | Suppress role subscription purchase and renewal notifications |
| 1 \<\< 5 | SUPPRESS_ROLE_SUBSCRIPTION_PURCHASE_NOTIFICATION_REPLIES | Hide role subscription sticker reply buttons |
| 1 \<\< 7 | SUPPRESS_CHANNEL_PROMPT_DEADCHAT | Suppress dead chat channel prompts |
| 1 \<\< 8 | SUPPRESS_UGC_ADDED_NOTIFICATIONS | Suppress emoji created notifications |
###### Privacy Level
| Value | Name | Description |
| ----- | ---------- | ------------------------------------------------------------------ |
| 1 | PUBLIC | Scheduled event or stage instance is visible publicly |
| 2 | GUILD_ONLY | Scheduled event or stage instance is only visible to guild members |
###### Hub Type
| Value | Name | Description |
| ----- | ----------- | ----------------------------------------------------------------------------- |
| 0 | DEFAULT | Student hub is not categorized as a high school or post-secondary institution |
| 1 | HIGH_SCHOOL | Student hub is for a high school |
| 2 | COLLEGE | Student hub is for a post-secondary institution (college or university) |
###### Guild Features
The available guild features, their functionality, and their requirements is subject to arbitrary change. The following table is a best-effort attempt to document the current state of guild features.
| Value | Description |
| ------------------------------------------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| ACTIVITIES_ALPHA | Access to alpha embedded activities ([`activities_team` release phase](/resources/application#embedded-activity-release-phase)) |
| ACTIVITIES_EMPLOYEE | Access to employee-released embedded activities ([`employee_release` release phase](/resources/application#embedded-activity-release-phase)) |
| ACTIVITIES_INTERNAL_DEV | Access to internal developer embedded activities |
| ACTIVITY_FEED_DISABLED_BY_USER | [Member list activity feed](https://support.discord.com/hc/en-us/articles/22045487931799-Members-List-Recent-Activity-FAQ) disabled |
| ACTIVITY_FEED_ENABLED_BY_USER | [Member list activity feed](https://support.discord.com/hc/en-us/articles/22045487931799-Members-List-Recent-Activity-FAQ) enabled |
| AGE_VERIFICATION_LARGE_GUILD | Guild requires account age verification to access |
| ANIMATED_BANNER | Ability to set an animated [guild banner image](https://support.discord.com/hc/en-us/articles/360028716472-Server-Banner-Background-Invite-Splash-Image) |
| ANIMATED_ICON | Ability to set an animated guild icon |
| ~~APPLICATION_COMMAND_PERMISSIONS_V2~~ | ~~Guild is using the [old application commad permissions configuration behavior](https://discord.com/developers/docs/change-log#upcoming-application-command-permission-changes)~~ |
| AUDIO_BITRATE_128_KBPS | Increased maximum voice channel bitrate (128 kbps) |
| AUDIO_BITRATE_256_KBPS | Increased maximum voice channel bitrate (256 kbps) |
| AUDIO_BITRATE_384_KBPS | Increased maximum voice channel bitrate (384 kbps) |
| AUTO_MODERATION | AutoMod feature enabled |
| ~~AUTOMOD_TRIGGER_KEYWORD_FILTER~~ ^1^ | ~~Access to the keyword filter trigger for AutoMod~~ |
| ~~AUTOMOD_TRIGGER_ML_SPAM_FILTER~~ ^1^ | ~~Access to the machine learning-based spam filter trigger for AutoMod~~ |
| ~~AUTOMOD_TRIGGER_SPAM_LINK_FILTER~~ ^1^ | ~~Access to the spam link filter trigger for AutoMod~~ |
| ~~AUTOMOD_TRIGGER_USER_PROFILE~~ | ~~Access to the user profile trigger for AutoMod~~ |
| BANNER | Ability to set a [guild banner image](https://support.discord.com/hc/en-us/articles/360028716472-Server-Banner-Background-Invite-Splash-Image) |
| BFG | Big what now 🤨 |
| ~~BOOSTING_TIERS_EXPERIMENT_MEDIUM_GUILD~~ | ~~Guild requires a reduced amount of premium subscriptions to go up a premium tier (tier 2 - 7 boosts, tier 3 - 10 boosts)~~ |
| ~~BOOSTING_TIERS_EXPERIMENT_SMALL_GUILD~~ | ~~Guild requires a reduced amount of premium subscriptions to go up a premium tier (tier 2 - 3 boosts, tier 3 - 4 boosts)~~ |
| BOT_DEVELOPER_EARLY_ACCESS | Access to early feature testing for bot and library developers |
| ~~BURST_REACTIONS~~ ^1^ | ~~Access to [burst reactions](/resources/message#reaction-object)~~ |
| BYPASS_SLOWMODE_PERMISSION_MIGRATION_COMPLETE | Guild has migrated to the new bypass slowmode permission |
| ~~CHANNEL_BANNER~~ | ~~Ability to set a channel banner~~ |
| CHANNEL_EMOJIS_GENERATED | Guild has channel icon emoji populated |
| CHANNEL_ICON_EMOJIS_GENERATED | Guild has channel icon emoji populated |
| ~~CHANNEL_HIGHLIGHTS~~ | ~~Access to channel highlights~~ |
| ~~CHANNEL_HIGHLIGHTS_DISABLED~~ |
| ~~CLAN~~ | ~~Guild is a [clan](https://support.discord.com/hc/en-us/articles/23187611406999-Guilds-FAQ)~~ |
| ~~CLAN_DISCOVERY_DISABLED~~ | ~~Clan discovery permanently disabled by Discord~~ |
| ~~CLAN_PILOT_GENSHIN~~ | ~~Access to clan conversion and clan discovery for Genshin Impact~~ |
| ~~CLAN_PILOT_VALORANT~~ | ~~Access to clan conversion and clan discovery for Valorant~~ |
| ~~CLAN_PREPILOT_GENSHIN~~ |
| ~~CLAN_PREPILOT_VALORANT~~ |
| ~~CLAN_SAFETY_REVIEW_DISABLED~~ |
| ~~CLYDE_DISABLED~~ | ~~Clyde AI integration opted-out~~ |
| ~~CLYDE_ENABLED~~ | ~~Clyde AI integration enabled~~ |
| ~~CLYDE_EXPERIMENT_ENABLED~~ | ~~Clyde AI experiment enabled~~ |
| COMMERCE | Access to store channels |
| COMMUNITY | Access to [welcome screen](#welcome-screen-object), [member verification](#member-verification-object), [stage channels](/resources/channel#channel-type), discovery, [community updates reception](https://support.discord.com/hc/en-us/articles/360035969312-Public-Server-Guidelines), and more |
| COMMUNITY_CANARY | Early access to experimental community features |
| COMMUNITY_EXP_LARGE_GATED |
| COMMUNITY_EXP_LARGE_UNGATED |
| COMMUNITY_EXP_MEDIUM |
| CONFERENCE | Guest invitees do not get marked as guest |
| CONSIDERED_EXTERNALLY_DISCOVERABLE | Guild is considered externally discoverable (i.e. listed in public server lists) |
| ~~CREATOR_ACCEPTED_NEW_TERMS~~ | ~~Guild owner has accepted the updated monetization agreements~~ |
| CREATOR_MONETIZABLE | Monetization enabled |
| CREATOR_MONETIZABLE_DISABLED | Monetization permanently disabled by Discord |
| CREATOR_MONETIZABLE_PENDING_NEW_OWNER_ONBOARDING | Monetization features are pending until the new guild owner completes the onboarding process |
| CREATOR_MONETIZABLE_PROVISIONAL | Monetization enabled |
| CREATOR_MONETIZABLE_RESTRICTED | Guild has restrictions on monetization features |
| CREATOR_MONETIZABLE_WHITEGLOVE | Guild has a fast-tracked monetization onboarding process |
| CREATOR_MONETIZATION_APPLICATION_ALLOWLIST |
| CREATOR_STORE_PAGE | Monetization store page enabled |
| DEVELOPER_SUPPORT_SERVER | Guild is an [application support server](https://support-dev.discord.com/hc/en-us/articles/6378525413143-App-Directory-App-profile-page) |
| DISCOVERABLE | Guild is public and discoverable in the directory |
| DISCOVERABLE_DISABLED | Discovery permanently disabled by Discord |
| ENABLED_DISCOVERABLE_BEFORE | Guild has previously been discoverable |
| ENABLED_MODERATION_EXPERIENCE_FOR_NON_COMMUNITY | Guild has enabled the members tab in the channel list without being a community guild |
| ENHANCED_ROLE_COLORS | Ability to set gradient role colors |
| EXPOSED_TO_ACTIVITIES_WTP_EXPERIMENT | |
| ~~EXPOSED_TO_BOOSTING_TIERS_EXPERIMENT~~ | ~~Guild requires a reduced amount of premium subscriptions to go up a premium tier (see `BOOSTING_TIERS_EXPERIMENT_MEDIUM_GUILD`, `BOOSTING_TIERS_EXPERIMENT_SMALL_GUILD`)~~ |
| ~~FEATURABLE~~ | ~~Guild is featured in discovery~~ |
| ~~FORCE_RELAY~~ | ~~Shards connections to the guild to different nodes that relay information between each other~~ (see `RELAY_ENABLED`) |
| FORWARDING_DISABLED | Guild has disabled forwarding messages to other channels |
| GAME_SERVER_HOSTING | Access to game server hosting through Discord |
| GAME_SERVERS | Guild has an active game server through Discord |
| ~~GENSHIN_L30~~ | ~~Access to clan conversion based on the intensity of Genshin Impact engagement among the guild's members, as depicted by the power user curve~~ |
| GUESTS_ENABLED | Guild has used guest invites |
| ~~GUILD_AUTOMOD_DEFAULT_LIST~~ ^1^ | |
| ~~GUILD_COMMUNICATION_DISABLED_GUILDS~~ ^1^ | ~~Access to member timeouts~~ |
| ~~GUILD_HOME_DEPRECATION_OVERRIDE~~ | ~~Home tab deprecation notice hidden~~ |
| ~~GUILD_HOME_OVERRIDE~~ | ~~Access to the Home feature, without additionally checking for the matching user experiment~~ |
| ~~GUILD_HOME_TEST~~ | ~~Access to the Home feature~~ |
| ~~GUILD_MEMBER_VERIFICATION_EXPERIMENT~~ | |
| GUILD_ONBOARDING | Onboarding feature enabled |
| ~~GUILD_ONBOARDING_ADMIN_ONLY~~ | ~~Onboarding only visible to guild admins~~ |
| GUILD_ONBOARDING_EVER_ENABLED | Guild has previously enabled the onboarding feature |
| GUILD_ONBOARDING_HAS_PROMPTS | Guild has prompts configured in onboarding |
| GUILD_PRODUCTS | Access to guild products |
| GUILD_PRODUCTS_ALLOW_ARCHIVED_FILE | Allows uploading archive formats as guild products |
| ~~GUILD_ROLE_SUBSCRIPTIONS~~ | ~~Role subscriptions enabled~~ (see `ROLE_SUBSCRIPTIONS_ENABLED`) |
| ~~GUILD_ROLE_SUBSCRIPTION_PURCHASE_FEEDBACK_LOOP~~ ^1^ | ~~Access to [`SUPPRESS_ROLE_SUBSCRIPTION_PURCHASE_NOTIFICATIONS`, `SUPPRESS_ROLE_SUBSCRIPTION_PURCHASE_NOTIFICATIONS_REPLIES` system channel flags](#system-channel-flags)~~ |
| ~~GUILD_ROLE_SUBSCRIPTION_TIER_TEMPLATE~~ ^1^ | ~~Access to role subscriptions tier templates~~ |
| ~~GUILD_ROLE_SUBSCRIPTION_TRIALS~~ ^1^ | ~~Access to role subscriptions trials~~ |
| GUILD_SERVER_GUIDE | New member welcome feature enabled |
| GUILD_TAGS | Ability to set a guild tag |
| GUILD_TAGS_BADGE_PACK_CREEPY_CRAWLIES | Ability to use badge icons from the [creepy crawlies pack](https://cdn.discordapp.com/assets/content/c174a191a551f359311ac49f7c3c344e7349ff82dd4f6f64ed5fbd355ff2a04f.png) |
| GUILD_TAGS_BADGE_PACK_FLEX | Ability to use badge icons from the [flex pack](https://cdn.discordapp.com/assets/content/4e745042a2d8bfd0006d1040fc5a266bfb31ec9bbda28bd1651c2a48fb627642.png) |
| GUILD_TAGS_BADGE_PACK_PETS | Ability to use badge icons from the [pets pack](https://cdn.discordapp.com/assets/content/a42569e97ea3ec4ce43009ea59cb9514080bc1a7191bd6db2eb4a2076964107d.png) |
| GUILD_TAGS_BADGE_PACK_PLANT | Ability to use badge icons from the [plant pack](https://cdn.discordapp.com/assets/content/a586e274a51442be7a6088580bf17a03e681120c57830b702c71024535ec3163.png) |
| GUILD_WEB_PAGE_VANITY_URL | Guild has an immutable vanity given by the server web page feature |
| HAD_EARLY_ACTIVITIES_ACCESS | Guild previously had access to embedded activities and can bypass the premium tier requirement |
| HAS_DIRECTORY_ENTRY | Guild is listed in a directory channel |
| HIDE_FROM_EXPERIMENT_UI |
| HUB | Guild is a [student hub](https://support.discord.com/hc/en-us/articles/4406046651927) |
| INCREASED_THREAD_LIMIT | Ability to have over 1,000 active threads |
| INTERNAL_EMPLOYEE_ONLY | Restricts guild joining to Discord employees |
| INVITE_SPLASH | Ability to set an invite splash background |
| INVITES_DISABLED | Guild has [paused invites](https://support.discord.com/hc/en-us/articles/8458903738647-Pause-Invites-FAQ), preventing new members from joining |
| ~~LEADERBOARD_ENABLED~~ | ~~Guild has [game leaderboard](https://support.discord.com/hc/en-us/articles/27615657704983-Leaderboards-FAQ) enabled~~ |
| LINKED_TO_HUB | Guild is linked to a [student hub](https://support.discord.com/hc/en-us/articles/4406046651927) |
| ~~LURKABLE~~ | ~~Ability to preview the guild before joining~~ (see `DISCOVERABLE` and `PREVIEW_ENABLED`) |
| ~~MARKETPLACES_CONNECTION_ROLES~~ ^1^ | ~~Access to guild linked roles~~ |
| MAX_FILE_SIZE_50_MB | Increased maximum file upload size (50 MB) |
| MAX_FILE_SIZE_100_MB | Increased maximum file upload size (100 MB) |
| MAX_FILE_SIZE_250_MB | Increased maximum file upload size (250 MB) |
| ~~MEDIA_CHANNEL_ALPHA~~ ^1^ | ~~Access to media channels~~ |
| ~~MEMBER_LIST_DISABLED~~ | ~~Member list access disallowed~~ |
| ~~MEMBER_PROFILES~~ | ~~Allows members to customize their per-guild profiles without Nitro~~ |
| ~~MEMBER_SAFETY_PAGE_ROLLOUT~~ | ~~Access to member safety tab~~ |
| MEMBER_VERIFICATION_GATE_ENABLED | [Member verification](#member-verification-object) enabled, requiring new members to pass the verification gate before interacting with the guild |
| MEMBER_VERIFICATION_MANUAL_APPROVAL | Membership verification manual approval enabled |
| ~~MEMBER_VERIFICATION_ROLLOUT_TEST~~ | ~~Early access to member verification manual approval general availability~~ |
| ~~MOBILE_WEB_ROLE_SUBSCRIPTION_PURCHASE_PAGE~~ ^1^ | ~~Allows purchasing role subscriptions tiers via web version of Discord on mobile~~ |
| ~~MONETIZATION_ENABLED~~ | ~~Monetization enabled~~ (see `CREATOR_MONETIZABLE`) |
| MORE_EMOJI | Increased guild emoji slots (200 each for normal and animated) |
| MORE_SOUNDBOARD | Increased guild soundboard slots (96) |
| MORE_STICKERS | Increased guild sticker slots (60) |
| NEWS | Access to [news channels](https://support.discord.com/hc/en-us/articles/360028384531-Channel-Following-FAQ) |
| ~~NEW_THREAD_PERMISSIONS~~ ^1^ | ~~[New thread permissions](https://support.discord.com/hc/en-us/articles/4403205878423-Threads-FAQ#h_01FDGC4JW2D665Y230KPKWQZPN) enabled~~ |
| NON_COMMUNITY_RAID_ALERTS | Non-community guild is opted-in to raid alerts |
| OFFICIAL_GAME_GUILD | Guild is considered an official Discord guild for a game |
| PARTNERED | Guild is [partnered with Discord](https://discord.com/partners) |
| PIN_PERMISSION_MIGRATION_COMPLETE | Guild has migrated to the new message pin permission |
| POWERUP_BETA_FEATURES | Guild has access to guild powerups that are in beta |
| PREMIUM_TIER_3_OVERRIDE | All guild powerups are force-enabled regardless of premium subscription count |
| PREVIEW_ENABLED | Guild is accessable (read-only) without passing member verification |
| ~~PRIVATE_THREADS~~ ^1^ | ~~Ability to create private threads~~ |
| PRODUCTS_AVAILABLE_FOR_PURCHASE | Guild has guild products available for purchase |
| PRUNE_REQUIRES_ADMIN | Guild has restricted the ability to [prune guild members](#prune-guild) to administrators |
| ~~PUBLIC~~ | ~~[Access to welcome screen, member verification, stage channels, discovery, and community updates reception](https://support.discord.com/hc/en-us/articles/360035969312-Public-Server-Guidelines)~~ (see `COMMUNITY`) |
| ~~PUBLIC_DISABLED~~ | ~~Community features are permanently disabled by Discord~~ |
| RAID_ALERTS_DISABLED | Raid alerts opted out |
| ~~RAID_ALERTS_ENABLED~~ | ~~Raid alerts enabled~~ (see `RAID_ALERTS_DISABLED`) |
| ~~RAPIDASH_TEST~~ | ~~Access to clan conversion and clan discovery~~ |
| ~~RAPIDASH_TEST_REBIRTH~~ | ~~Access to clan conversion and clan discovery~~ |
| RELAY_ENABLED | Shards connections to the guild to different nodes that relay information between each other |
| REPORT_TO_MOD_PILOT | Guild has early access to report to moderator feature |
| REPORT_TO_MOD_SURVEY | Guild has access to report to moderator feature survey |
| ~~RESTRICT_SPAM_RISK_GUILDS~~ ^1^ | ~~Guild has additional spam risk protections enabled~~ |
| ROLE_ICONS | Ability to set an image or emoji as a role icon |
| ROLE_SUBSCRIPTIONS_AVAILABLE_FOR_PURCHASE | Guild has role subscriptions available for purchase |
| ROLE_SUBSCRIPTIONS_ENABLED | Role subscriptions enabled |
| ~~ROLE_SUBSCRIPTIONS_ENABLED_FOR_PURCHASE~~ | ~~Ability to purchase role subscriptions in the guild~~ (see `ROLE_SUBSCRIPTIONS_AVAILABLE_FOR_PURCHASE`) |
| ~~SEVEN_DAY_THREAD_ARCHIVE~~ ^1^ | ~~Ability to have threads that archive after seven days~~ |
| ~~SERVER_PROFILES_TEST~~ | ~~Guild has early access to server profiles~~ |
| ~~SHARD~~ | ~~Shards [student hub](https://support.discord.com/hc/en-us/articles/4406046651927) UI~~ |
| SHARED_CANVAS_FRIENDS_AND_FAMILY_TEST | Access to the shared canvas feature |
| SOCIAL_LAYER_STOREFRONT | Guild can monetize in-game items through the social layer SDK |
| SOUNDBOARD | Guild has a custom [soundboard sound](https://support.discord.com/hc/en-us/articles/12612888127767-Soundboard-FAQ) |
| STAGE_CHANNEL_VIEWERS_50 | Increased maximum stage stream viewers (50) |
| STAGE_CHANNEL_VIEWERS_150 | Increased maximum stage stream viewers (150) |
| STAGE_CHANNEL_VIEWERS_300 | Increased maximum stage stream viewers (300) |
| ~~SUMMARIES_ENABLED~~ | ~~Access to [conversation summaries](https://support.discord.com/hc/en-us/articles/12926016807575-Conversation-Summaries-AI)~~ (see `SUMMARIES_ENABLED_GA`) |
| SUMMARIES_ENABLED_GA | Access to [conversation summaries](https://support.discord.com/hc/en-us/articles/12926016807575-Conversation-Summaries-AI) general access |
| SUMMARIES_DISABLED_BY_USER | [Conversation summaries](https://support.discord.com/hc/en-us/articles/12926016807575-Conversation-Summaries-AI) opted out |
| SUMMARIES_ENABLED_BY_USER | [Conversation summaries](https://support.discord.com/hc/en-us/articles/12926016807575-Conversation-Summaries-AI) enabled |
| SUMMARIES_LONG_LOOKBACK | [Conversation summaries](https://support.discord.com/hc/en-us/articles/12926016807575-Conversation-Summaries-AI) with a longer lookback period |
| SUMMARIES_OPT_OUT_EXPERIENCE | [Conversation summaries](https://support.discord.com/hc/en-us/articles/12926016807575-Conversation-Summaries-AI) enabled by default, must be opted out instead of opted in |
| STAFF_LEVEL_COLLABORATOR_REQUIRED | Restricts guild joining to users with the [`COLLABORATOR` flag](/resources/user#user-flags) or higher |
| STAFF_LEVEL_RESTRICTED_COLLABORATOR_REQUIRED | Restricts guild joining to users with the [`RESTRICTED_COLLABORATOR` flag](/resources/user#user-flags) or higher |
| ~~TEXT_IN_STAGE_ENABLED~~ ^1^ | ~~Access to text in stage (messageable stage channels)~~ |
| ~~TEXT_IN_VOICE_ENABLED~~ ^1^ | ~~Access to text in voice (messageable voice channels)~~ |
| ~~THREADS_ENABLED~~ ^1^ | ~~Access to [threads](/topics/threads)~~ |
| ~~THREADS_ENABLED_TESTING~~ ^1^ | ~~Access to [threads](/topics/threads) prior to release, meant for bot and library developers to test their code against the new features~~ |
| ~~THREAD_DEFAULT_AUTO_ARCHIVE_DURATION~~ |
| ~~THREADS_ONLY_CHANNEL~~ ^1^ | ~~Access to [forum channels](/topics/threads#forums)~~ |
| ~~THREE_DAY_THREAD_ARCHIVE~~ ^1^ | ~~Ability to have threads that archive after three days~~ |
| ~~TICKETED_EVENTS_ENABLED~~ | ~~Access to ticketed [scheduled events](/resources/guild-scheduled-event)~~ |
| ~~TICKETING_ENABLED~~ | ~~Access to ticketed [scheduled events](/resources/guild-scheduled-event)~~ (see `TICKETED_EVENTS_ENABLED`) |
| TIERLESS_BOOSTING | Guild is using the new powerups-based boosting system |
| ~~TIERLESS_BOOSTING_CLIENT_TEST~~ | ~~Early access to guild powerup management~~ |
| TIERLESS_BOOSTING_SYSTEM_MESSAGE | Guild has received tierless boosting dismissible |
| ~~TIERLESS_BOOSTING_TEST~~ | ~~Early access to guild powerup management~~ |
| ~~VALORANT_L30~~ | ~~Access to clan conversion based on the intensity of Valorant engagement among the guild's members, as depicted by the power user curve~~ |
| VANITY_URL | Ability to set a vanity URL |
| VERIFIED | Guild is [verified](https://discord.com/verification) |
| VIDEO_BITRATE_ENHANCED | Increased camera feed quality (720p) |
| VIDEO_QUALITY_720_60FPS | Increased maximum streaming quality (720p, 60fps) |
| VIDEO_QUALITY_1080_60FPS | Increased maximum streaming quality (1080p, 60fps) |
| VIP_REGIONS | Increased maximum voice channel bitrate (384 kbps) |
| ~~VOICE_CHANNEL_EFFECTS~~ ^1^ | ~~Access to voice channel effects~~ |
| VOICE_IN_THREADS | Access to voice in threads (calls within threads) |
| WELCOME_SCREEN_ENABLED | Welcome screen enabled |
^1^ This is now a base feature, and the guild feature has no effect if still present.
###### Mutable Guild Features
These guild features are mutable, and can be edited with the [Modify Guild](#modify-guild) endpoint.
| Feature | Description | Required Permissions |
| ----------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------- |
| ACTIVITY_FEED_DISABLED_BY_USER ^1^ | Whether the [member list activity feed](https://support.discord.com/hc/en-us/articles/22045487931799-Members-List-Recent-Activity-FAQ) is explicitly disabled | `MANAGE_GUILD` |
| ACTIVITY_FEED_ENABLED_BY_USER ^1^ | Whether the [member list activity feed](https://support.discord.com/hc/en-us/articles/22045487931799-Members-List-Recent-Activity-FAQ) is explicitly enabled | `MANAGE_GUILD` |
| COMMUNITY | Whether community features are available | `ADMINISTRATOR` |
| DISCOVERABLE ^3^ | Whether the guild is public and discoverable in the directory | `ADMINISTRATOR` |
| ENABLED_MODERATION_EXPERIENCE_FOR_NON_COMMUNITY | Whether the member tab is shown in the channel list for non-community guilds | `MANAGE_GUILD` |
| INVITES_DISABLED | Whether joining the guild is disabled | `MANAGE_GUILD` |
| MEMBER_VERIFICATION_GATE_ENABLED ^4^ | Whether the member verification gate is enabled | `MANAGE_GUILD` |
| NON_COMMUNITY_RAID_ALERTS | Whether raid alerts are opted in for non-community guilds | `MANAGE_GUILD` |
| PRUNE_REQUIRES_ADMIN ^2^ | Whether the ability to [prune guild members](#prune-guild) should be restricted to administrators |
| RAID_ALERTS_DISABLED | Whether raid alerts are opted out for community guilds | `MANAGE_GUILD` |
| SUMMARIES_ENABLED_BY_USER ^5^ | Whether [conversation summaries](https://support.discord.com/hc/en-us/articles/12926016807575-Conversation-Summaries-AI) are enabled | `MANAGE_GUILD` |
^1^ Only one of the features can be set at a time.
^2^ Modification requires the user to be the owner of the guild.
^3^ Guild must also pass all discovery requirements in order to set.
^4^ Feature is only removable, not settable.
^5^ Guild must have access to conversation summaries (either the `SUMMARIES_ENABLED` or `SUMMARIES_ENABLED_GA` feature).
###### Example Guild
```json
{
"id": "81384788765712384",
"name": "Discord API",
"icon": "a363a84e969bcbe1353eb2fdfb2e50e6",
"description": null,
"home_header": null,
"splash": null,
"discovery_splash": null,
"features": [
"INVITE_SPLASH",
"VIP_REGIONS",
"PREVIEW_ENABLED",
"VANITY_URL",
"CHANNEL_ICON_EMOJIS_GENERATED",
"COMMUNITY",
"NEW_THREAD_PERMISSIONS",
"WELCOME_SCREEN_ENABLED",
"NEWS",
"ANIMATED_ICON",
"AUTO_MODERATION",
"MEMBER_VERIFICATION_GATE_ENABLED",
"THREADS_ENABLED",
"COMMUNITY_EXP_LARGE_UNGATED",
"SOUNDBOARD",
"THREE_DAY_THREAD_ARCHIVE"
],
"emojis": [],
"stickers": [],
"banner": null,
"owner_id": "80088516616269824",
"application_id": null,
"region": "deprecated",
"afk_channel_id": null,
"afk_timeout": 3600,
"system_channel_id": "381870553235193857",
"widget_enabled": true,
"widget_channel_id": null,
"verification_level": 3,
"roles": [
{
"id": "81384788765712384",
"name": "@everyone",
"description": null,
"permissions": "110917634608832",
"position": 0,
"color": 0,
"hoist": false,
"managed": false,
"mentionable": false,
"icon": null,
"unicode_emoji": null,
"flags": 0
}
],
"default_message_notifications": 1,
"mfa_level": 1,
"explicit_content_filter": 2,
"max_presences": null,
"max_members": 500000,
"max_stage_video_channel_users": 50,
"max_video_channel_users": 25,
"vanity_url_code": "discord-api",
"premium_tier": 1,
"premium_subscription_count": 5,
"system_channel_flags": 9,
"preferred_locale": "en-US",
"rules_channel_id": "381898062269775883",
"safety_alerts_channel_id": null,
"public_updates_channel_id": "650136538264502282",
"hub_type": null,
"premium_progress_bar_enabled": false,
"latest_onboarding_question_id": null,
"incidents_data": null,
"inventory_settings": null,
"nsfw": false,
"nsfw_level": 0
}
```
###### Example Partial Guild
```json
{
"id": "752630786561409076",
"name": "Elite Creative",
"icon": "278da1c7740e394657c1179f4782aef1",
"description": "The largest Fortnite Creative server across the globe. Join a Creative community offering events, 1v1s. and more!",
"home_header": null,
"splash": "2b4ae5cdd71038b4880b1b57a6e5dacb",
"discovery_splash": "9d7ec672b89b320ef7a51e5b6ae453b8",
"features": [
"ANIMATED_BANNER",
"ANIMATED_ICON",
"AUTO_MODERATION",
"BANNER",
"COMMUNITY",
"DISCOVERABLE",
"ENABLED_DISCOVERABLE_BEFORE",
"GUILD_ONBOARDING_EVER_ENABLED",
"GUILD_WEB_PAGE_VANITY_URL",
"INVITE_SPLASH",
"NEWS",
"PREVIEW_ENABLED",
"RAID_ALERTS_ENABLED",
"ROLE_ICONS",
"VANITY_URL",
"WELCOME_SCREEN_ENABLED"
],
"approximate_member_count": 155451,
"approximate_presence_count": 7532,
"emojis": [],
"stickers": []
}
```
### User Guild Object
A partial guild object returned from the [List User Guilds](#list-user-guilds) endpoint. Represents a guild the user is a member of.
###### User Guild Structure
| Field | Type | Description |
| ------------------------------- | ------------- | ----------------------------------------------------------------- |
| id | snowflake | The ID of the guild |
| name | string | The name of the guild (2-100 characters) |
| icon | ?string | The guild's [icon hash](/reference#cdn-formatting) |
| banner | ?string | The guild's [banner hash](/reference#cdn-formatting) |
| owner | boolean | Whether the user is the owner of the guild |
| features | array[string] | Enabled [guild features](#guild-features) |
| permissions | string | Total permissions for the user in the guild (excludes overwrites) |
| approximate_member_count? ^1^ | integer | Approximate count of total members in the guild |
| approximate_presence_count? ^1^ | integer | Approximate count of non-offline members in the guild |
^1^ Only included when fetched from the [List User Guilds](#list-user-guilds) endpoint with `with_counts` set to `true`.
###### Example User Guild
```json
[
{
"id": "80351110224678913",
"name": "1337 Krew",
"icon": "8342729096ea3675442027381ff50dfe",
"banner": "bb42bdc37653b7cf58c4c8cc622e76cb",
"owner": true,
"permissions": "36953089",
"features": ["COMMUNITY", "NEWS", "ANIMATED_ICON", "INVITE_SPLASH", "BANNER", "ROLE_ICONS"],
"approximate_member_count": 420,
"approximate_presence_count": 69
}
]
```
### Guild Widget Object
An embeddable widget for a guild.
###### Guild Widget Structure
| Field | Type | Description |
| -------------- | --------------------------------------------------------------- | ----------------------------------------------------- |
| id | snowflake | The ID of the guild the widget is for |
| name | string | The name of the guild the widget is for |
| instant_invite | ?string | The invite URL for the guild's widget channel, if any |
| presence_count | integer | Approximate count of non-offline members in the guild |
| channels | array[[widget channel](#guild-widget-channel-structure) object] | The public voice and stage channels in the guild |
| members | array[[widget member](#guild-widget-member-structure) object] | The non-offline guild members (max 100) |
###### Guild Widget Channel Structure
| Field | Type | Description |
| -------- | --------- | ------------------------------------------ |
| id | snowflake | The ID of the channel |
| name | string | The name of the channel (1-100 characters) |
| position | integer | Sorting position of the channel |
###### Guild Widget Member Structure
Due to privacy concerns, `id`, `discriminator`, and `avatar` are anonymized. `id` is replaced with an incrementing integer, `discriminator` is always `0000`, and `avatar` is always `null` (replaced with an encrypted `avatar_url` field).
| Field | Type | Description |
| ----------- | ------------------------------------------------------------------------ | ----------------------------------------------------------- |
| id | snowflake | The incrementing ID of the member |
| username | string | The display name or censored username of the member |
| avatar_url | string | The avatar URL of the member |
| status | string | The [status](/resources/presence#status-type) of the member |
| activity? | [widget member activity](#guild-widget-member-activity-structure) object | The primary activity the member is participating in |
| channel_id? | snowflake | The ID of the voice or stage channel the member is in |
| deaf? | boolean | Whether the member is deafened by the guild, if any |
| mute? | boolean | Whether the member is muted by the guild, if any |
| self_deaf? | boolean | Whether the member is locally deafened |
| self_mute? | boolean | Whether the member is locally muted |
| suppress? | boolean | Whether the member's permission to speak is denied |
###### Guild Widget Member Activity Structure
| Field | Type | Description |
| ----- | ------ | ------------------------ |
| name | string | The name of the activity |
###### Example Guild Widget
```json
{
"id": "1046920999469330512",
"name": "Alien Network",
"instant_invite": "https://discord.com/invite/alien",
"channels": [
{
"id": "1053657210082836620",
"name": "stage",
"position": 2
}
],
"members": [
{
"id": "0",
"username": "Dolfies",
"discriminator": "0000",
"avatar": null,
"status": "dnd",
"activity": {
"name": "balls lmao"
},
"deaf": false,
"mute": false,
"self_deaf": false,
"self_mute": true,
"suppress": false,
"channel_id": "1057241425793798144",
"avatar_url": "https://cdn.discordapp.com/widget-avatars/zOXeOyhOGqx-bwpzszp-obU-_RFE9xI9HG19HylPyMs/actPlrz4a6Kz4NSBV4jmkd1E4raF_UjDuIXnyCjJgY5DpcbFPZnVS1SvQbRkHbXaVLvKKv7gkZi0PPXX2gdxngxHSyFH7AuxH0Y-8pgQh5xhWQaC9PsmeJ64Bv8xjF9Wb_whrDVNA-I4Eg"
}
],
"presence_count": 69
}
```
###### Guild Widget Settings Structure
| Field | Type | Description |
| ---------- | ---------- | ----------------------------------------------------------------- |
| enabled | boolean | Whether the widget is enabled |
| channel_id | ?snowflake | The channel ID that the widget will generate an invite to, if any |
###### Example Guild Widget Settings
```json
{
"enabled": true,
"channel_id": "41771983444115456"
}
```
### Role Object
Roles represent a set of permissions attached to a group of users. Roles have names, colors, and can be "pinned" to the side bar, causing their members to be listed separately.
Roles can have separate permission profiles for the global context (guild) and channel context. The @everyone role has the same ID as the guild it belongs to.
Roles without colors (`primary_color` of 0) do not count towards the final computed color in the user list.
###### Role Structure
| Field | Type | Description |
| ---------------------- | -------------------------------------------- | ------------------------------------------------------------------------------------------ |
| id | snowflake | The ID of the role |
| name | string | The name of the role (max 100 characters) |
| description | ?string | The description for the role (max 90 characters) |
| color **(deprecated)** | integer | The color of the role represented as an integer representation of a hexadecimal color code |
| colors | [role colors](#role-colors-structure) object | The colors of the role encoded as an integer representation of hexadecimal color codes |
| hoist | boolean | Whether this role is pinned in the user listing |
| icon? | ?string | The role's [icon hash](/reference#cdn-formatting) |
| unicode_emoji? | ?string | The role's unicode emoji |
| position | integer | Position of this role |
| permissions | string | The permission bitwise value for the role |
| managed | boolean | Whether this role is managed by an integration |
| mentionable | boolean | Whether this role is mentionable |
| flags? | integer | The [role's flags](#role-flags) |
| tags? | [role tags](#role-tags-structure) object | The tags this role has |
| version? ^1^ | string | The version of the guild serialized as a stringified integer |
^1^ Only included within the [Guild Role Create](/gateway/gateway-events#guild-role-create), [Guild Role Update](/gateway/gateway-events#guild-role-update), and [Guild Role Delete](/gateway/gateway-events#guild-role-delete) Gateway events.
###### Role Colors Structure
| Field | Type | Description |
| ------------------ | -------- | --------------------------------------------------------------- |
| primary_color | integer | The primary color of the role (matches `color`) |
| secondary_color | ?integer | The secondary color of the role, creating a two-point gradient |
| tertiary_color ^1^ | ?integer | The tertiary color of the role, creating a three-point gradient |
^1^ The only valid three-point gradient is (`11127295`, `16759788`, `16761760`). Attempting to set `tertiary_color` with any other values will fail.
###### Role Tags Structure
Tags with type `null` represent booleans. They will be present and set to `null` if they are `true`, and will be not present if they are `false`.
| Field | Type | Description |
| ------------------------ | --------- | ------------------------------------------------------------- |
| bot_id? | snowflake | The ID of the bot this role belongs to |
| integration_id? | snowflake | The ID of the integration this role belongs to |
| premium_subscriber? | null | Whether this is the guild's premium subscriber (booster) role |
| subscription_listing_id? | snowflake | The ID of this role's subscription SKU and listing |
| available_for_purchase? | null | Whether this role is available for purchase |
| guild_connections? | null | Whether this role has a connection requirement |
###### Role Flags
| Value | Name | Description |
| -------- | --------- | ---------------------------------------------------------------------------------- |
| 1 \<\< 0 | IN_PROMPT | Role is part of an [onboarding prompt option](#onboarding-prompt-option-structure) |
###### Example Role
```json
{
"id": "1050931799506817125",
"name": "Premium Members",
"description": null,
"permissions": "262144",
"position": 176,
"color": 3447003,
"colors": {
"primary_color": 3447003,
"secondary_color": null,
"tertiary_color": null
},
"hoist": false,
"managed": true,
"mentionable": false,
"icon": null,
"unicode_emoji": "👽",
"flags": 0,
"tags": {
"integration_id": "1055934248995000390"
}
}
```
### Role Connection Configuration Object
Holds configuration for a role's linking requirements.
###### Role Connection Configuration Structure
This structure is represented as an array[array[[role connection requirement](#role-connection-requirement-structure) object]].
The top-level array represents requirements using OR logic, while the inner arrays represent requirements using AND logic.
This means that a user must satisfy at least one requirement from the top-level array, but all requirements within that array to be considered eligible for the role.
###### Role Connection Requirement Structure
| Field | Type | Description |
| ------------------------------ | --------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------- |
| connection_type ^1^ | string | The [type of connection](/resources/connected-accounts#connection-type) required |
| connection_metadata_field? ^2^ | ?string | The metadata field to check for the connection |
| operator? | ?integer | The [comparison operator](#role-connection-operator-type) to use |
| value? | ?string | The value to compare the metadata field to |
| application_id? | snowflake | The ID of the application to check for the connection |
| application? ^3^ | [integration application](/resources/integration#integration-application-object) object | The application to check for the connection |
| name? ^3^ | string | The friendly name of the application's metadata field |
| description? ^3^ | string | The description of the application's metadata field |
| result? ^3^ | boolean | The result of the connection check |
^1^ A special connection type of `application` is used to represent application role connection requirements.
^2^ In the case of regular connections, this is checked against the provider's [connection metadata](/resources/connected-accounts#connection-object). For application connections, this is checked against the user's [application metadata](/resources/application#application-role-connection-object).
^3^ Only included when fetched from the [Get Guild Role Connection Eligibility](#get-guild-role-connection-eligibility) endpoint. Received only and cannot be set.
###### Role Connection Operator Type
| Value | Name | Description |
| ----- | ------------------------------ | -------------------------------------------------------------------------------------------------------------------------------------- |
| 1 | INTEGER_LESS_THAN_OR_EQUAL | The metadata value (`integer`) is less than or equal to the guild's configured value (`integer`) |
| 2 | INTEGER_GREATER_THAN_OR_EQUAL | The metadata value (`integer`) is greater than or equal to the guild's configured value (`integer`) |
| 3 | INTEGER_EQUAL | The metadata value (`integer`) is equal to the guild's configured value (`integer`) |
| 4 | INTEGER_NOT_EQUAL | The metadata value (`integer`) is not equal to the guild's configured value (`integer`) |
| 5 | DATETIME_LESS_THAN_OR_EQUAL | The metadata value (`ISO8601 string`) is less than or equal to the guild's configured value (`integer`; `days before current date`) |
| 6 | DATETIME_GREATER_THAN_OR_EQUAL | The metadata value (`ISO8601 string`) is greater than or equal to the guild's configured value (`integer`; `days before current date`) |
| 7 | BOOLEAN_EQUAL | The metadata value (`integer`) is equal to the guild's configured value (`integer`; `1`) |
| 8 | BOOLEAN_NOT_EQUAL | The metadata value (`integer`) is not equal to the guild's configured value (`integer`; `1`) |
###### Example Role Connection Configuration
```json
[
[
{
"connection_type": "paypal",
"connection_metadata_field": null,
"operator": null,
"value": null
},
{
"connection_type": "paypal",
"connection_metadata_field": "verified",
"operator": 1,
"value": "1"
},
{
"connection_type": "paypal",
"connection_metadata_field": "created_at",
"operator": 4,
"value": "0"
}
],
[
{
"connection_type": "spotify",
"connection_metadata_field": null,
"operator": null,
"value": null
}
]
]
```
### Guild Member Object
A participating user in a [guild](#guild-object).
###### Guild Member Structure
| Field | Type | Description |
| --------------------------------- | ------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| user ^1^ | partial [user](/resources/user#user-object) object | The user this guild member represents |
| nick? | ?string | The guild-specific nickname of the member (1-32 characters) |
| avatar? | ?string | The member's [guild avatar hash](/reference#cdn-formatting) |
| avatar_decoration_data? | ?[avatar decoration data](/resources/user#avatar-decoration-data-object) object | The member's [guild avatar decoration](https://support.discord.com/hc/en-us/articles/13410113109911-Avatar-Decorations) |
| collectibles? | ?[collectibles](/resources/user#collectibles-object) object | The member's equipped collectibles |
| display_name_styles? | ?[display name style](/resources/user#display-name-style-structure) object | The member's display name style |
| banner? | ?string | The member's [guild banner hash](/reference#cdn-formatting) |
| bio? ^4^ | ?string | The member's guild-specific bio (max 190 characters) |
| roles | array[snowflake] | The role IDs assigned to this member |
| joined_at | ISO8601 timestamp | When the user joined the guild |
| premium_since? | ?ISO8601 timestamp | When the member subscribed to (started [boosting](https://support.discord.com/hc/en-us/articles/360028038352-Server-Boosting-)) the guild |
| deaf? | boolean | Whether the member is deafened in voice channels |
| mute? | boolean | Whether the member is muted in voice channels |
| pending? ^2^ | boolean | Whether the member has not yet passed the guild's [member verification](#member-verification-object) requirements |
| communication_disabled_until? ^3^ | ?ISO8601 timestamp | When the member's [timeout](https://support.discord.com/hc/en-us/articles/4413305239191-Time-Out-FAQ) will expire and they will be able to communicate in the guild again |
| unusual_dm_activity_until? ^3^ | ?ISO8601 timestamp | When the member's unusual DM activity flag will expire |
| flags | integer | The [member's flags](#guild-member-flags) |
| permissions? ^4^ ^5^ | string | Total permissions of the member in the guild |
^1^ Not included in certain member objects served alongside user objects. These cases are always called out in the relevant structures.
^2^ Not included in contexts that are impossible for a pending member to exist in. If the guild has [previewing disabled](#guild-previewing), this field will always be `false`.
^3^ If the value is a time in the past, the flag has expired.
^4^ Only included in private guild member objects returned from the [Get Current Guild Member](#get-current-guild-member), [Modify Current Guild Member](#modify-current-guild-member), and [Get User Profile](/resources/user#get-user-profile) endpoints.
^5^ When received in an interaction, this field will instead contain the member's total permissions in the channel, including overwrites.
###### Guild Member Flags
| Value | Name | Description |
| ------------ | --------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| 1 \<\< 0 | DID_REJOIN | Guild member has left and rejoined the guild |
| 1 \<\< 1 | COMPLETED_ONBOARDING | Guild member has completed onboarding |
| 1 \<\< 2 | BYPASSES_VERIFICATION ^1^ | Guild member bypasses guild verification requirements and [member verification](#member-verification-object) |
| 1 \<\< 3 | STARTED_ONBOARDING | Guild member has started onboarding |
| 1 \<\< 4 | IS_GUEST | Guild member is a [guest](/resources/invite#guest-invites) and not a true member |
| 1 \<\< 5 | STARTED_HOME_ACTIONS | Guild member has started the new member actions in the server guide |
| 1 \<\< 6 | COMPLETED_HOME_ACTIONS | Guild member has completed all of the new member actions in the server guide |
| 1 \<\< 7 | AUTOMOD_QUARANTINED_NAME ^2^ | Guild member has been indefinitely quarantined by [an AutoMod Rule](/resources/auto-moderation#automod-rule-object) for their username, display name, or nickname |
| ~~1 \<\< 8~~ | ~~AUTOMOD_QUARANTINED_BIO ^2^~~ | ~~Guild member has been indefinitely quarantined by [an AutoMod Rule](/resources/auto-moderation#automod-rule-object) for their bio~~ |
| 1 \<\< 9 | DM_SETTINGS_UPSELL_ACKNOWLEDGED | Guild member has acknowledged the DM privacy settings upsell modal |
| 1 \<\< 10 | AUTOMOD_QUARANTINED_GUILD_TAG ^2^ | Guild member has been indefinitely quarantined by [an AutoMod Rule](/resources/auto-moderation#automod-rule-object) for their primary guild tag |
^1^ Allows a member who does not meet verification requirements to participate in the guild, and forces the [member's `pending` status](#guild-member-object) to be `false`. Removing this flag does not make the member pending again, but subjects them to the verification requirements again.
^2^ Quarantined users, similar to timed out users, are prevented from interacting with the guild in any way.
###### Example Guild Member
```json
{
"avatar": null,
"banner": null,
"communication_disabled_until": null,
"unusual_dm_activity_until": null,
"flags": 34,
"joined_at": "2023-03-22T13:59:47.553000+00:00",
"nick": null,
"pending": false,
"premium_since": null,
"roles": [
"1040221495437299782",
"1029330445336313927",
"1049489484179312691",
"1053820570367701012",
"1029317826755956827",
"1029316630431412287"
],
"user": {
"id": "828387742575624222",
"username": "jupppper",
"avatar": "e14a7c62b0b38068be88be194b23910f",
"discriminator": "0",
"public_flags": 16384,
"banner": "e45c9b5799fcb46b82bd5f1afc1b30c4",
"global_name": "Jup",
"accent_color": 1,
"avatar_decoration_data": null,
"primary_guild": null
},
"mute": false,
"deaf": false
}
```
### Supplemental Guild Member Object
Additional information about a participating user's join source in a [guild](#guild-object).
###### Supplemental Guild Member Structure
| Field | Type | Description |
| ------------------------------- | ------------------------------------------- | ------------------------------------------------------------------------------------------------------------------ |
| user_id? ^1^ | snowflake | The ID of the user this guild member represents |
| member? ^2^ | [guild member](#guild-member-object) object | The associated guild member |
| join_source_type? | integer | [How the user joined the guild](#join-source-type) |
| source_invite_code? | ?string | The invite code or vanity used to join the guild, if applicable |
| inviter_id? | ?snowflake | The ID of the user or integration that invited the user to the guild, if applicable |
| integration_type? ^1^ | ?string | The [type of integration](/resources/integration#integration-type) that added the user to the guild, if applicable |
| join_source_application_id? ^2^ | ?snowflake | The ID of the application that owns the linked lobby |
| join_source_channel_id? ^2^ | ?snowflake | The ID of the channel the lobby is linked to |
^1^ Only included when fetched from the [List Guild Members Supplemental](#list-guild-members-supplemental) endpoint.
^2^ Only included when fetched from the [Search Guild Members](#search-guild-members) endpoint.
###### Join Source Type
| Value | Name | Description |
| ----- | --------------------------------------- | -------------------------------------------------------------------------------------------------- |
| 0 | UNSPECIFIED | The user joined the guild through an unknown source |
| 1 | BOT | The user was added to the guild by a bot using the [`guilds.join` OAuth2 scope](#add-guild-member) |
| 2 | INTEGRATION | The user was added to the guild by an integration (e.g. Twitch) |
| 3 | DISCOVERY | The user joined the guild through guild discovery |
| 4 | HUB | The user joined the guild through a student hub |
| 5 | INVITE | The user joined the guild through an invite |
| 6 | VANITY_URL | The user joined the guild through a vanity URL |
| 7 | MANUAL_MEMBER_VERIFICATION | The user was accepted into the guild after applying for membership |
| 8 | SOCIAL_LAYER_INTEGRATION_LINKED_CHANNEL | The user joined the guild through a linked lobby |
###### Example Supplemental Guild Member
```json
{
"user_id": "257496590401536000",
"source_invite_code": "41i3n5",
"join_source_type": 5,
"inviter_id": "1001086404203389018",
"integration_type": null
}
```
### Ban Object
A ban for a [guild](#guild-object). Banned users can't rejoin a guild unless [unbanned](#delete-guild-ban).
###### Ban Structure
| Field | Type | Description |
| ------ | -------------------------------------------------- | ---------------------- |
| user | partial [user](/resources/user#user-object) object | The banned user |
| reason | ?string | The reason for the ban |
###### Example Ban
```json
{
"user": {
"id": "53908232506183680",
"username": "mason",
"avatar": "a_d5efa99b3eeaa7dd43acca82f5692432",
"discriminator": "0",
"public_flags": 4325445,
"banner": "42db4e3be824706cb1304fba05995722",
"accent_color": null,
"global_name": "Mason",
"avatar_decoration_data": null,
"primary_guild": null
},
"reason": "mentioning b1nzy"
}
```
### Welcome Screen Object
###### Welcome Screen Structure
| Field | Type | Description |
| ---------------- | ------------------------------------------------------------------------- | -------------------------------------------------------------------- |
| description | ?string | The welcome message shown in the welcome screen (max 140 characters) |
| welcome_channels | array[[welcome screen channel](#welcome-screen-channel-structure) object] | The channels shown in the welcome screen (max 5) |
###### Welcome Screen Channel Structure
| Field | Type | Description |
| ----------- | ---------- | ----------------------------------------------------------------------------------------- |
| channel_id | snowflake | The ID of the channel |
| description | string | The description shown for the channel (1-50 characters) |
| emoji_id | ?snowflake | The [emoji ID](/resources/emoji#emoji-object), if the emoji is custom |
| emoji_name | ?string | The emoji name if custom, the unicode character if standard, or `null` if no emoji is set |
###### Example Welcome Screen
```json
{
"description": "Discord Developers is a place to learn about Discord's API, bots, and SDKs and integrations. This is NOT a general Discord support server.",
"welcome_channels": [
{
"channel_id": "697138785317814292",
"description": "Follow for official Discord API updates",
"emoji_id": null,
"emoji_name": "📡"
},
{
"channel_id": "697236247739105340",
"description": "Get help with Bot Verifications",
"emoji_id": null,
"emoji_name": "📸"
},
{
"channel_id": "697489244649816084",
"description": "Create amazing things with Discord's API",
"emoji_id": null,
"emoji_name": "🔬"
},
{
"channel_id": "613425918748131338",
"description": "Integrate Discord into your game",
"emoji_id": null,
"emoji_name": "🎮"
},
{
"channel_id": "646517734150242346",
"description": "Find more places to help you on your quest",
"emoji_id": null,
"emoji_name": "🔦"
}
]
}
```
### Member Verification Object
In guilds with [member verification](https://support.discord.com/hc/en-us/articles/1500000466882) enabled, when a member joins,
a [Guild Member Add](/gateway/gateway-events#guild-member-add) Gateway event will be dispatched but they will initially be restricted from doing any actions in the guild, and `pending` will be true in the [guild member](#guild-member-object) object.
When the member completes the verification, a [Guild Member Update](/gateway/gateway-events#guild-member-update) Gateway event will be dispatched and `pending` will be false.
To represent a member's progress towards becoming a full member of the guild, a [Guild Join Request Create](/gateway/gateway-events#guild-join-request-create) Gateway event will be dispatched.
Once the join request is approved, the member's `pending` status will be false and they will be able to interact with the guild.
Unless using [manual approval](#manual-approval), the join request will be automatically approved when the user [submits their join request](#create-guild-join-request).
Assigning a member the [`BYPASSES_VERIFICATION` flag](#guild-member-flags) will force their `pending` status to be false and approve their current join request regardless of the join request's status.
Note that bot users will always bypass member verification and have their `pending` status set to false.
#### Guild Previewing
Discoverable guilds, guilds with member verification enabled, and guilds in a directory entry have the [`PREVIEW_ENABLED`](#guild-features) feature by default.
This allows the guild to be lurkable by users who are not members, if discoverable, and allows members who have not passed the verification gate to view the guild without interacting with it.
If a guild has member verification enabled and is not previewable, new joiners will not be able to view the guild until they pass the verification gate, and are therefore not considered members until they do. **This means members do not join the guild until they pass the verification gate.**
A [Guild Member Add](/gateway/gateway-events#guild-member-add) Gateway event will not be dispatched until the member has passed the verification gate, and `pending` will always be false in the [guild member](#guild-member-object) object for new joiners.
Join requests will continue to be dispatched as normal, but there will not be an associated guild member until the join request is approved.
From the joiner's perspective, they will also not receive a [Guild Create](/gateway/gateway-events#guild-create) Gateway event or any other events dispatched from the guild until they pass member verification.
Non-previewable pending guilds can only be retrieved with the [List Join Request Guilds](#list-join-request-guilds) endpoint. Their join requests are also sent in the [`guild_join_requests` field of the Ready event](/gateway/gateway-events#ready).
Note that the preview disabled paradigm only applies if a guild meets one of the requirements for previewing in the first place.
#### Manual Approval
To use [form field types](#member-verification-form-field-type) other than `TERMS`, the guild must have the [`MEMBER_VERIFICATION_MANUAL_APPROVAL` guild feature](#guild-features) enabled.
When using these form field types, join requests must be [manually approved](#action-guild-join-request) after they are [submitted](#create-guild-join-request) before the user can complete member verification.
When only using only [`TERMS` form field types](#member-verification-form-field-type), the join request will be automatically approved when the user [submits the request](#create-guild-join-request).
###### Member Verification Structure
| Field | Type | Description |
| ----------- | ----------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------- |
| version | ?ISO8601 timestamp | When the member verification was last modified |
| form_fields | array[[member verification form field](#member-verification-form-field-structure) object] | Questions for applicants to answer (max 5) |
| description | ?string | A description of what the guild is about; this can be different than the guild's description (max 300 characters) |
| guild ^1^ | ?[member verification guild](#member-verification-guild-structure) object | The guild this member verification is for |
| profile ^1^ | [guild profile](/resources/discovery#guild-profile-object) object | The profile of the guild this member verification is for |
^1^ Only included when fetched from the [Get Guild Member Verification](#get-guild-member-verification) endpoint with `with_guild` set to `true`.
###### Member Verification Form Field Structure
| Field | Type | Description |
| ------------- | ----------------------------- | ---------------------------------------------------------------- |
| field_type | string | The [type of question](#member-verification-form-field-type) |
| label | string | The label for the form field (max 300 characters) |
| choices? | array[string] | Multiple choice answers (1-8, max 150 characters) |
| values? | ?array[string] | The rules that the user must agree to (1-16, max 300 characters) |
| response? ^1^ | ?string \| integer \| boolean | Response for this field |
| required | boolean | Whether this field is required for a successful application |
| description | ?string | The subtext of the form field |
| automations | ?array[string] | Unknown (max 300 characters, max 10) |
| placeholder? | ?string | Placeholder text for the field's response area |
^1^ Not present when fetched from the [Get Guild Member Verification](#get-guild-member-verification) endpoint. For [`TERMS` form fields](#member-verification-form-field-type), the response should be `true`. For [`MULTIPLE_CHOICE` form field types](#member-verification-form-field-type), the response is the index of the selected choice.
###### Member Verification Form Field Type
| Value | Description |
| ---------------- | ---------------------------------------------------------- |
| TERMS | User must agree to the guild rules |
| TEXT_INPUT | User must respond with a short answer (max 150 characters) |
| PARAGRAPH | User must respond with a paragraph (max 1000 characters) |
| MULTIPLE_CHOICE | User must select one of the provided choices |
| ~~VERIFICATION~~ | ~~User must verify their email or phone number~~ |
###### Member Verification Guild Structure
| Field | Type | Description |
| -------------------------- | ---------------------------------------------------- | ------------------------------------------------------------------------------------- |
| id | snowflake | The ID of the guild |
| name | string | The name of the guild (2-100 characters) |
| icon | ?string | The guild's [icon hash](/reference#cdn-formatting) |
| description | ?string | The description for the guild (max 300 characters) |
| splash | ?string | The guild's [splash hash](/reference#cdn-formatting) |
| discovery_splash | ?string | The guild's [discovery splash hash](/reference#cdn-formatting) |
| home_header | ?string | The guild's [home header hash](/reference#cdn-formatting), used in new member welcome |
| verification_level | integer | The [verification level](#verification-level) required for the guild |
| features | array[string] | Enabled [guild features](#guild-features) |
| emojis | array[[emoji](/resources/emoji#emoji-object) object] | Custom guild emoji |
| approximate_member_count | integer | Approximate number of total members in the guild |
| approximate_presence_count | integer | Approximate number of non-offline members in the guild |
###### Example Member Verification
```json
{
"version": "2022-12-21T16:08:17.822000+00:00",
"form_fields": [
{
"field_type": "TERMS",
"label": "Read and agree to the server rules",
"description": null,
"automations": null,
"required": true,
"values": [
"No spam or self-promotion (server invites, advertisements, etc) without permission from a staff member. This includes DMing fellow members.",
"No age-restricted or obscene content. This includes text, images, or links featuring nudity, sex, hard violence, or other graphically disturbing content.",
"If you see something against the rules or something that makes you feel unsafe, let staff know. We want this server to be a welcoming space!"
]
},
{
"field_type": "TEXT_INPUT",
"label": "Why do you like aliens?",
"description": null,
"automations": null,
"required": true,
"placeholder": null
},
{
"field_type": "MULTIPLE_CHOICE",
"label": "What is your favorite alien movie?",
"description": null,
"automations": null,
"required": true,
"choices": ["Alien", "E.T."]
}
],
"description": "Alien",
"guild": {
"id": "1046920999469330512",
"name": "Alien Network",
"icon": "66b0f4d96c145970fa9d96ada8afadf3",
"description": "Where the 👽s 👽 and sometimes very 👽 things happen 😨.",
"home_header": "39ba384a31e9c285649ad00b359946ab",
"splash": "b40e61f7730b8781b9a551964570e0cc",
"discovery_splash": "0e11ae8d9f1c86958be05e61b0c90ac3",
"features": [],
"approximate_member_count": 100,
"approximate_presence_count": 99,
"emojis": [],
"verification_level": 2
}
}
```
### Guild Join Request Object
Guild join requests are an extension of [member verification](#member-verification-object) that represent a user's request to join a guild.
A join request is created when a user attempts to join a guild with member verification enabled, and the user must complete the verification process to join the guild.
All join requests are stored for 180 days.
Most join request features require the [`MEMBER_VERIFICATION_MANUAL_APPROVAL` guild feature](#guild-features), as join request are automatically actioned when only using the `TERMS` [form field type](#member-verification-form-field-type) and do not require manual approval.
This includes most of the join request endpoints, such as [Get Guild Join Request](#get-guild-join-request) and [Action Guild Join Request](#action-guild-join-request).
Guild join requests are not returned to moderators until they are submitted by the user.
###### Guild Join Request Structure
| Field | Type | Description |
| --------------------------------- | ------------------------------------------------------------------------------------------ | ----------------------------------------------------------------------------------- |
| id | snowflake | The ID of the join request |
| join_request_id | snowflake | The ID of the join request |
| created_at | ISO8601 timestamp | When the join request was created |
| application_status | string | The [status of the join request](#guild-join-request-status) |
| guild_id | snowflake | The ID of the guild this join request is for |
| form_responses? ^1^ | ?array[[member verification form field](#member-verification-form-field-structure) object] | Responses to the guild's member verification questions |
| last_seen | ?ISO8601 timestamp | When the request was acknowledged by the user |
| actioned_at? **(deprecated)** ^1^ | snowflake | A snowflake representing when the join request was actioned |
| reviewed_at? ^1^ | ISO8601 timestamp | When the join request was actioned |
| actioned_by_user? ^1^ | partial [user](/resources/user#user-object) object | The moderator who actioned the join request |
| rejection_reason | ?string | Why the join request was rejected |
| user_id | snowflake | The ID of the user who created this join request |
| user? ^1^ ^2^ | partial [user](/resources/user#user-object) object | The user who created this join request |
| interview_channel_id | ?snowflake | The ID of a channel where an interview regarding this join request may be conducted |
^1^ Only included when fetched from the [Get Guild Join Request](#get-guild-join-request) or [List Guild Join Requests](#list-guild-join-requests) endpoints, or when receiving a [related Gateway event](/gateway/gateway-events#guild-join-request-create) as a moderator.
^2^ Only guaranteed for users other than the current user.
###### Guild Join Request Status
| Value | Description |
| --------- | ---------------------------------------- |
| STARTED | The request is started but not submitted |
| SUBMITTED | The request has been submitted |
| REJECTED | The request has been rejected |
| APPROVED | The request has been approved |
###### Example Guild Join Request
```json
{
"created_at": "2024-05-20T03:45:28.965000+00:00",
"join_request_id": "1241959960003477524",
"id": "1241959960003477524",
"rejection_reason": null,
"application_status": "APPROVED",
"actioned_at": "2024-05-20T03:45:44.547975+00:00",
"actioned_by_user": {
"id": "828387742575624222",
"username": "jupppper",
"avatar": "e14a7c62b0b38068be88be194b23910f",
"discriminator": "0",
"public_flags": 16384,
"banner": "e45c9b5799fcb46b82bd5f1afc1b30c4",
"global_name": "Jup",
"accent_color": 1,
"avatar_decoration_data": null,
"primary_guild": null
},
"form_responses": [
{
"field_type": "TERMS",
"label": "Read and agree to the server rules",
"description": null,
"automations": null,
"required": true,
"values": [
"No spam or self-promotion (server invites, advertisements, etc) without permission from a staff member. This includes DMing fellow members.",
"No age-restricted or obscene content. This includes text, images, or links featuring nudity, sex, hard violence, or other graphically disturbing content.",
"If you see something against the rules or something that makes you feel unsafe, let staff know. We want this server to be a welcoming space!"
],
"response": true
},
{
"field_type": "TEXT_INPUT",
"label": "Why do you like aliens?",
"description": null,
"automations": null,
"required": true,
"placeholder": null,
"response": "I like aliens because they're cool!"
},
{
"field_type": "MULTIPLE_CHOICE",
"label": "What is your favorite alien movie?",
"description": null,
"automations": null,
"required": true,
"values": ["Alien", "E.T."],
"response": 0
}
],
"last_seen": "2024-05-20T03:45:44.547975+00:00",
"guild_id": "1046920999469330512",
"user_id": "852892297661906993",
"user": {
"id": "852892297661906993",
"username": "alien",
"global_name": "Alien",
"avatar": "14733482e560d9267c0a414b21b2fb8d",
"discriminator": "0",
"public_flags": 64,
"avatar_decoration_data": null,
"primary_guild": null
},
"interview_channel_id": null
}
```
### Onboarding Object
The [onboarding](https://support.discord.com/hc/en-us/articles/11074987197975-Community-Onboarding-FAQ) flow for a guild.
Onboarding enforces constraints when enabled. These constraints are that at least one default channel must allow sending messages to the default (@everyone) role. The `mode` field modifies what is considered when enforcing these constraints.
###### Onboarding Structure
| Field | Type | Description |
| ------------------------------ | ----------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------ |
| guild_id | snowflake | The ID of the guild this onboarding is part of |
| prompts | array[[onboarding prompt](#onboarding-prompt-structure) object] | The prompts shown during onboarding and in community customization |
| default_channel_ids | array[snowflake] | The channel IDs that members get opted into automatically |
| enabled | boolean | Whether onboarding is enabled in the guild |
| below_requirements | boolean | Whether the guild is below the requirements for onboarding |
| mode | integer | The current [criteria mode](#onboarding-mode) for onboarding |
| connections? | array[[onboarding connection](#onboarding-connection-structure) object] | Connection recommendations shown during onboarding |
| responses? ^1^ | array[snowflake] | The onboarding prompt option IDs the current user has chosen |
| onboarding_prompts_seen? ^1^ | map[snowflake, integer] | A mapping of prompt IDs to Unix timestamps (in milliseconds) of when the current user saw the prompt |
| onboarding_responses_seen? ^1^ | map[snowflake, integer] | A mapping of prompt option IDs to Unix timestamps (in milliseconds) of when the current user saw the prompt option |
^1^ Only included when fetched from the [Get Guild Onboarding](#get-guild-onboarding) endpoint.
###### Onboarding Mode
Defines the criteria used to satisfy onboarding constraints that are required for enabling.
| Value | Name | Description |
| ----- | ------------------- | -------------------------------------------------------- |
| 0 | ONBOARDING_DEFAULT | Count only default channels towards constraints |
| 1 | ONBOARDING_ADVANCED | Count default channels and questions towards constraints |
###### Onboarding Prompt Structure
| Field | Type | Description |
| ------------- | ----------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------- |
| id | snowflake | The ID of the prompt |
| type | integer | The [type of prompt](#onboarding-prompt-type) |
| options | array[[onboarding prompt option](#onboarding-prompt-option-structure) object] | Options available within the prompt |
| title | string | The title of the prompt |
| single_select | boolean | Whether users are limited to selecting one option for the prompt |
| required | boolean | Whether the prompt is required before a user completes the onboarding flow |
| in_onboarding | boolean | Wether the prompt is present in the onboarding flow, or only appears in community customization |
###### Onboarding Prompt Option Structure
| Field | Type | Description |
| ----------- | --------------------------------------------- | ---------------------------------------------------------------- |
| id | snowflake | The ID of the prompt option |
| channel_ids | array[snowflake] | The channel IDs a member is added to when the option is selected |
| role_ids | array[snowflake] | The role IDs assigned to a member when the option is selected |
| emoji | [emoji](/resources/emoji#emoji-object) object | Emoji representing the option |
| title | string | The title of the option |
| description | ?string | The description for the option |
###### Onboarding Prompt Type
| Value | Name | Description |
| ----- | --------------- | --------------------------------------------- |
| 0 | MULTIPLE_CHOICE | Prompt offers multiple options to select from |
| 1 | DROPDOWN | Prompt offers a dropdown menu to select from |
###### Onboarding Connection Structure
| Field | Type | Description |
| ------------------ | ---------- | ------------------------------------------------------------------------ |
| connection_type | integer | The [type of onboarding connection](#onboarding-connection-type) |
| application_id ^1^ | ?snowflake | The ID of the application |
| provider_id ^2^ | ?string | The [connection provider](/resources/connected-accounts#connection-type) |
| description | string | The connection description |
^1^ Only applicable if `connection_type` is `APPLICATION`.
^2^ Only applicable if `connection_type` is `PROVIDER_CONNECTED_ACCOUNT`.
###### Onboarding Connection Type
| Value | Name | Description |
| ----- | -------------------------- | -------------------------------------- |
| 0 | APPLICATION | Application role connection suggestion |
| 1 | PROVIDER_CONNECTED_ACCOUNT | Connected account suggestion |
###### Example Onboarding
```json
{
"guild_id": "960007075288915998",
"prompts": [
{
"id": "1067461047608422473",
"title": "What do you want to do in this community?",
"options": [
{
"id": "1067461047608422476",
"title": "Chat with Friends",
"description": "",
"emoji": {
"id": "1070002302032826408",
"name": "chat",
"animated": false
},
"role_ids": [],
"channel_ids": ["962007075288916001"]
},
{
"id": "1070004843541954678",
"title": "Get Gud",
"description": "We have excellent teachers!",
"emoji": {
"id": null,
"name": "😀",
"animated": false
},
"role_ids": ["982014491980083211"],
"channel_ids": []
}
],
"single_select": false,
"required": false,
"in_onboarding": true,
"type": 0
}
],
"default_channel_ids": [
"998678771706110023",
"998678693058719784",
"1070008122577518632",
"998678764340912138",
"998678704446263309",
"998678683592171602",
"998678699715067986"
],
"enabled": true,
"mode": 0,
"below_requirements": false
}
```
### Onboarding Responses Object
###### Onboarding Responses Structure
| Field | Type | Description |
| ------------------------- | ----------------------- | ------------------------------------------------------------------------------------------------------------------ |
| guild_id | snowflake | The ID of the guild the onboarding responses are for |
| user_id | snowflake | The ID of the user that did onboarding |
| onboarding_responses | array[snowflake] | The onboarding prompt option IDs the current user has chosen |
| onboarding_prompts_seen | map[snowflake, integer] | A mapping of prompt IDs to Unix timestamps (in milliseconds) of when the current user saw the prompt |
| onboarding_responses_seen | map[snowflake, integer] | A mapping of prompt option IDs to Unix timestamps (in milliseconds) of when the current user saw the prompt option |
### New Member Welcome Object
The welcome experience for new and existing members in a guild, also known as the server guide.
The new member welcome experience enforces constraints when enabled. These constraints are that there must be at least 3 new member actions, all referenced channels must be viewable by the default role,
and new member action channels with an [`action_type` of `CHAT`](#new-member-action-type) must allow sending messages to the default role.
###### New Member Welcome Structure
| Field | Type | Description |
| ------------------ | -------------------------------------------------------------------------- | ----------------------------------------------------------------- |
| guild_id | snowflake | The ID of the guild this new member welcome is for |
| enabled | boolean | Whether the new member welcome experience is enabled |
| welcome_message | [new member welcome message](#new-member-welcome-message-structure) object | Welcome message shown to new members of the guild |
| new_member_actions | array[[new member action](#new-member-action-structure) object] | Actions shown to new members of the guild (max 5) |
| resource_channels | array[[resource channel](#resource-channel-structure) object] | Read-only channels that provide resources for new members (max 7) |
###### New Member Welcome Message Structure
| Field | Type | Description |
| -------------- | ---------------- | -------------------------------------------------------------- |
| author_ids ^1^ | array[snowflake] | The IDs of the users who authored the welcome message (max 10) |
| message ^2^ | string | The welcome message shown to new members (max 300 characters) |
^1^ New member welcome message authors must be guild members with the `MANAGE_GUILD` or `MANAGE_ROLES` permission.
^2^ `[@username]` may be used as a placeholder for the member's name.
###### New Member Action Structure
| Field | Type | Description |
| ----------- | ----------------------------------------------------- | --------------------------------------------------------------------------------- |
| channel_id | snowflake | The ID of the channel where the action is located |
| action_type | integer | The [type of action](#new-member-action-type) the user should take in the channel |
| title | string | The title of the action (max 60 characters) |
| description | string | The description of the action (max 200 characters) |
| emoji? | partial [emoji](/resources/emoji#emoji-object) object | The emoji representing the action |
| icon? | string | The [icon hash](/reference#cdn-formatting) representing the action |
###### New Member Action Type
| Value | Name | Description |
| ----- | ---- | ----------------------------- |
| 0 | VIEW | View the channel |
| 1 | CHAT | Send a message in the channel |
###### Resource Channel Structure
| Field | Type | Description |
| ----------- | ----------------------------------------------------- | ---------------------------------------------------------------------------- |
| channel_id | snowflake | The ID of the channel that provides resources for new members |
| title | string | The title of the resource channel (max 60 characters) |
| description | string | The description of the resource channel (max 200 characters) |
| emoji? | partial [emoji](/resources/emoji#emoji-object) object | The emoji representing the resource channel |
| icon? | string | The [icon hash](/reference#cdn-formatting) representing the resource channel |
###### Example New Member Welcome
```json
{
"guild_id": "1029315212005888060",
"enabled": false,
"welcome_message": {
"author_ids": ["852892297661906993"],
"message": "Hello [@username], 👽👽👽"
},
"new_member_actions": [
{
"channel_id": "1029316811088478299",
"action_type": 0,
"title": "Get your info",
"description": "",
"emoji": {
"id": null,
"name": "👽",
"animated": false
}
}
],
"resource_channels": [
{
"channel_id": "1029316811088478299",
"title": "Info",
"description": "Absolute cinema"
}
]
}
```
### New Member Actions Progress Object
A user's progress towards completing the new member actions in a guild.
###### New Member Actions Progress Structure
| Field | Type | Description |
| --------------- | ------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------ |
| guild_id | snowflake | The ID of the guild this new member actions progress is for |
| user_id | snowflake | The ID of the user this new member actions progress is for |
| channel_actions | map[snowflake, [new member action progress](#new-member-action-progress-structure) object] | The progress of the user in each new member action channel they have interacted with |
###### New Member Action Progress Structure
| Field | Type | Description |
| --------- | ------- | ------------------------------------------------------------------- |
| completed | boolean | Whether the user has completed the new member action in the channel |
###### Example New Member Actions Progress
```json
{
"guild_id": "1029315212005888060",
"user_id": "852892297661906993",
"channel_actions": {
"1029316811088478299": {
"completed": true
}
}
}
```
### Premium Guild Subscription Object
Represents a member's premium guild subscription ([boost](https://support.discord.com/hc/en-us/sections/360007875211-Server-Boosting)).
###### Premium Guild Subscription Structure
| Field | Type | Description |
| ------------- | -------------------------------------------------- | ------------------------------------------------------------------------------------------------ |
| id | snowflake | The ID of the premium guild subscription |
| guild_id | snowflake | The ID of the guild this subscription is for |
| user_id | snowflake | The ID of the user who created this premium guild subscription |
| ended | boolean | If this premium guild subscription has ended |
| ends_at? | ISO8601 timestamp | When this premium guild subscription will expire |
| pause_ends_at | ?ISO8601 timestamp | When the user's overall subscription pause will end, reactivating the premium guild subscription |
| user ^1^ | partial [user](/resources/user#user-object) object | The user this premium guild subscription is for |
^1^ Omitted in the [Guild Applied Boosts Update](/gateway/gateway-events#guild-applied-boosts-update) Gateway event.
###### Example Premium Guild Subscription
```json
{
"id": "1315132642890350602",
"user_id": "673658900435697665",
"guild_id": "1081635484209520802",
"ended": false,
"pause_ends_at": null,
"user": {
"id": "673658900435697665",
"username": "android",
"global_name": "Android",
"avatar": "08f104f8d5406c4d46916794fe2efeb7",
"avatar_decoration_data": {
"asset": "a_8552f9857793aed0cf816f370e2df3be",
"sku_id": "1232071712695386162",
"expires_at": null
},
"collectibles": null,
"discriminator": "0",
"public_flags": 4194560,
"primary_guild": null
}
}
```
### Game Server Object
###### Game Server Structure
| Field | Type | Description |
| ------------------ | ---------------------------------------------------------- | -------------------------------------------------------------- |
| id | snowflake | The ID of the game server |
| name | string | The name of the game server |
| region_id? | ?string | The ID of the game server region |
| region_name? | ?string | The name of the game server region |
| sku_id | snowflake | The ID of the SKU |
| plan_name | string | The name of the server plan |
| players_count? | ?integer | Current amount of players connected to the game server |
| max_players_count? | ?integer | Maximum amount of players that can connect to the game server |
| ip? | string | The IP of the game server |
| port? | string | The port of the game server |
| entitlement_id | snowflake | The ID of the entitlement |
| provider_type | string | The [type of game server provider](#game-server-provider-type) |
| provider_url? | ?string | The panel URL to the game server |
| status | integer | The [status](#game-server-status) of the game server |
| game_id | snowflake | The ID of the game application |
| game_config? | [game server config](#game-server-config-structure) object | The game config |
###### Game Server Provider Type
| Value | Description |
| --------- | ----------- |
| shockbyte | ShockByte |
###### Game Server Status
| Value | Description |
| ---------------- | -------------------------------------- |
| starting | Game server is starting |
| startup_failed | Game server failed to start |
| missing_stock | Game server's location is out of stock |
| sleeping | Game server is sleeping |
| offline | Game server is offline |
| online | Game server is online |
| deleted | Game server has been deleted |
| provider_errored | Game server's provider had an error |
###### Game Server Config Structure
| Field | Type | Description |
| ------- | ------ | ------------------------------ |
| type | string | The type of the game server |
| version | string | The version of the game server |
###### Example Game Server
```json
{
"id": "1429548737042186251",
"status": "online",
"sku_id": "1425220365138792480",
"entitlement_id": "1429548737042186250",
"game_id": "1402418491272986635",
"name": "Alien Minecraft SMP",
"region_id": "poland",
"region_name": "Poland",
"plan_name": "Ultimate Plan",
"ip": "162.159.136.232",
"port": "42252",
"max_players_count": 15,
"players_count": 2,
"provider_url": "https://discord.shockbyte.com/server/6a7dd5e2-9e60-48fd-bb3c-6f7efc108db1",
"provider_type": "shockbyte",
"game_config": {
"version": "1.21.8",
"type": "Paper"
}
}
```
### Role Subscription Settings Object
###### Role Subscription Settings Structure
| Field | Type | Description |
| --------------------------------------- | --------------------------------------------------------- | -------------------------------------------------------------------------------------------------- |
| guild_id | snowflake | The ID of the guild |
| full_server_gate | boolean | Whether the guild is fully gated behind a role subscription |
| description? | ?string | The description of the guild's shop |
| server_shop_tab_order | integer | The [order of tabs in guild shop](#guild-product-shop-tabs-order-type) |
| store_page_primary_color? | ?integer | The store page accent color encoded as an integer representation of a hexadecimal color code |
| store_page_trailer_url? | ?string | The URL to the teaser trailer YouTube video |
| store_page_show_subscriber_count? | boolean | Whether to show amount of role subscribers on the store page |
| store_page_guild_products_default_sort? | integer | The default [sort order](#guild-product-sort-order-type) of the guild's products on the store page |
| cover_image_asset? | [store asset](/resources/store#store-asset-object) object | The guild shop's cover image |
| store_page_slug ^1^ | string | The store page's slug |
^1^ Store pages are accessible at `https://discord.com/servers/`.
###### Guild Product Shop Tabs Order Type
| Value | Name | Description |
| ----- | -------------- | ------------------- |
| 1 | SUBS_FIRST | Subscriptions first |
| 2 | PRODUCTS_FIRST | Products first |
| 3 | UNKNOWN_3 | Unknown |
###### Guild Product Sort Order Type
| Value | Name | Description |
| ----- | --------------- | ------------------------------------ |
| 1 | NAME | Sort by name |
| 2 | PRICE_ASC | Sort by price in ascending order |
| 3 | PRICE_DESC | Sort by price in descending order |
| 4 | NEWEST_ARRIVALS | Sort by creation in descending order |
###### Example Role Subscriptions Settings
```json
{
"guild_id": "1029315212005888060",
"full_server_gate": false,
"description": "not the neller man",
"server_shop_tab_order": 2,
"store_page_primary_color": 5868359,
"store_page_trailer_url": "https://youtube.com/watch?v=LLFhKaqnWwkk",
"store_page_show_subscriber_count": true,
"store_page_guild_products_default_sort": 4,
"cover_image_asset": {
"id": "1118997969761489088",
"size": 248825,
"mime_type": "image/jpeg",
"width": 1600,
"height": 1344,
"application_id": "1050921725816213565"
},
"store_page_slug": "alien-network-1029315212005888060"
}
```
### Guild Product Listing Object
###### Guild Product Listing Structure
| Field | Type | Description |
| ----------------- | ---------------------------------------------------------------- | -------------------------------------------------------------------- |
| id | snowflake | The ID of the SKU |
| application_id | snowflake | The ID of the application |
| guild_id | snowflake | The ID of the guild |
| name | string | The name of the product listing |
| description | string | The description of the product listing |
| image_asset | ?[store asset](/resources/store#store-asset-object) object | The thumbnail of the product listing |
| role_id | snowflake | The ID of the role granted |
| published | boolean | Whether the product listing is published |
| has_entitlement | boolean | Whether the current user has an entitlement for the product listing |
| attachments_count | integer | Number of attachments granted by the product listing |
| published_at | ISO8601 timestamp | When the product listing was published at |
| price_tier | integer | The [base price](/resources/store#list-store-price-tiers) of the SKU |
| attachments | array[[attachment](/resources/message#attachment-object) object] | The attachments granted by the product listing |
| price | [unit price](/resources/payment#unit-price-structure) object | The price for the product listing |
### Role Subscription Group Listing Object
###### Role Subscription Group Listing Structure
| Field | Type | Description |
| -------------------------- | ----------------------------------------------------------------------------------------------- | ------------------------------------------------- |
| id | snowflake | The ID of the subscription group listing |
| guild_id | snowflake | The ID of the guild |
| application_id | snowflake | The ID of the application |
| name | string | The name of the subscription group listing |
| description | string | The description of the subscription group listing |
| subscription_listings_ids? | array[snowflake] | The IDs of the subscription listing SKUs |
| subscription_listings? | array[[role subscription listing](#role-subscription-listing-object) object] | The subscription listings |
| benefit_channels? | array[[role subscription benefit channel](#role-subscription-benefit-channel-structure) object] | The benefits for the channel |
###### Role Subscription Benefit Channel Structure
| Field | Type | Description |
| ----- | --------- | ----------------------- |
| id | snowflake | The ID of the channel |
| name | string | The name of the channel |
### Role Subscription Listing Object
###### Role Subscription Listing Structure
| Field | Type | Description |
| ------------------ | ---------------------------------------------------------------------------- | ------------------------------------------------ |
| id | snowflake | The ID of the SKU |
| guild_id | snowflake | The ID of the guild |
| application_id | snowflake | The ID of the application |
| name | string | The name of the subscription listing |
| description | string | The description of the subscription listing |
| image_asset | [store asset](/resources/store#store-asset-object) object | The thumbnail of the subscription listing |
| subscription_plans | array[[subscription plan](/resources/store#subscription-plan-object) object] | The subscription plans for the listing |
| role_benefits | [role subscription benefits](#role-subscription-benefits-structure) object | The role benefits |
| role_id | snowflake | The ID of the role given by the subscription |
| published | boolean | Whether the subscription listing is published |
| soft_deleted | boolean | Whether the subscription listing is soft deleted |
| archived | boolean | Whether the subscription listing is archived |
###### Role Subscription Benefits Structure
| Field | Type | Description |
| -------- | ------------------------------------------------------------------------------- | ------------------------ |
| sku_id | snowflake | The ID of the SKU |
| benefits | array[[role subscription benefit](#role-subscription-benefit-structure) object] | The benefits of the role |
###### Role Subscription Benefit Structure
| Field | Type | Description |
| -------------- | ---------- | -------------------------------------------------------- |
| emoji_id ^1^ | ?snowflake | The ID of a guild's custom emoji |
| emoji_name ^1^ | ?string | The unicode character of the emoji |
| name | string | The name of the benefit |
| description | string | The description of the benefit |
| ref_type | integer | The [type of reference](#role-subscription-benefit-type) |
| ref_id | ?snowflake | The ID of the referenced entity |
^1^ At most one of `emoji_id` and `emoji_name` may be set to a non-null value.
###### Role Subscription Benefit Type
| Value | Name | Description | Reference Type |
| ----- | ---------- | ------------------- | --------------------------------------------------- |
| 1 | CHANNEL | Access to a channel | [channel](/resources/channel#channel-object) object |
| 2 | INTANGIBLE | Intangible benefit | — |
### Role Subscription Trial Object
###### Role Subscription Trial Structure
| Field | Type | Description |
| -------------------------- | ------------------------------------------------------------------------------ | ---------------------------------------------------- |
| id | snowflake | The ID of the role subscription listing |
| num_active_trial_users | integer | Number of active users on the trial |
| max_num_active_trial_users | ?integer | Maximum number of possibly active users on the trial |
| active_trial? | [subscription trial](/resources/subscription#subscription-trial-object) object | The associated subscription trial |
### Creator Monetization Request Object
###### Creator Monetization Request Structure
| Field | Type | Description |
| ------------------ | ------------------ | ---------------------------------------------------------------- |
| id | snowflake | The ID of the creator monetization request |
| state | string | The [state of application](#creator-monetization-request-state) |
| actioned_at | ?ISO8601 timestamp | When the creator monetization request was actioned |
| requester_id | snowflake | The ID of the user that created the creator monetization request |
| requester_acked_at | ?ISO8601 timestamp | When the creator monetization request action was acknowledged |
###### Creator Monetization Request State
| Value | Description |
| --------------- | --------------------------- |
| OPEN | The application is open |
| REJECTED | The application is rejected |
| APPROVED | The application is approved |
| ACTION_REQUIRED | Action required |
## Endpoints
List User Guilds
Returns a list of [user guild](#user-guild-object) objects representing the guilds the current user is a member of.
This endpoint returns 200 guilds by default, which is the maximum number of guilds a non-bot user can join. Therefore, pagination is **not typically needed** in order to get a list of the users' guilds, and all parameters are optional.
###### Query String Params
| Field | Type | Description |
| ---------------- | --------- | ------------------------------------------------------------------------- |
| before? | snowflake | Get guilds before this guild ID |
| after? | snowflake | Get guilds after this guild ID |
| limit? | integer | Max number of guilds to return (1-200, default 200) |
| with_counts? ^1^ | boolean | Whether to include approximate member and presence counts (default false) |
^1^ For OAuth2 requests, this parameter requires the additional `guilds.members.read` scope.
List Join Request Guilds
Returns a list of partial [guild](#guild-object) objects representing [non-previewable guilds](#guild-previewing) the current user has pending join requests for.
Leave Guild
Leaves the given guild ID. Returns a 204 empty response on success. Fires a [Guild Delete](/gateway/gateway-events#guild-delete) and a [Guild Member Remove](/gateway/gateway-events#guild-member-remove) Gateway event.
###### JSON Params
| Field | Type | Description |
| -------- | ------- | -------------------------------------------------------- |
| lurking? | boolean | Whether the user is lurking in the guild (default false) |
Create Guild
Creates a new guild. Returns a [guild](#guild-object) object on success. Fires a [Guild Create](/gateway/gateway-events#guild-create) Gateway event.
If not specified, the below parameters use defaults from the `2TffvPucqHkN` [guild template](/resources/guild-template#guild-template-object).
###### JSON Params
| Field | Type | Description |
| ------------------------------ | ------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------- |
| name | string | The name of the guild (2-100 characters, excluding trailing and leading whitespace) |
| description? | ?string | The description for the guild (max 300 characters) |
| region? **(deprecated)** | ?string | The main [voice region](/resources/voice#voice-region-object) ID of the guild |
| icon? | ?[image data](/reference#cdn-data) | The guild's icon |
| verification_level? | ?integer | The [verification level](#verification-level) required for the guild |
| default_message_notifications? | ?integer | Default [message notification level](#message-notification-level) for the guild |
| explicit_content_filter? | ?integer | [Whose messages](#explicit-content-filter-level) are scanned and deleted for explicit content in the guild |
| preferred_locale? | ?string | The preferred locale of the guild (default "en-US") |
| roles? ^1^ | ?array[partial [role](#role-object) object] | Roles in the new guild |
| channels? ^2^ | ?array[partial [channel](/resources/channel#channel-object) object] | Channels in the new guild |
| afk_channel_id? | ?snowflake | The ID of the guild's AFK channel; this is where members in voice idle for longer than `afk_timeout` are moved |
| afk_timeout? | ?integer | The AFK timeout of the guild (one of 60, 300, 900, 1800, 3600, in seconds) |
| system_channel_id? | ?snowflake | The ID of the channel where system event messages, such as member joins and premium subscriptions (boosts), are posted |
| system_channel_flags? | ?integer | The [flags](#system-channel-flags) that limit system event messages |
| guild_template_code? | ?string | The [template](/resources/guild-template#guild-template-object) code that inspired this guild, used for analytics |
| staff_only? ^3^ | boolean | Whether the new guild will only be accessible for Discord employees |
^1^ The first member of the array is used to change properties of the guild's default (@everyone) role. If you are trying to bootstrap a guild with additional roles, keep this in mind. Additionally, the required `id` field within each role object is an integer placeholder, and will be replaced by the API upon consumption. Its purpose is to allow you to [overwrite](/resources/channel#permission-overwrite-object) a role's permissions in a channel when also passing in channels with the channels array.
^2^ The `id` field within each channel object may be set to an integer placeholder, and will be replaced by the API upon consumption. Its purpose is to allow you to create `GUILD_CATEGORY` channels by setting the `parent_id` field on any children to the category's `id` field. Category channels must be listed before any children.
^3^ Adds the [`INTERNAL_EMPLOYEE_ONLY` guild feature](#guild-features), making the server only available for Discord employees. Only settable by Discord employees.
###### Example Partial Channel Object
```json
[
{
"name": "my-category",
"type": 4,
"id": 1
},
{
"name": "naming-things-is-hard",
"type": 0,
"parent_id": 1
}
]
```
Get Guild
Returns a [guild](#guild-object) object for the given guild ID. User must be a member of the guild.
###### Query String Params
| Field | Type | Description |
| ------------ | ------- | ------------------------------------------------------------------------- |
| with_counts? | boolean | Whether to include approximate member and presence counts (default false) |
Get Guild Basic
Returns a partial [guild](#guild-object) object for the given guild ID. If the user is not in the guild, the guild must be discoverable.
Get Guild Preview
Returns a partial [guild](#guild-object) object for the given guild ID with all partial fields. If the user is not in the guild, the guild must be discoverable.
Modify Guild
Modifies a guild's settings. Requires the `MANAGE_GUILD` permission. Returns the updated [guild](#guild-object) object on success. Fires a [Guild Update](/gateway/gateway-events#guild-update) Gateway event.
Upon transferring ownership of a guild with creator monetization enabled, the new owner will need to accept the terms before the feature can be used.
###### JSON Params
| Field | Type | Description |
| ------------------------------- | ---------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| name? | string | The name of the guild (2-100 characters, excluding trailing and leading whitespace) |
| icon? | ?[image data](/reference#cdn-data) | The guild's icon; animated icons are only shown when the guild has the `ANIMATED_ICON` feature |
| banner? | ?[image data](/reference#cdn-data) | The guild's banner; banners are only shown when the guild has the `BANNER` feature, animated banners are only shown when the guild has the `ANIMATED_BANNER` feature |
| home_header? | ?[image data](/reference#cdn-data) | The guild's home header, used in new member welcome; home headers are only shown when the guild has the `BANNER` feature |
| splash? | ?[image data](/reference#cdn-data) | The guild's invite splash; splashes are only shown when the guild has the `INVITE_SPLASH` feature |
| discovery_splash? | ?[image data](/reference#cdn-data) | The guild's discovery splash |
| owner_id? | snowflake | The user ID of the guild's owner (must be the current owner); if the current owner has an email address associated with their account and does not have MFA enabled, `code` must be provided |
| code? ^2^ | string | The guild ownership transfer code |
| description? | ?string | The description for the guild (max 300 characters) |
| region? **(deprecated)** | ?string | The main [voice region](/resources/voice#voice-region-object) ID of the guild |
| afk_channel_id? | ?snowflake | The ID of the guild's AFK channel; this is where members in voice idle for longer than `afk_timeout` are moved |
| afk_timeout? | integer | The AFK timeout of the guild (one of 60, 300, 900, 1800, 3600, in seconds) |
| verification_level? | integer | The [verification level](#verification-level) required for the guild |
| default_message_notifications? | integer | Default [message notification level](#message-notification-level) for the guild |
| explicit_content_filter? | integer | [Whose messages](#explicit-content-filter-level) are scanned and deleted for explicit content in the guild |
| features? | array[string] | [Mutable guild features](#mutable-guild-features) |
| system_channel_id? ^1^ | ?snowflake | The ID of the channel where system event messages, such as member joins and premium subscriptions (boosts), are posted |
| system_channel_flags? | integer | The [flags](#system-channel-flags) that limit system event messages |
| rules_channel_id? ^1^ | ?snowflake | The ID of the channel where community guilds display rules and/or guidelines |
| public_updates_channel_id? | ?snowflake | The ID of the channel where admins and moderators of community guilds receive notices from Discord |
| safety_alerts_channel_id? | ?snowflake | The ID of the channel where admins and moderators of community guilds receive safety alerts from Discord |
| preferred_locale? | string | The preferred locale of the guild; used in discovery and notices from Discord (default "en-US") |
| owner_configured_content_level? | integer | The owner-configured [NSFW level](#nsfw-level) of the guild |
| premium_progress_bar_enabled? | boolean | Whether the guild has the premium (boost) progress bar enabled |
^1^ Setting these to a value of `1` will implicitly create a new "#rules" or "#moderator-only" channel.
^2^ This value can be obtained by requesting a verification code with the [Get Guild Ownership Transfer Code](#get-guild-ownership-transfer-code) endpoint.
Modify Guild MFA Level
Modifies the guild's [MFA requirement](#mfa-level) for administrative actions within the guild. User must be the owner. Fires a [Guild Update](/gateway/gateway-events#guild-update) Gateway event.
###### JSON Params / Response Body
| Field | Type | Description |
| ----- | ------- | ---------------------------------------------------------------------------- |
| level | integer | Required [MFA level](#mfa-level) for administrative actions within the guild |
###### Example Response
```json
{
"level": 1
}
```
Get Guild Ownership Transfer Code
Sends a verification code to the guild owner's email address to initiate the guild ownership transfer process. User must be the owner. Returns a 204 empty response on success.
This endpoint should only be used when the current owner has an email address associated with their account and does not have MFA enabled.
If the owner does not have an email address associated with their account or has MFA enabled, a code is not required to transfer ownership.
Delete Guild
Deletes a guild permanently. User must be the owner. Returns a 204 empty response on success. Fires a [Guild Delete](/gateway/gateway-events#guild-delete) Gateway event.
List Guild Members
Returns a list of [guild member](#guild-member-object) objects that are members of the guild. User must be a member of the guild.
This endpoint is not usable by user accounts and is restricted according to whether the `GUILD_MEMBERS` [Privileged Intent](/gateway/using-gateway#privileged-intents) is enabled for the application.
###### Query String Params
| Field | Type | Description |
| ------ | --------- | --------------------------------------------------- |
| limit? | integer | Max number of members to return (1-1000, default 1) |
| after? | snowflake | Get members after this member ID |
Query Guild Members
Returns a list of [guild member](#guild-member-object) objects whose username or nickname contains a provided string. User must be a member of the guild.
Functionally identical to the [Request Guild Members](/gateway/gateway-events#request-guild-members) Gateway Opcode.
This endpoint is not usable by user accounts.
###### Query String Params
| Field | Type | Description |
| ------ | ------- | --------------------------------------------------- |
| query | string | Query to match username(s) and nickname(s) against |
| limit? | integer | Max number of members to return (1-1000, default 1) |
Search Guild Members
Returns [supplemental guild member](#supplemental-guild-member-object) objects containing [guild member](#guild-member-object) objects that match a specified query. Requires the `MANAGE_GUILD` permission.
This endpoint utilizes Elasticsearch to power results. This means that while it is very powerful, it's also tricky to use and reliant on the index, meaning results may not be immediately available for a recently-joined member.
For applications, this endpoint is restricted according to whether the `GUILD_MEMBERS` [Privileged Intent](/gateway/using-gateway#privileged-intents) is enabled for the application.
If the guild you are searching is not yet indexed, the endpoint will return a 202 accepted response. The response body will not contain any search results, and will look similar to an error response:
```json
{
"message": "Index not yet available. Try again later",
"code": 110000,
"documents_indexed": 0,
"retry_after": 15
}
```
You should retry the request after the timeframe specified in the `retry_after` field. If the `retry_after` field is `0`, you should retry the request after a short delay.
See [the unavailable resources section](/topics/rate-limits#unavailable-resources) for more information.
###### JSON Params
| Field | Type | Description |
| ---------- | ---------------------------------------------------------------------- | ---------------------------------------------------------------------------- |
| limit? | integer | Max number of members to return (1-1000, default 25) |
| sort? | integer | The [sorting algorithm](#member-sort-type) to use (default `JOINED_AT_DESC`) |
| or_query? | [member filter](#member-filter-structure) object | The filter criteria to match against members using OR logic |
| and_query? | [member filter](#member-filter-structure) object | The filter criteria to match against members using AND logic |
| before? | [member pagination filter](#member-pagination-filter-structure) object | Get members before this member |
| after? | [member pagination filter](#member-pagination-filter-structure) object | Get members after this member |
###### Member Sort Type
| Value | Name | Description |
| ----- | -------------- | ----------------------------------------------------------- |
| 1 | JOINED_AT_DESC | Sort by when the user joined the guild descending (default) |
| 2 | JOINED_AT_ASC | Sort by when the user joined the guild ascending |
| 3 | USER_ID_DESC | Sort by when the user joined Discord descending |
| 4 | USER_ID_ASC | Sort by when the user joined Discord ascending |
###### Member Filter Structure
| Field | Type | Description | Queries |
| ------------------- | -------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------- | ----------------------- |
| user_id? | [query](#query-structure) object (snowflake) | Query to match member IDs against | `or_query`, `range` |
| usernames? | [query](#query-structure) object (string) | Query to match display name(s), username(s), and nickname(s) against | `or_query` |
| role_ids? | [query](#query-structure) object (snowflake) | IDs of roles to match members against | `or_query`, `and_query` |
| guild_joined_at? | [query](#query-structure) object (integer) | Unix timestamp (in milliseconds) of when the user joined the guild | `range` |
| safety_signals? | [safety signals](#safety-signals-structure) object | Safety signals to match members against | |
| is_pending? | boolean | Whether the member has not yet passed the guild's [member verification](#member-verification-object) requirements | `true`, `false` |
| did_rejoin? | boolean | Whether the member left and rejoined the guild | `true`, `false` |
| join_source_type? | [query](#query-structure) object (integer) | [How the user joined the guild](#join-source-type) | `or_query` |
| source_invite_code? | [query](#query-structure) object (string) | The invite code or vanity used to join the guild | `or_query` |
###### Safety Signals Structure
| Field | Type | Description | Queries |
| ----------------------------- | ------------------------------------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------- |
| unusual_dm_activity_until? | [query](#query-structure) object (integer) | Unix timestamp (in milliseconds) of when the member's unusual DM activity flag will expire | `range` |
| communication_disabled_until? | [query](#query-structure) object (integer) | Unix timestamp (in milliseconds) of when the member's [timeout](https://support.discord.com/hc/en-us/articles/4413305239191-Time-Out-FAQ) will expire | `range` |
| unusual_account_activity? | boolean | Whether the user has the [`SPAMMER` flag](/resources/user#user-flags) | `true`, `false` |
| automod_quarantined_username? | boolean | Whether the member has been indefinitely quarantined by [an AutoMod Rule](/resources/auto-moderation#automod-rule-object) for their username, display name, or nickname | `true`, `false` |
###### Query Structure
| Field | Type | Description |
| ---------- | -------------------------------------------- | ---------------------------------------------------------------------- |
| or_query? | array[snowflake \| string \| integer] | The values to match against using OR logic (1-100 characters, max 10) |
| and_query? | array[snowflake \| string \| integer] | The values to match against using AND logic (1-100 characters, max 10) |
| range? | [range query](#range-query-structure) object | The range of values to match against |
###### Range Query Structure
| Field | Type | Description |
| ----- | -------------------- | ------------------------------------ |
| gte? | snowflake \| integer | Inclusive lower bound value to match |
| lte? | snowflake \| integer | Inclusive upper bound value to match |
###### Member Pagination Filter Structure
| Field | Type | Description |
| --------------- | --------- | ----------------------------------------------------------------------------------- |
| user_id | snowflake | The ID of the user to paginate past |
| guild_joined_at | integer | Unix timestamp (in milliseconds) of when the user to paginate past joined the guild |
###### Response Body
| Field | Type | Description |
| ------------------ | ---------------------------------------------------------------------------- | --------------------------------- |
| guild_id | snowflake | The ID of the guild searched |
| members | array[[supplemental guild member](#supplemental-guild-member-object) object] | The resulting members |
| page_result_count | integer | The number of results returned |
| total_result_count | integer | The total number of results found |
List Guild Members Supplemental
Returns a list of [supplemental guild member](#supplemental-guild-member-object) objects including join source information for the given user IDs. Requires the `MANAGE_GUILD` permission.
###### JSON Params
| Field | Type | Description |
| -------- | ---------------- | ------------------------------------------------------------------------- |
| user_ids | array[snowflake] | The user IDs to fetch supplemental guild member information for (max 200) |
List Guild Members With Unusual DM Activity
Returns a list of [guild member unusual DM activity](#guild-member-unusual-dm-activity-structure) objects representing the members that have ever had unusual DM activity. User must be a member of the guild.
###### Query String Params
| Field | Type | Description |
| ------ | --------- | ------------------------------------------------------- |
| limit? | integer | Max number of members to return (max 1000, default 100) |
| after? | snowflake | Get members after this member ID |
###### Guild Member Unusual DM Activity Structure
| Field | Type | Description |
| ----------------------------- | ----------------- | ---------------------------------------------------- |
| user_id | snowflake | The ID of the user with unusual DM activity |
| guild_id | snowflake | The ID of the guild the user is in |
| unusual_dm_activity_until ^1^ | ISO8601 timestamp | When the user's unusual DM activity flag will expire |
^1^ If the value is a time in the past, the flag has expired.
###### Example Guild Member Unusual DM Activity
```json
{
"user_id": "934487154330066945",
"guild_id": "81384788765712384",
"unusual_dm_activity_until": "2024-01-15T06:10:37.288219+00:00"
}
```
Get Current Guild Member
Returns the private [guild member](#guild-member-object) object for the current user in the specified guild.
Get Guild Member
Returns a [guild member](#guild-member-object) object for the specified user.
Join Guild
Adds the current user to the guild. The guild must be discoverable. If the user is not a member of the guild, returns a [guild](#guild-object) object with the extra fields below. Otherwise, returns a 204 empty response.
May fire a [Guild Create](/gateway/gateway-events#guild-create), [Guild Member Add](/gateway/gateway-events#guild-member-add), and/or [Guild Join Request Create](/gateway/gateway-events#guild-join-request-create) Gateway event.
For guilds with [member verification](#member-verification-object) enabled, this endpoint will default to adding new members as `pending` in the [guild member](#guild-member-object) object. Members that are `pending` will have to complete member verification before they become full members that can talk.
For guilds with [previewing disabled](#guild-previewing), the return type will instead be a partial [guild](#guild-object) object with the extra fields below.
###### Query String Params
| Field | Type | Description |
| ----------------------- | ------- | --------------------------------------------------------------------------------------------------------------------- |
| lurker? ^1^ | boolean | Whether the user will lurk the guild (default false) |
| session_id? | string | The session ID to lurk with, required for lurking |
| location? | string | The analytics location the request initiated from |
| recommendation_load_id? | string | The unique identifier for the current guild discovery recommendations (client-generated UUID as a hexadecimal string) |
^1^ Lurking a guild allows the user to receive Gateway events for the guild without being a full member for the lifetime of the Gateway session. This is useful for previewing the guild before joining. Lurking requires the [`PREVIEW_ENABLED` guild feature](#guild-features).
###### Response Body Extra Fields
| Field | Type | Description |
| ----------------------- | ----------------------------------------------- | ---------------------------------------------------------------------------------------------------- |
| show_verification_form? | boolean | Whether the user should be shown the guild's [member verification](#member-verification-object) form |
| welcome_screen? | [welcome screen](#welcome-screen-object) object | The guild's welcome screen, shown to new members when joining the guild |
Add Guild Member
Adds a user to the guild, provided you have a valid OAuth2 access token for the user with the `guilds.join` scope. Returns the joined [guild member](#guild-member-object) object or a 204 empty response (if the user is already a member of the guild) on success. May fire a [Guild Member Add](/gateway/gateway-events#guild-member-add) and/or [Guild Join Request Create](/gateway/gateway-events#guild-join-request-create) Gateway event.
For guilds with [member verification](#member-verification-object) enabled, this endpoint will default to adding new members as `pending` in the [guild member](#guild-member-object) object. Members that are `pending` will have to complete member verification before they become full members that can talk.
Note that this endpoint ignores whether [guild previewing](#guild-previewing) is enabled and will always join the user as a member.
This endpoint is not usable by user accounts. The Authorization header must be a bot token (belonging to the same application used for authorization), and the bot must be a member of the guild with the `CREATE_INSTANT_INVITE` permission.
###### JSON Params
| Field | Type | Description | Permission |
| ------------ | ---------------- | ------------------------------------------------------------------------------------------------------------------------ | --------------------------------------------------------------------------- |
| access_token | string | An OAuth2 access token granted with the `guilds.join` to the bot's application for the user you want to add to the guild | `CREATE_INSTANT_INVITE` |
| nick? | ?string | The guild-specific nickname of the member (1-32 characters) | `MANAGE_NICKNAMES` |
| roles? | array[snowflake] | The role IDs assigned to this member | `MANAGE_ROLES` |
| mute? | boolean | Whether the member is muted in voice channels | `MUTE_MEMBERS` |
| deaf? | boolean | Whether the user is deafened in voice channels | `DEAFEN_MEMBERS` |
| flags? ^1^ | integer | The [member's flags](#guild-member-flags) (only `BYPASSES_VERIFICATION` can be set) | `MANAGE_GUILD` or (`MODERATE_MEMBERS` and `KICK_MEMBERS` and `BAN_MEMBERS`) |
^1^ For guilds with member verification enabled, assigning the [`BYPASSES_VERIFICATION` guild member flag](#guild-member-flags) will add the user as a full member (`pending` is false in the [member object](#guild-member-object)).
Modify Guild Member
Modifies attributes of a guild member. User must be a member of the guild. Returns the updated [guild member](#guild-member-object) object on success. Fires a [Guild Member Update](/gateway/gateway-events#guild-member-update) Gateway event.
###### JSON Params
| Field | Type | Description | Permission |
| --------------------------------- | ------------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------- |
| nick? | ?string | The guild-specific nickname of the member (1-32 characters) | `MANAGE_NICKNAMES` |
| roles? | array[snowflake] | The role IDs assigned to this member | `MANAGE_ROLES` |
| mute? ^1^ | boolean | Whether the member is muted in voice channels | `MUTE_MEMBERS` |
| deaf? ^1^ | boolean | Whether the user is deafened in voice channels | `DEAFEN_MEMBERS` |
| channel_id? ^1^ | snowflake | The ID of the voice channel the user is connected to | `MOVE_MEMBERS` |
| communication_disabled_until? ^2^ | ?ISO8601 timestamp | When the user's [timeout](https://support.discord.com/hc/en-us/articles/4413305239191-Time-Out-FAQ) will expire and they will be able to communicate in the guild again (up to 28 days in the future) | `MODERATE_MEMBERS` |
| flags? | integer | The [member's flags](#guild-member-flags) (only `BYPASSES_VERIFICATION` can be set) | `MANAGE_GUILD` or (`MODERATE_MEMBERS` and `KICK_MEMBERS` and `BAN_MEMBERS`) |
^1^ Requires the member to be connected to voice. When moving members to channels, the current user _must_ have permissions to both connect to the channel and have the `MOVE_MEMBERS` permission. If the `channel_id` is set to `null`, this will force the target user to be disconnected from voice.
^2^ Guild administrators cannot be timed out. If a member is timed out and becomes an administrator before their timeout expires, the timeout will no longer have an effect.
Modify Current Guild Member
Modifies the current user's member in the guild. Returns the updated private [guild member](#guild-member-object) object on success. Fires a [Guild Member Update](/gateway/gateway-events#guild-member-update) Gateway event.
###### JSON Params
| Field | Type | Description | Permission |
| ------------------------- | ----------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------- |
| nick? | ?string | The guild-specific nickname of the member (1-32 characters) | `CHANGE_NICKNAME` |
| avatar? | ?[image data](/reference#cdn-data) | The member's guild avatar; can only be changed for premium users and bots |
| avatar_description? | ?string | The description of the new guild avatar, usually in the format "\{filename\}, added \{date\}" (max 1024 characters) |
| avatar_id? | string | The ID of the recent avatar to use |
| avatar_decoration_sku_id? | ?snowflake | The SKU ID of the member's guild avatar decoration; can only be changed for premium users |
| collectibles? | ?[collectibles](#collectibles-structure) object | The member's equipped collectibles; can only be changed for premium users |
| display_name_font_id? | ?integer | The [display name font](/resources/user#display-name-font) to use; can only be changed for premium users and bots |
| display_name_effect_id? | ?integer | The [display name effect](/resources/user#display-name-effect) to use; can only be changed for premium users and bots |
| display_name_colors? | ?array[integer] | The display name colors to use encoded as an array of integers representing hexadecimal color codes (max 2); can only be changed for premium users and bots |
| pronouns? | ?string | The member's guild pronouns (max 40 characters) |
| bio? | ?string | The member's guild bio (max 190 characters); can only be changed for premium users and bots |
| banner? | ?[image data](/reference#cdn-data) | The member's guild banner; can only be changed for premium users and bots |
###### Collectibles Structure
| Field | Type | Description |
| ---------- | --------------------------------------------------- | ----------------------------------------------------------------------------------------------------- |
| nameplate? | ?[nameplate data](#nameplate-data-structure) object | The member's [nameplate](https://support.discord.com/hc/en-us/articles/30408457944215-Nameplates-FAQ) |
###### Nameplate Data Structure
| Field | Type | Description |
| ------- | --------- | ----------------------------- |
| sku_id? | snowflake | The ID of the nameplate's SKU |
Modify Current Guild Member Nick
See [Modify Current Guild Member](#modify-current-guild-member) for more information.
This endpoint is deprecated. It is replaced by [Modify Current Guild Member](#modify-current-guild-member).
Modify Guild Member Profile
Modifies the current user's profile in the guild. Returns a [profile metadata](/resources/user#profile-metadata-object) object on success. Fires a [Guild Member Update](/gateway/gateway-events#guild-member-update) Gateway event.
###### JSON Params
| Field | Type | Description |
| ------------------------------------------------ | ---------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------- |
| pronouns? | ?string | The member's guild pronouns (max 40 characters) |
| bio? | ?string | The member's guild bio (max 190 characters); can only be changed for premium users |
| banner? | ?[image data](/reference#cdn-data) | The member's guild banner; can only be changed for premium users |
| accent_color? | ?integer | The member's guild accent color as a hex integer; can only be changed for premium users |
| theme_colors? | ?array[integer, integer] | The member's two guild theme colors encoded as an array of integers representing hexadecimal color codes; can only be changed for premium users |
| popout_animation_particle_type? **(deprecated)** | ?snowflake | The member's guild profile popout animation particle type; can only be changed for premium users |
| emoji_id? **(deprecated)** | ?snowflake | The member's guild profile emoji ID; can only be changed for premium users |
| profile_effect_id? | ?snowflake | The member's guild profile effect ID; can only be changed for premium users |
Add Guild Member Role
Adds a role to a [guild member](#guild-member-object). Requires the `MANAGE_ROLES` permission. Returns a 204 empty response on success. Fires a [Guild Member Update](/gateway/gateway-events#guild-member-update) Gateway event.
Remove Guild Member Role
Removes a role from a [guild member](#guild-member-object). Requires the `MANAGE_ROLES` permission. Returns a 204 empty response on success. Fires a [Guild Member Update](/gateway/gateway-events#guild-member-update) Gateway event.
Remove Guild Member
Removes a [member](#guild-member-object) from a guild. Requires the `KICK_MEMBERS` permission. Returns a 204 empty response on success. Fires a [Guild Member Remove](/gateway/gateway-events#guild-member-remove) Gateway event.
Acknowledge DM Settings Upsell Modal
Adds the `DM_SETTINGS_UPSELL_ACKNOWLEDGED` [member flag](#guild-member-flags) to the current user. User must be a member of the guild. Returns a 204 empty response on success. Fires a [Guild Member Update](/gateway/gateway-events#guild-member-update) Gateway event.
List Guild Bans
Returns a list of [ban](#ban-object) objects for the guild. Requires the `BAN_MEMBERS` permission.
###### Query String Params
| Field | Type | Description |
| ----------- | --------- | ---------------------------------------------------------- |
| before? ^1^ | snowflake | Get bans before this user ID |
| after? ^1^ | snowflake | Get bans after this user ID |
| limit? ^2^ | number | Max number of bans to return (1-1000, default all or 1000) |
^1^ Bans will always be returned in ascending order by user ID.
^2^ User accounts are required to specify a `limit`.
Search Guild Bans
Returns a list of [ban](#ban-object) objects whose username or display name contains a provided string. Requires the `BAN_MEMBERS` permission.
###### Query String Params
| Field | Type | Description |
| --------- | ---------------- | ------------------------------------------------------------------------ |
| query? | string | Query to match username(s) and display name(s) against (1-32 characters) |
| user_ids? | array[snowflake] | The user IDs to match against (max 10) |
| limit? | integer | Max number of members to return (1-10, default 10) |
Get Guild Ban
Returns a [ban](#ban-object) object for the given user. Requires the `BAN_MEMBERS` permission.
Create Guild Ban
Creates a guild ban and optionally deletes previous messages sent by the banned user. Requires the `BAN_MEMBERS` permission. Returns a 204 empty response on success. Fires a [Guild Ban Add](/gateway/gateway-events#guild-ban-add) and optionally a [Guild Member Remove](/gateway/gateway-events#guild-member-remove) Gateway event.
###### JSON Params
| Field | Type | Description |
| ------------------------------------- | ------- | -------------------------------------------------------------- |
| delete_message_days? **(deprecated)** | integer | Number of days to delete messages for (0-7, default 0) |
| delete_message_seconds? | integer | Number of seconds to delete messages for (0-604800, default 0) |
Bulk Guild Ban
Create multiple guild bans and optionally delete previous messages sent by the banned users. Requires both the `BAN_MEMBERS` and `MANAGE_GUILD` permissions. Fires multiple [Guild Ban Add](/gateway/gateway-events#guild-ban-add) and optionally [Guild Member Remove](/gateway/gateway-events#guild-member-remove) Gateway events.
This endpoint is deprecated. It is replaced by [Bulk Guild Ban V2](#bulk-guild-ban-v2).
###### JSON Params
| Field | Type | Description |
| ----------------------- | ---------------- | -------------------------------------------------------------- |
| user_ids | array[snowflake] | The user IDs to ban (max 200) |
| delete_message_seconds? | integer | Number of seconds to delete messages for (0-604800, default 0) |
###### Response Body
| Field | Type | Description |
| ---------------- | ---------------- | ------------------------------------------ |
| banned_users | array[snowflake] | The user IDs that were successfully banned |
| failed_users ^1^ | array[snowflake] | The user IDs that were not banned |
^1^ A ban will fail if the user is already banned, the user has a higher role than the current user, the user is the owner of the guild, or the user is the current user. If a bulk ban has no successful bans, the request will fail with a [`500000` JSON error code](/topics/errors#json-error-codes).
Bulk Guild Ban V2
Create multiple guild bans and optionally delete previous messages sent by the banned users. Requires both the `BAN_MEMBERS` and `MANAGE_GUILD` permissions. Returns a 204 empty response on success. Fires a [Guild Bulk Ban Update](/gateway/gateway-events#guild-bulk-ban-update) Gateway event for the current user. Fires multiple [Guild Ban Add](/gateway/gateway-events#guild-ban-add) and optionally [Guild Member Remove](/gateway/gateway-events#guild-member-remove) Gateway events.
###### JSON Params
| Field | Type | Description |
| ----------------------- | ---------------- | -------------------------------------------------------------- |
| user_ids ^1^ | array[snowflake] | The user IDs to ban (max 200) |
| delete_message_seconds? | integer | Number of seconds to delete messages for (0-604800, default 0) |
^1^ If the only user ID provided belongs to the current user, the request will fail with a [`500000` JSON error code](/topics/errors#json-error-codes).
Delete Guild Ban
Removes the ban for a user. Requires the `BAN_MEMBERS` permission. Returns a 204 empty response on success. Fires a [Guild Ban Remove](/gateway/gateway-events#guild-ban-remove) Gateway event.
List Guild Roles
Returns a list of [role](#role-object) objects for the guild. User must be a member of the guild.
Get Guild Role
Returns a [role](#role-object) object for the given role. User must be a member of the guild.
Get Guild Role Member Counts
Returns a mapping of role IDs to their respective member counts. User must be a member of the guild.
###### Example Response
```json
{
"1040221495437299782": 2,
"1040221495437299783": 1,
"1040221495437299784": 0
}
```
List Guild Role Members
Returns a list of member IDs that have the specified [role](#role-object), up to a maximum of 100. User must be a member of the guild.
This endpoint does not return results for the default (@everyone) role.
###### Example Response
```json
["852892297661906993", "907489667895676928"]
```
Add Guild Role Members
Adds multiple [guild members](#guild-member-object) to a [role](#role-object). Requires the `MANAGE_ROLES` permission. Returns a mapping of member IDs to [guild member](#guild-member-object) objects. Fires multiple [Guild Member Update](/gateway/gateway-events#guild-member-update) Gateway events.
###### JSON Params
| Field | Type | Description |
| ---------- | ---------------- | --------------------------------------------- |
| member_ids | array[snowflake] | The member IDs to assign the role to (max 30) |
###### Example Response
```json
{
"863406480111566858": {
"avatar": null,
"banner": null,
"communication_disabled_until": null,
"unusual_dm_activity_until": null,
"flags": 0,
"joined_at": "2022-10-11T12:31:03.882000+00:00",
"nick": ":~]",
"pending": false,
"premium_since": null,
"roles": ["1040221495437299782"],
"user": {
"id": "863406480111566858",
"username": "leaduck",
"global_name": "LeaDuck",
"avatar": "bb450561133bac3da5c7e201db40af6c",
"discriminator": "0",
"public_flags": 256,
"avatar_decoration_data": null,
"primary_guild": null
},
"mute": false,
"deaf": false
}
}
```
List Guild Role Connections Configurations
Returns a list of [role connection rule](#role-connection-rule-structure) objects representing the role connections for the guild. User must be a member of the guild.
###### Role Connection Rule Structure
| Field | Type | Description |
| ------------ | ------------------------------------------------------------------------------------------------ | ---------------------------------------- |
| role_id | snowflake | The ID of the linkable role |
| rules | [role connection configuration](#role-connection-configuration-object) object | The requirements for the linkable role |
| applications | map[snowflake, [integration application](/resources/integration#integration-application-object)] | The applications referenced in the rules |
Get Guild Role Connection Configuration
Returns a [role connection configuration](#role-connection-configuration-object) object representing the role connection for the given role. Requires the `MANAGE_ROLES` permission.
Modify Guild Role Connection Configuration
Replaces the [role connection configuration](#role-connection-configuration-object) for the given role. Requires the `MANAGE_ROLES` permission. Accepts a [role connection configuration](#role-connection-configuration-object) object. Returns the updated [role connection configuration](#role-connection-configuration-object) object on success.
Get Guild Role Connection Eligibility
Returns a [role connection configuration](#role-connection-configuration-object) object with extra fields representing the user's eligibility to link the given role. User must be a member of the guild.
Assign Guild Role Connection
Assigns an eligibile role connection to the current user. Returns a 204 empty response on success. Fires a [Guild Member Update](/gateway/gateway-events#guild-member-update) Gateway event.
Unassign Guild Role Connection
Unassigns a role connection from the current user. Returns a 204 empty response on success. Fires a [Guild Member Update](/gateway/gateway-events#guild-member-update) Gateway event.
Create Guild Role
Creates a new role for the guild. Requires the `MANAGE_ROLES` permission. Returns the new [role](#role-object) object on success. Fires a [Guild Role Create](/gateway/gateway-events#guild-role-create) Gateway event.
Guilds may have a maximum of 250 roles.
###### JSON Params
| Field | Type | Description |
| --------------------------- | --------------------------------------------- | -------------------------------------------------------------------------------------- |
| name? | ?string | The name of the role (max 100 characters, default "new role") |
| description? | ?string | The description for the role (max 90 characters) |
| color? **(deprecated)** ^1^ | ?integer | Integer representation of a hexadecimal color code for the role |
| colors? ^1^ ^2^ | ?[role colors](#role-colors-structure) object | The colors of the role encoded as an integer representation of hexadecimal color codes |
| hoist? | ?boolean | Whether this role is pinned in the user listing (default false) |
| icon? | ?[image data](/reference#cdn-data) | The role's icon |
| unicode_emoji? | ?string | The role's unicode emoji |
| permissions? | ?string | The permission bitwise value for the role (default @everyone permissions) |
| mentionable? | ?boolean | Whether this role is mentionable (default false) |
^1^ If both `color` and `colors` are provided, the `color` field will be ignored.
^2^ Requires the [`ENHANCED_ROLE_COLORS` guild feature](#guild-features).
Modify Guild Role Positions
Modifies the positions of a set of [role](#role-object) objects for the guild. Requires the `MANAGE_ROLES` permission. Returns a list of all of the guild's [role](#role-object) objects on success. Fires multiple [Guild Role Update](/gateway/gateway-events#guild-role-update) Gateway events.
This endpoint takes a JSON array of parameters in the following format:
###### JSON Params
| Field | Type | Description |
| --------- | --------- | ---------------------------- |
| id | snowflake | The ID of the role |
| position? | ?integer | Sorting position of the role |
Modify Guild Role
Modifies a guild role. Requires the `MANAGE_ROLES` permission. Returns the updated [role](#role-object) on success. Fires a [Guild Role Update](/gateway/gateway-events#guild-role-update) Gateway event.
###### JSON Params
| Field | Type | Description |
| --------------------------- | --------------------------------------------- | -------------------------------------------------------------------------------------- |
| name? | ?string | The name of the role (max 100 characters, default "new role" if `null`) |
| description? | ?string | The description for the role (max 90 characters) |
| color? **(deprecated)** ^1^ | ?integer | Integer representation of a hexadecimal color code for the role |
| colors? ^1^ ^2^ | ?[role colors](#role-colors-structure) object | The colors of the role encoded as an integer representation of hexadecimal color codes |
| hoist? | ?boolean | Whether this role is pinned in the user listing |
| icon? | ?[image data](/reference#cdn-data) | The role's icon |
| unicode_emoji? | ?string | The role's unicode emoji |
| permissions? | ?string | The permission bitwise value for the role (default @everyone permissions if `null`) |
| mentionable? | ?boolean | Whether this role is mentionable |
^1^ If both `color` and `colors` are provided, the `color` field will be ignored.
^2^ Requires the [`ENHANCED_ROLE_COLORS` guild feature](#guild-features).
Delete Guild Role
Deletes a guild role. Requires the `MANAGE_ROLES` permission. Returns a 204 empty response on success. Fires a [Guild Role Delete](/gateway/gateway-events#guild-role-delete) Gateway event.
Get Guild Prune
Returns the number of members that would be removed in a prune operation. If the [`PRUNE_REQUIRES_ADMIN` guild feature](#guild-features) has been enabled, then the `ADMINISTRATOR` permission is required. Otherwise, requires both the `MANAGE_GUILD` and `KICK_MEMBERS` permissions.
By default, prune will not remove users with roles. You can optionally include specific roles in your prune by providing the `include_roles` parameter. Any inactive user that has a subset of the provided role(s) will be counted in the prune and users with additional roles will not.
###### Query String Params
| Field | Type | Description |
| -------------- | ---------------- | ------------------------------------------------------------ |
| days? | integer | Number of inactive days to count prune for (1-30, default 7) |
| include_roles? | array[snowflake] | Additional roles to include |
###### Response Body
| Field | Type | Description |
| ------ | ------- | --------------------------------------------------------------------------------------------- |
| pruned | integer | The number of members that would be removed in a prune operation with the provided parameters |
###### Example Response
```json
{ "pruned": 42 }
```
Prune Guild
Begins a prune operation. If the [`PRUNE_REQUIRES_ADMIN` guild feature](#guild-features) has been enabled, then the `ADMINISTRATOR` permission is required. Otherwise, requires both the `MANAGE_GUILD` and `KICK_MEMBERS` permissions. For large guilds, it's recommended to set the `compute_prune_count` option to `false`, allowing the request to return before all members are pruned. Fires multiple [Guild Member Remove](/gateway/gateway-events#guild-member-remove) Gateway events.
By default, prune will not remove users with roles. You can optionally include specific roles in your prune by providing the `include_roles` parameter. Any inactive user that has a subset of the provided role(s) will be included in the prune and users with additional roles will not.
###### JSON Params
| Field | Type | Description |
| -------------------- | ---------------- | -------------------------------------------------------------------------- |
| days? | integer | Number of inactive days to prune for (1-30, default 7) |
| compute_prune_count? | boolean | Whether to wait for the prune to complete before responding (default true) |
| include_roles? | array[snowflake] | Additional roles to include |
###### Response Body
| Field | Type | Description |
| ------ | -------- | ------------------------------------------------------------------------------------------------------------------- |
| pruned | ?integer | The number of members that were removed in the prune operation with the provided parameters; `null` if not computed |
###### Example Response
```json
{ "pruned": null }
```
Get Guild Widget Settings
Returns a [guild widget settings](#guild-widget-settings-structure) object for the guild. Requires the `MANAGE_GUILD` permission.
Modify Guild Widget
Modifies the widget settings for the guild. Requires the `MANAGE_GUILD` permission. Returns the updated [guild widget settings](#guild-widget-settings-structure) object on success.
###### JSON Params
| Field | Type | Description |
| ----------- | ---------- | ----------------------------------------------------------------- |
| enabled? | boolean | Whether the widget is enabled |
| channel_id? | ?snowflake | The channel ID that the widget will generate an invite to, if any |
Get Guild Widget
Returns a [guild widget](#guild-widget-object) object for the given guild ID. The guild must have the widget enabled. May fire an [Invite Create](/gateway/gateway-events#invite-create) Gateway event.
If a widget channel is set and a usable invite for it does not already exist, fetching the widget will create one. Subsequent calls will attempt to reuse the generated invite.
Get Guild Widget Image
Returns a widget image PNG for the given guild ID. The guild must have the widget enabled.
###### Query String Params
| Field | Type | Description |
| ------ | ------ | ------------------------------------------------------------------------------------- |
| style? | string | [Style of widget image](#guild-widget-image-style-option) returned (default `shield`) |
###### Guild Widget Image Style Option
| Value | Description | Example |
| ------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------ |
| shield | Shield style widget with Discord icon and online count | [Example](https://discord.com/api/guilds/81384788765712384/widget.png?style=shield) |
| banner1 | Large image with guild icon, name and online count; "POWERED BY DISCORD" as the footer of the widget | [Example](https://discord.com/api/guilds/81384788765712384/widget.png?style=banner1) |
| banner2 | Smaller widget style with guild icon, name and online count; split on the right with Discord logo | [Example](https://discord.com/api/guilds/81384788765712384/widget.png?style=banner2) |
| banner3 | Large image with guild icon, name and online count; in the footer, Discord logo on the left and "Chat Now" on the right | [Example](https://discord.com/api/guilds/81384788765712384/widget.png?style=banner3) |
| banner4 | Large Discord logo at the top of the widget; guild icon, name and online count in the middle portion of the widget and a "JOIN MY SERVER" button at the bottom | [Example](https://discord.com/api/guilds/81384788765712384/widget.png?style=banner4) |
Get Guild Vanity Invite
Returns the vanity invite for the guild. The guild must have the `VANITY_URL` or `GUILD_WEB_PAGE_VANITY_URL` feature. Requires the `MANAGE_GUILD` permission.
###### Response Body
| Field | Type | Description |
| ----- | ------- | --------------------------------------------- |
| code | ?string | The vanity invite code for the guild |
| uses | integer | The number of times this invite has been used |
###### Example Response
```json
{
"code": "abc",
"uses": 12
}
```
Modify Guild Vanity Invite
Modifies the vanity invite for the guild. The guild must have the `VANITY_URL` or `GUILD_WEB_PAGE_VANITY_URL` feature. Guilds without the `VANITY_URL` feature can only clear their vanity invite. Requires both the `MANAGE_GUILD` and `CREATE_INSTANT_INVITE` permissions. Fires a [Guild Update](/gateway/gateway-events#guild-update) Gateway event.
###### JSON Params
| Field | Type | Description |
| ----- | ------- | ---------------------------------------------------------------------------- |
| code | ?string | The vanity invite code for the guild (2-25 characters, alphanumeric and `-`) |
###### Response Body
| Field | Type | Description |
| ----- | ------- | ----------------------------------------------------- |
| code | ?string | The vanity invite code for the guild |
| uses | integer | The number of times this invite has been used (now 0) |
Get Guild Member Verification
Returns the [member verification](#member-verification-object) object for the guild if one is set. If the user is not in the guild, the guild must be discoverable or have [guild previewing](#guild-previewing) disabled.
###### Query String Params
| Field | Type | Description |
| --------------- | ------- | ------------------------------------------------------------------- |
| with_guild? ^1^ | boolean | Whether to include the guild object in the response (default false) |
| invite_code? | string | The invite code the verification is fetched from |
^1^ Requires that the user is not a member of the guild, and that the guild is not full.
Modify Guild Member Verification
Modifies the member verification for the guild. Requires the `MANAGE_GUILD` permission. Returns the updated [member verification](#member-verification-object) object. May fire a [Guild Update](/gateway/gateway-events#guild-update) Gateway event.
###### JSON Params
| Field | Type | Description |
| ------------ | ----------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| enabled? | boolean | Whether the member verification gate is enabled |
| form_fields? | array[[member verification form field](#member-verification-form-field-structure) object] | Questions for applicants to answer (max 5) |
| description? | ?string | A description of what the guild is about; this can be different than the guild's description (max 300 characters) |
| bulk_action? | string | When disabling the verification gate, [what to do](#guild-join-request-status) with pending applications (only `APPROVED` and `REJECTED` can be used, default `APPROVED`) |
List Guild Join Requests
Returns a list of join requests for the guild for manual approval. Requires the `KICK_MEMBERS` permission.
###### Query String Params
| Field | Type | Description |
| ----------- | --------- | ------------------------------------------------------------------------------------------------ |
| status? ^1^ | string | The [status of the join requests](#guild-join-request-status) to filter by (default `SUBMITTED`) |
| limit? | integer | Max number of join requests to return (1-100, default 100) |
| before? | snowflake | Get join requests before this request ID |
| after? | snowflake | Get join requests after this request ID |
^1^ Requests of status `STARTED` cannot be queried.
###### Response Body
| Field | Type | Description |
| ------------------- | ------------------------------------------------------- | ------------------------------------------------------ |
| guild_join_requests | array[[guild join request](#guild-join-request-object)] | The join requests for the guild |
| total? | integer | The total number of join requests that match the query |
Get Guild Join Request
Returns a [guild join request](#guild-join-request-object) object for the given request ID. Requires the `KICK_MEMBERS` permission if the request is not for the current user.
Get Current User Guild Join Request
Returns a partial [guild join request](#guild-join-request-object) object representing the current user's active join request for the guild.
Get Guild Join Request Cooldown
Returns the remaining time until the current user can submit another join request for the guild.
###### Response Body
| Field | Type | Description |
| -------- | ------- | ------------------------------------------------------------------------------------------- |
| cooldown | integer | How long (in seconds) the user has to wait until the current user can submit a join request |
Create Guild Join Request
Submits a request to join a guild. Returns a partial [guild join request](#guild-join-request-object) object on success. Fires a [Guild Join Request Create](/gateway/gateway-events#guild-join-request-create) or [Guild Join Request Update](/gateway/gateway-events#guild-join-request-update) Gateway event.
###### JSON Params
| Field | Type | Description |
| --------------- | ----------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------- |
| form_fields ^1^ | array[[member verification form field](#member-verification-form-field-structure) object] | The answered member verification questions |
| version | ?ISO8601 timestamp | When the member verification was last modified, same as [`version` in the member verification object](#member-verification-object) |
^1^ The `form_fields` array must contain all fields from the guild's [member verification](#member-verification-object) object, with a populated `response` field for each `required` field.
Reset Guild Join Request
Resets the current user's join request for the guild. Returns a partial [guild join request](#guild-join-request-object) object on success. Fires a [Guild Join Request Delete](/gateway/gateway-events#guild-join-request-delete) and [Guild Join Request Create](/gateway/gateway-events#guild-join-request-create) Gateway event.
Acknowledge Guild Join Request
Acknowledges an approved join request for the current user. Returns a 204 empty response on success. Fires a [Guild Join Request Update](/gateway/gateway-events#guild-join-request-update) Gateway event.
Users can only acknowledge their own join requests (`{guild_join_request.id}` may be `@me` or the user's ID), and only if the request is approved and is not already acknowledged (has a `last_seen` of `null`).
Upon acknowledgement, the join request is no longer considered active and will not be returned in the [Ready event](/gateway/gateway-events#ready).
Delete Guild Join Request
If the guild has [previewing disabled](#guild-previewing), deletes the current user's join request. Else, functions the same as [Reset Guild Join Request](#reset-guild-join-request). Returns a 204 empty response if deletion is successful or a partial [guild join request](#guild-join-request-object) object if the join request is reset. Fires a [Guild Join Request Delete](/gateway/gateway-events#guild-join-request-delete) and optionally a [Guild Join Request Create](/gateway/gateway-events#guild-join-request-create) Gateway event.
Create Guild Join Request Interview
Creates or returns an existing private interview channel for the join request. Requires the `KICK_MEMBERS` permission. Returns a [group DM channel](/resources/channel#channel-object) object on success. Fires a [Guild Join Request Update](/gateway/gateway-events#guild-join-request-update) and [Channel Create](/gateway/gateway-events#channel-create) Gateway event.
The created group DM channel will share the same ID as the join request and will be accessible by the join request user and the user who created the interview using this endpoint.
If a group DM channel already exists for the join request, the requestor will be added to it.
Action Guild Join Request
Accepts or denies a join request for the guild. Requires the `KICK_MEMBERS` permission. Returns a [guild join request](#guild-join-request-object) object on success. Fires a [Guild Join Request Update](/gateway/gateway-events#guild-join-request-update) and optionally a [Guild Member Add](/gateway/gateway-events#guild-member-add) or [Guild Member Remove](/gateway/gateway-events#guild-member-remove) Gateway event.
This endpoint was previously keyed by user ID, allowing a [user ID](/resources/user#user-object) to be used in place of the [guild join request ID](#guild-join-request-object) in the request path. This behavior is deprecated and should not be relied upon.
###### JSON Params
| Field | Type | Description |
| ----------------- | ------- | ------------------------------------------------------------------------------------------------------------------ |
| action | string | The [action to take](#guild-join-request-status) on the join requests (only `APPROVED` and `REJECTED` can be used) |
| rejection_reason? | ?string | The reason for rejecting the join request (max 160 characters) |
Action Guild Join Request by ID
Same as above, except this endpoint does not accept a [user ID](/resources/user#user-object) in place of the [guild join request ID](#guild-join-request-object).
Bulk Action Guild Join Requests
Accepts or denies all pending join requests for the guild. Requires the `KICK_MEMBERS` permission. Returns a 204 empty response on success. May fire multiple [Guild Join Request Update](/gateway/gateway-events#guild-join-request-update), [Guild Member Add](/gateway/gateway-events#guild-member-add), and [Guild Member Remove](/gateway/gateway-events#guild-member-remove) Gateway events.
###### JSON Params
| Field | Type | Description |
| ------ | ------ | ------------------------------------------------------------------------------------------------------------------ |
| action | string | The [action to take](#guild-join-request-status) on the join requests (only `APPROVED` and `REJECTED` can be used) |
List User Guild Join Requests
Returns a list of [guild join request](#guild-join-request-object) objects that the user has submitted to the guild.
Get Guild Welcome Screen
Returns the [welcome screen](#welcome-screen-object) object for the guild. Requires the `MANAGE_GUILD` permission if the welcome screen is not yet enabled, otherwise no permission is required.
Modify Guild Welcome Screen
Modifies the guild's welcome screen. Requires the `MANAGE_GUILD` permission. Returns the updated [welcome screen](#welcome-screen-object) object. May fire a [Guild Update](/gateway/gateway-events#guild-update) Gateway event.
###### JSON Params
| Field | Type | Description |
| ----------------- | -------------------------------------------------------------------------- | -------------------------------------------------------------------- |
| enabled? | ?boolean | Whether the welcome screen is enabled |
| description? | ?string | The welcome message shown in the welcome screen (max 140 characters) |
| welcome_channels? | ?array[[welcome screen channel](#welcome-screen-channel-structure) object] | The channels shown in the welcome screen (max 5) |
Get Guild Onboarding
Returns the [onboarding](#onboarding-object) object for the guild. Requires the `MANAGE_GUILD` permission if the feature is disabled, otherwise requires that the user is a member of the guild.
Modify Guild Onboarding
Modifies the onboarding configuration of the guild. Returns the updated [onboarding](#onboarding-object) object. Requires the `MANAGE_GUILD` permission. Fires a [Guild Update](/gateway/gateway-events#guild-update) Gateway event.
Onboarding enforces constraints when enabled. These constraints are that at least one default channel must allow sending messages to the default (@everyone) role. The `mode` field modifies what is considered when enforcing these constraints.
###### JSON Params
| Field | Type | Description |
| -------------------- | --------------------------------------------------------------- | ------------------------------------------------------------------ |
| prompts? | array[[onboarding prompt](#onboarding-prompt-structure) object] | The prompts shown during onboarding and in community customization |
| default_channel_ids? | array[snowflake] | The channel IDs that members get opted into automatically |
| enabled? | boolean | Whether onboarding is enabled in the guild |
| mode? | integer | The current [criteria mode](#onboarding-mode) for onboarding |
List Guild Onboarding Allowed Applications
Returns the applications that are allowed to be used as onboarding connections.
###### Response Body
| Field | Type | Description |
| --------------- | ---------------- | --------------------------- |
| application_ids | array[snowflake] | The allowed application IDs |
Create Guild Onboarding Responses
Creates the initial onboarding response for the current user in the guild. If responses are not empty, returns an [onboarding responses](#onboarding-responses-object) object on success. Otherwise, returns a 204 empty response. May fire a [Guild Member Update](/gateway/gateway-events#guild-member-update) Gateway event.
###### JSON Params
| Field | Type | Description |
| -------------------------- | ----------------------- | ------------------------------------------------------------------------------------------------------------------ |
| onboarding_responses? | array[snowflake] | The onboarding prompt option IDs the current user chose (max 750) |
| onboarding_prompts_seen? | map[snowflake, integer] | A mapping of prompt IDs to Unix timestamps (in milliseconds) of when the current user saw the prompt |
| onboarding_responses_seen? | map[snowflake, integer] | A mapping of prompt option IDs to Unix timestamps (in milliseconds) of when the current user saw the prompt option |
Modify Guild Onboarding Responses
Updates the onboarding response for the current user in the guild. If responses are not empty, returns an [onboarding responses](#onboarding-responses-object) object on success. Otherwise, returns a 204 empty response. May fire a [Guild Member Update](/gateway/gateway-events#guild-member-update) Gateway event.
###### JSON Params
| Field | Type | Description |
| -------------------------- | ----------------------- | ------------------------------------------------------------------------------------------------------------------ |
| onboarding_responses? | array[snowflake] | The onboarding prompt option IDs the current user chose (max 750) |
| onboarding_prompts_seen? | map[snowflake, integer] | A mapping of prompt IDs to Unix timestamps (in milliseconds) of when the current user saw the prompt |
| onboarding_responses_seen? | map[snowflake, integer] | A mapping of prompt option IDs to Unix timestamps (in milliseconds) of when the current user saw the prompt option |
Get Guild New Member Welcome
If it exists, returns the [new member welcome](#new-member-welcome-object) object for the guild. Otherwise, returns a 204 empty response. Requires the `MANAGE_GUILD` permission if the feature is disabled, otherwise no permission is required.
Modify Guild New Member Welcome
Modifies the guild's new member welcome configuration. Requires the `MANAGE_GUILD` permission. Returns the updated [new member welcome](#new-member-welcome-object) object. May fire a [Guild Update](/gateway/gateway-events#guild-update) Gateway event.
The new member welcome experience enforces constraints when enabled. These constraints are that there must be at least 3 new member actions, all referenced channels must be viewable by the default role,
and new member action channels with an [`action_type` of `CHAT`](#new-member-action-type) must allow sending messages to the default role.
###### JSON Params
| Field | Type | Description |
| ----------------------- | -------------------------------------------------------------------------- | ----------------------------------------------------------------- |
| enabled? | boolean | Whether the new member welcome experience is enabled |
| welcome_message? | [new member welcome message](#new-member-welcome-message-structure) object | Welcome message shown to new members of the guild |
| new_member_actions? ^1^ | array[partial [new member action](#new-member-action-structure) object] | Actions shown to new members of the guild (max 5) |
| resource_channels? ^2^ | array[partial [resource channel](#resource-channel-structure) object] | Read-only channels that provide resources for new members (max 7) |
^1^ Only the `channel_id`, `action_type`, and `name` fields are required. `icon` cannot be set.
^2^ Only the `channel_id` and `name` fields are required. `icon` cannot be set.
Modify Guild New Member Action
Modifies a new member action for the guild. Requires the `MANAGE_GUILD` permission. Returns the updated [new member action](#new-member-action-structure) object on success.
###### JSON Params
| Field | Type | Description |
| ----- | ---------------------------------- | -------------------------------------------- |
| icon? | ?[image data](/reference#cdn-data) | The new member action's icon (max 10000 KiB) |
Modify Guild Resource Channel
Modifies a resource channel for the guild. Requires the `MANAGE_GUILD` permission. Returns the updated [resource channel](#resource-channel-structure) object on success.
All parameters to this endpoint are optional and nullable. Omitting or setting a `null` value will set it to default.
###### JSON Params
| Field | Type | Description |
| ----- | ---------------------------------- | ------------------------------------------- |
| icon? | ?[image data](/reference#cdn-data) | The resource channel's icon (max 10000 KiB) |
Get Guild New Member Actions
If it exists, returns a [new member actions progress](#new-member-actions-progress-object) object for the user in the guild, representing the user's progress towards completing the new member actions. Otherwise, returns a 204 empty response.
Complete Guild New Member Action
Completes a new member action for the user in the guild. Returns the updated [new member actions progress](#new-member-actions-progress-object) object on success. May fire a [Guild Member Update](/gateway/gateway-events#guild-member-update) Gateway event.
List Guild Top Games
Returns up to 20 of the top most played games for the guild. Requires the `MANAGE_GUILD` permission.
###### Response Body
| Field | Type | Description |
| --------- | ------------------------------------------------------- | --------------------------------- |
| top_games | array[[game activity](#game-activity-structure) object] | The top games played in the guild |
###### Game Activity Structure
| Field | Type | Description |
| ------------------- | --------- | ----------------------------------------------- |
| game_application_id | snowflake | The ID of the application representing the game |
| activity_level | integer | The activity level of the guild in the game |
| activity_score | integer | The activity score of the guild in the game |
List Premium Guild Subscriptions
Returns a list of [premium guild subscription](#premium-guild-subscription-object) objects for the guild. User must be a member of the guild.
###### Query String Params
| Field | Type | Description |
| -------------- | ------- | ----------------------------------------------------------------------------- |
| include_ended? | boolean | Whether to include premium guild subscripions that have ended (default false) |
Create Premium Guild Subscriptions
Adds premium guild subscriptions to the given guild. User must be a member of the guild. Returns a list of [premium guild subscription](#premium-guild-subscription-object) objects on success.
Fires [Guild Update](/gateway/gateway-events#guild-update), optionally [Message Create](/gateway/gateway-events#message-create), [Guild Applied Boosts Update](/gateway/gateway-events#guild-applied-boosts-update), multiple [User Premium Guild Subscription Slot Update](/gateway/gateway-events#user-premium-guild-subscription-slot-update), and optionally [Guild Member Update](/gateway/gateway-events#guild-member-update) and [Guild Powerup Entitlements Create](/gateway/gateway-events#guild-powerup-entitlements-create) Gateway events.
###### JSON Params
| Field | Type | Description |
| ---------------------------------------- | ---------------- | --------------------------------------------------------- |
| user_premium_guild_subscription_slot_ids | array[snowflake] | The premium guild subscription slot IDs to apply |
| disable_powerup_auto_apply? | boolean | Whether to disable auto-creating powerups (default false) |
Delete Premium Guild Subscription
Deletes a premium guild subscription. User must be the owner of the subscription slot. Returns a 204 empty response on success. Fires a [User Premium Guild Subscription Slot Delete](/gateway/gateway-events#user-premium-guild-subscription-slot-delete), [Guild Update](/gateway/gateway-events#guild-update), [Guild Applied Boosts Update](/gateway/gateway-events#guild-applied-boosts-update) and optionally [Guild Member Update](/gateway/gateway-events#guild-member-update) Gateway events.
List Guild Powerups
Returns a list of [entitlement](/resources/entitlement#entitlement-object) objects representing the guild's applied powerups. Powerups are special SKUs that can be purchased using premium subscriptions (boosts) to enhance the guild's features. User must be a member of the guild.
###### Query String Params
| Field | Type | Description |
| ---------------- | ------- | ----------- |
| include_ends_at? | boolean | Unknown |
Add Guild Powerup
Adds the given powerup SKU to the guild. Requires the `MANAGE_GUILD` permission. Returns a 204 empty response on success. Fires [Guild Update](/gateway/gateway-events#guild-update), [Guild Powerup Entitlements Create](/gateway/gateway-events#guild-powerup-entitlements-create), and optionally [Game Server Create](/gateway/gateway-events#game-server-create) Gateway events.
###### JSON Params
| Field | Type | Description |
| ------------------- | ------ | --------------------------------------------- |
| game_server_name? | string | The name of the game server (1-32 characters) |
| game_server_region? | string | The region for the game server |
Modify Guild Powerup
Modifies the guild's powerup. Returns a 204 empty response on success. Fires a [Game Server Update](/gateway/gateway-events#game-server-update) Gateway event.
###### JSON Params
| Field | Type | Description |
| ----------------- | --------- | --------------------------------------------- |
| game_server_name? | string | The name of the game server (1-32 characters) |
| sku_id? | snowflake | The ID of the plan SKU |
Remove Guild Powerup
Removes the given powerup SKU from the guild. Requires the `MANAGE_GUILD` permission. Returns a 204 empty response on success. Fires [Guild Update](/gateway/gateway-events#guild-update), [Guild Powerup Entitlements Delete](/gateway/gateway-events#guild-powerup-entitlements-delete), and optionally [Game Server Delete](/gateway/gateway-events#game-server-delete) Gateway events.
###### Query String Params
| Field | Type | Description |
| --------------- | --------- | ---------------------------------------------------------------------------------------- |
| entitlement_id? | snowflake | The ID of the entitlement to remove (if not specified, all entitlements will be removed) |
List Guild Game Servers
Returns a list of [game server](#game-server-object) objects attached to the given guild ID.
List Guild Game Server Regions
Returns a list of [game server region](#game-server-region-structure) objects for the given guild ID.
###### Game Server Region Structure
| Field | Type | Description |
| ------------ | ------ | ----------------------------------------------------------------------------------------------------- |
| id | string | The ID of the region |
| name | string | The name of the region |
| country_code | string | The [ISO 3166-1 alpha-2](https://en.wikipedia.org/wiki/ISO_3166-1_alpha-2) country code of the region |
| ping_url | string | The WebSocket URL of region server used to ping |
Wake Guild Game Server
Wakes up the game server. Returns a [game server](#game-server-object) object on success.
Get Admin Community Eligibility
Checks if the user is eligible to join the Discord Admin Community through the guild. Requires the `MANAGE_GUILD` permission.
###### Response Body
| Field | Type | Description |
| ------------------------- | ------- | ---------------------------------------------------------------------------------- |
| eligible_for_admin_server | boolean | Whether the user is eligible to join the Discord Admin Community through the guild |
Join Admin Community
Joins the Discord Admin Community through the guild. Requires the `MANAGE_GUILD` permission. Returns the joined [guild](#guild-object) object on success. Fires [Guild Create](/gateway/gateway-events#guild-create), [Guild Member Add](/gateway/gateway-events#guild-member-add), and optionally [Guild Join Request Create](/gateway/gateway-events#guild-join-request-create) Gateway events.
Migrate Pin Permission
Migrates the guild's `MANAGE_MESSAGES` permission to the new `PIN_MESSAGES` permission. Requires the `ADMINISTRATOR` permission. Returns a 204 empty response on success. Fires a [Guild Update](/gateway/gateway-events#guild-update) and multiple [Channel Update](/gateway/gateway-events#channel-update) and [Guild Role Update](/gateway/gateway-events#guild-role-update) Gateway events.
Migrate Bypass Slowmode Permission
Migrates the guild's `MANAGE_MESSAGES`, `MANAGE_CHANNEL` and `MANAGE_THREADS` permissions to the new `BYPASS_SLOWMODE` permission. Requires the `ADMINISTRATOR` permission. Returns a 204 empty response on success. Fires a [Guild Update](/gateway/gateway-events#guild-update) and multiple [Channel Update](/gateway/gateway-events#channel-update) and [Guild Role Update](/gateway/gateway-events#guild-role-update) Gateway events.
Query Student Hubs
Queries the student hubs for the given email.
###### JSON Params
| Field | Type | Description |
| -------------------------- | --------- | ------------------------------------------------------------------------------------------------- |
| email | string | The email to lookup (max 320 characters) |
| use_verification_code? ^1^ | boolean | Whether to email the user a code to verify their student status (default false) |
| allow_multiple_guilds? ^2^ | boolean | Whether to return a list of guilds for the email instead of picking the first one (default false) |
| guild_id? ^2^ | snowflake | The guild ID to email a verification code for |
^1^ `use_verification_code` should always be set to `true` as the old behavior is deprecated and results in an email asking the user to update their client to join the student hub.
^2^ `allow_multiple_guilds` should always be set to `true` as the resultant guild ID is required for the [Join Student Hub](#join-student-hub) endpoint.
If `allow_multiple_guilds` is set to `false`, the `guild_id` parameter is ignored and an email is sent for the first guild found. If `allow_multiple_guilds` is set to `true`, a second request must be made with a `guild_id` provided to send the email.
###### Response Body
| Field | Type | Description |
| ------------------ | --------------------------------------------------------------- | ------------------------------------------------------------------------------------ |
| has_matching_guild | boolean | Whether a student hub was found and verification code was sent to the email provided |
| guilds_info? ^1^ | array[[student hub guild](#student-hub-guild-structure) object] | The guilds found for the email provided |
^1^ Only returned if `allow_multiple_guilds` is set to `true` and no `guild_id` is provided.
###### Student Hub Guild Structure
| Field | Type | Description |
| ----- | --------- | -------------------------------------------------------- |
| id | snowflake | The ID of the student hub |
| name | string | The name of the student hub (2-100 characters) |
| icon | ?string | The student hub's [icon hash](/reference#cdn-formatting) |
Join Student Hub
Verifies the student status of the user and joins them to the student hub guild. May fire [Guild Create](/gateway/gateway-events#guild-create), [Guild Member Add](/gateway/gateway-events#guild-member-add), and optionally [Guild Join Request Create](/gateway/gateway-events#guild-join-request-create) Gateway events.
###### JSON Params
| Field | Type | Description |
| -------- | --------- | ------------------------------------------------------ |
| email | string | The email to verify (max 320 characters) |
| guild_id | snowflake | The ID of the student hub being joined |
| code | string | The verification code sent to the email (8 characters) |
###### Response Body
| Field | Type | Description |
| ------ | ---------------------- | ---------------------------------------------------------- |
| joined | boolean | Whether the user successfully joined the student hub guild |
| guild? | [guild](#guild-object) | The student hub guild the user joined |
Join Student Hub Waitlist
Signs up the user for the student hub waitlist. The user will get an email and system message when a student hub is created for their email domain.
###### JSON Params
| Field | Type | Description |
| ------ | ------ | -------------------------------------------------------------- |
| email | string | The email to sign up for the waitlist (max 320 characters) |
| school | string | The name of the school the user is attending (3-20 characters) |
###### Response Body
| Field | Type | Description |
| ------------ | --------- | ----------------------------------------------------------- |
| email | string | The email that was signed up for the waitlist |
| email_domain | string | The domain of the email that was signed up for the waitlist |
| school | string | The name of the school the user is attending |
| user_id | snowflake | The ID of the user that signed up for the waitlist |
###### Example Response
```json
{
"email": "nelly@discordapp.com",
"user_id": "852892297661906993",
"email_domain": "discordapp.com",
"school": "discord"
}
```
Get Guild Role Subscriptions Settings
Returns a [role subscription settings](#role-subscription-settings-object) object for the given guild ID. User must be a member of the guild.
Modify Guild Role Subscriptions Settings
Modifies the guild's role subscription settings. Requires the `MANAGE_GUILD` permission. Returns a [role subscription settings](#role-subscription-settings-object) object on success.
###### JSON Params
| Field | Type | Description |
| --------------------------------------- | -------- | -------------------------------------------------------------------------------------------------- |
| full_server_gate? | boolean | Whether the guild is fully gated behind a role subscription |
| description? | ?string | The description of the guild's shop (max 1500 characters) |
| server_shop_tab_order? | integer | The [order of tabs in guild shop](#guild-product-shop-tabs-order-type) |
| store_page_enabled? | boolean | Whether the store page should be enabled |
| store_page_primary_color? | ?integer | The store page accent color encoded as an integer representation of a hexadecimal color code |
| store_page_trailer_url? | ?string | The URL to the teaser trailer YouTube video (max 8192 characters) |
| store_page_show_subscriber_count? | boolean | Whether to show amount of role subscribers on the store page |
| store_page_guild_products_default_sort? | integer | The default [sort order](#guild-product-sort-order-type) of the guild's products on the store page |
Create Guild Role Subscription Group Listing
Creates a subscription group listing. Requires the `ADMINISTRATOR` permission. Accepts an empty object. Returns a [role subscription group listing](#role-subscription-group-listing-object) object on success.
###### JSON Params
| Field | Type | Description |
| ------------ | ------ | ----------------------------------------------------------------------- |
| description? | string | The description of the subscription group listing (max 1500 characters) |
Get Guild Role Subscription Group Listing
Returns a partial [role subscription group listing](#role-subscription-group-listing-object) object without `subscription_listings` and `benefit_channels` fields for the given guild and subscription group listing ID.
###### Query String Parameters
| Field | Type | Description |
| ------------------------------ | ------- | ----------------------------------------------------------------- |
| include_draft_listings? ^1^ | boolean | Whether to include drafted subscription listings (default false) |
| include_archived_listings? ^1^ | boolean | Whether to include archived subscription listings (default false) |
^1^ Requires the `ADMINISTRATOR` permission.
###### Example Response Body
```json
{
"id": "1005887530828320878",
"guild_id": "679875946597056683",
"application_id": "1004764183042211890",
"name": "Premium Membership Group",
"description": " ",
"subscription_listings_ids": ["1005887534900985896", "1031542675255603261", "1162013584243556412"]
}
```
List Guild Role Subscription Group Listings
Returns an array of [role subscription group listing](#role-subscription-group-listing-object) objects for the given guild ID. User must be a member of the guild.
###### Query String Parameters
| Field | Type | Description |
| --------------------------- | ------- | ---------------------------------------------------------------------------------------------- |
| include_draft_listings? ^1^ | boolean | Whether to include drafted subscription listings (default false) |
| include_soft_deleted? | boolean | Whether to include soft deleted subscription group listings (default false) |
| country_code? | string | The user's [ISO 3166-1 alpha-2](https://en.wikipedia.org/wiki/ISO_3166-1_alpha-2) country code |
^1^ Requires the `ADMINISTRATOR` permission.
Modify Guild Role Subscription Group Listing
Modifies the guild role subscription group listing. Requires the `ADMINISTRATOR` permission. Returns the updated [role subscription group listing](#role-subscription-group-listing-object) object on success.
###### JSON Params
| Field | Type | Description |
| ------------ | ------ | ----------------------------------------------------------------------- |
| description? | string | The description of the subscription group listing (max 1500 characters) |
Delete Guild Role Subscription Group Listing
Deletes the guild role subscription group listing. Requires the `ADMINISTRATOR` permission. Returns a 204 empty response on success.
Create Guild Role Subscription Listing
Creates the guild role subscription listing. Requires the `ADMINISTRATOR` permission. Returns a [role subscription listing](#role-subscription-listing-object) object on success.
###### JSON Params
| Field | Type | Description |
| ------------------------ | ------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------ |
| name | string | The name of the subscription listing (1-100 characters) |
| description | string | The description of the subscription listing (1-1500 characters) |
| image | [image data](/reference#cdn-data) | The thumbnail of the subscription listing |
| price_tier | integer | The [base price](/resources/store#list-store-price-tiers) of the SKU |
| benefits | array[[role subscription benefit](#role-subscription-benefit-structure) object] | The benefits of the role |
| can_access_all_channels? | boolean | Whether purchasing the subscription listing will grant access to the guild (default false) |
Modify Guild Role Subscription Listing
Modifies the guild role subscription listing. Requires the `ADMINISTRATOR` permission. Returns an updated [role subscription listing](#role-subscription-listing-object) object on success.
###### JSON Params
| Field | Type | Description |
| ------------------------ | ------------------------------------------------------------------------------- | -------------------------------------------------------------------------- |
| name? | string | The name of the subscription listing |
| description? | string | The description of the subscription listing |
| image? | ?[image data](/reference#cdn-data) | The thumbnail of the subscription listing |
| price_tier? | integer | The [base price](/resources/store#list-store-price-tiers) of the SKU |
| benefits? | array[[role subscription benefit](#role-subscription-benefit-structure) object] | The benefits of the role |
| can_access_all_channels? | boolean | Whether purchasing the subscription listing will grant access to the guild |
Delete Guild Role Subscription Listing
Deletes the guild role subscription listing. Requires the `ADMINISTRATOR` permission. Returns a 204 empty response on success.
Archive Guild Role Subscription Listing
Archives the subscription group listing. Requires the `ADMINISTRATOR` permission. Returns a 204 empty response on success.
List Guild Role Subscription Trials
Returns an array of [role subscription trial](#role-subscription-trial-object) objects for the given guild ID.
Modify Guild Role Subscription Listing Trial
Modifies the subscription listing's trial information. Returns a 204 empty response.
###### JSON Params
| Field | Type | Description |
| --------------------------- | -------------------------------------------------------------------------------------- | ------------------------------------------------------------- |
| trial? | partial [subscription trial](/resources/subscription#subscription-trial-object) object | The subscription trial's interval information |
| max_num_active_trial_users? | ?integer | Maximum number of possibly active users of the trial (10-100) |
List Guild Role Subscription Listing Templates
Returns the guild role subscription listing templates, used as placeholders to help guide role subscription creation.
###### Response Body
| Field | Type | Description |
| --------- | ------------------------------------------------------------------------------------------------- | ------------- |
| templates | array[[role subscription listing template](#role-subscription-listing-template-structure) object] | The templates |
###### Role Subscription Listing Template Structure
| Field | Type | Description |
| ------------------------------------- | ------------------------------------------------------------------------------------------------- | ------------------------------------------------- |
| category | string | The category name |
| category_image | string | The CDN URL to the default category image |
| unselected_dark_theme_category_image | string | The CDN URL to the category image for dark theme |
| unselected_light_theme_category_image | string | The CDN URL to the category image for light theme |
| listings | array[[template role subscription listing](#template-role-subscription-listing-structure) object] | The template listings |
###### Template Role Subscription Listing Structure
| Field | Type | Description |
| ---------------- | ----------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------- |
| name | string | The name of the subscription listing |
| description | string | The description of the subscription listing |
| price_tier | integer | The [base price](/resources/store#list-store-price-tiers) of the SKU |
| image | [image data](/reference#cdn-data) | The thumbnail of the subscription listing |
| role_color | integer | The primary color of the role represented as an integer representation of a hexadecimal color code |
| channels | array[[template role subscription listing channel](#template-role-subscription-listing-channel-structure) object] | The channels available to the role |
| additional_perks | array[[role subscription benefit](#role-subscription-benefit-structure) object] | The additional perks of the role |
###### Template Role Subscription Listing Channel Structure
| Field | Type | Description |
| ----------- | --------- | ------------------------------------------------------ |
| id | snowflake | The ID of the channel |
| type | integer | The [type of channel](/resources/channel#channel-type) |
| name | string | The name of the channel |
| tagline | string | The tagline of the channel |
| description | string | The topic of the channel |
| topic | string | The topic of the channel |
| emoji_name | string | The unicode character of the emoji |
###### Example Role Subscription Listing Template
```json
{
"category": "Supporter",
"category_image": "https://cdn.discordapp.com/assets/server-subscription-tier-template/Supporter.png",
"unselected_dark_theme_category_image": "https://cdn.discordapp.com/assets/server-subscription-tier-template/Supporter_unselected_dark_theme.png",
"unselected_light_theme_category_image": "https://cdn.discordapp.com/assets/server-subscription-tier-template/Supporter_unselected_light_theme.png",
"listings": [
{
"name": "Supporter",
"description": "Join the Supporters! Subscribe now for exclusive chats to meet and mingle with other subscribers.",
"image": "data:image/png;base64,i...",
"price_tier": 399,
"channels": [
{
"id": "1087447734891315201",
"type": 5,
"name": "supporter-updates",
"tagline": "Share the latest news!",
"description": "Get notified about streams, events, and more.",
"topic": "Get notified about streams, events, and more.",
"emoji_name": "📢"
},
{
"id": "1087447734891315202",
"type": 0,
"name": "supporter-chat",
"tagline": "A special chat just for fans.",
"description": "Meet, mix, and mingle with fellow supporters.",
"topic": "Meet, mix, and mingle with fellow supporters.",
"emoji_name": "⭐"
}
],
"additional_perks": [
{
"emoji_id": null,
"emoji_name": "⭐",
"name": "Supporter-Only Chats",
"description": "Hangout with other supporters in exclusive spaces.",
"ref_type": 2,
"ref_id": null
}
],
"role_color": 9369855
}
]
}
```
Get Guild Role Subscription Listing Trial Eligibility
Returns whether the current user is eligible for a role subscription listing trial.
###### Response Body
| Field | Type | Description |
| ----------- | ------- | ------------------------------------ |
| is_eligible | boolean | Whether the current user is eligible |
Get Creator Monetization Eligibility
Returns the creator monetization eligibility for the guild. User must be the owner.
###### Response Body
| Field | Type | Description |
| --------------------------- | -------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------ |
| guild_id | snowflake | The ID of the guild |
| can_apply? | boolean | Whether the guild meets the requirements to apply for creator monetization |
| sufficient? | boolean | Whether the guild meets the requirements to use creator monetization |
| country? | boolean | Whether the guild owner is in a country eligible for creator monetization |
| mfa? | boolean | Whether the guild has the [MFA requirement for moderation actions](/resources/guild#mfa-level) enabled |
| size? | boolean | Whether the guild meets the minimum member count requirement |
| safe_environment? | boolean | Whether the guild has not been flagged by Trust & Safety |
| health_score? | ?[discovery health score](/resources/discovery#discovery-health-score-structure) object | The guild's activity metrics |
| health_score_pending? | boolean | Whether the guild's activity metrics have not yet been calculated |
| nsfw_properties? | [discovery NSFW properties](/resources/discovery#discovery-nsfw-properties-structure) object | Disallowed terms found in the guild's name, description, and channel names |
| retention_healthy? | boolean | Whether the guild meets the new member retention requirement |
| engagement_healthy? | boolean | Whether the guild meets the weekly visitor and communicator requirements |
| age? | boolean | Whether the guild meets the minimum age requirement |
| owner_age? | boolean | Whether the guild owner meets the minimum legal age requirement |
| minimum_age_in_days? | ?integer | The minimum guild age requirement (in days) |
| minimum_owner_age_in_years? | ?integer | The minimum guild owner legal age requirement (in years) |
| minimum_size? | ?integer | The minimum guild member count requirement |
| latest_request? | [creator monetization request](#creator-monetization-request-object) object | The latest request to enable creator monetization |
| rejection? | [creator monetization rejection](#creator-monetization-rejection-structure) object | The information about the latest application rejection |
###### Creator Monetization Rejection Structure
| Field | Type | Description |
| --------------- | ------------------ | ------------------------------------------- |
| can_reapply_at? | ?ISO8601 timestamp | When the guild can reapply for monetization |
Create Creator Monetization Enable Request
Creates a request to enable access to guild monetization features. User must be the owner. Returns a 204 empty response on success.
Accept Creator Monetization Enable Request Terms
Accepts the guild monetization terms of use for the given enable request. User must be the owner. Returns a 204 empty response on success. Fires a [Guild Update](/gateway/gateway-events#guild-update) Gateway event.
This endpoint is deprecated. It is replaced by [Accept Creator Monetization Terms](#accept-creator-monetization-terms).
Accept Creator Monetization Terms
Accepts the guild monetization terms of use. User must be the owner. Returns a 204 empty response on success. Fires a [Guild Update](/gateway/gateway-events#guild-update) Gateway event.
Get Creator Monetization Restrictions
Returns the currently active restrictions to creator monetization.
###### Response Body
| Field | Type | Description |
| ------------ | --------------- | ---------------------------------------------------------------------------------- |
| restrictions | ?array[integer] | The [restrictions to creator monetization](#creator-monetization-restriction-type) |
###### Creator Monetization Restriction Type
| Value | Description |
| ----------------------------------- | ---------------------------------------------------------- |
| NEW_PURCHASES_DISABLED | New purchases are disabled |
| REAPPLICATION_DISABLED | Creator cannot reapply |
| SETTINGS_READ_ONLY | The settings are read-only |
| SUBSCRIPTIONS_ENDED_FULL_REFUND | Subscriptions are cancelled and a full refund is given |
| SUBSCRIPTIONS_ENDED_PRORATED_REFUND | Subscriptions are cancelled and a prorated refund is given |
Get Creator Monetization Marketing Onboarding
Returns the marketing onboarding for monetization.
###### Response Body
| Field | Type | Description |
| -------- | ------------------------------------------------------------------------------------------------------------------------------- | ------------ |
| sections | array[[creator monetization marketing onboarding section](#creator-monetization-marketing-onboarding-section-structure) object] | The sections |
###### Creator Monetization Marketing Onboarding Section Structure
| Field | Type | Description |
| ------------- | --------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------ |
| type | string | The [type of section](#creator-monetization-marketing-onboarding-section-type) |
| creators? ^1^ | array[[creator monetization marketing onboarding section review](#creator-monetization-marketing-onboarding-section-review-structure) object] | The reviews from other creators |
^1^ Only present if `type` is [`OTHER_CREATORS`](#creator-monetization-marketing-onboarding-section-type).
###### Creator Monetization Marketing Onboarding Section Review Structure
| Field | Type | Description |
| ----------------------- | --------- | ------------------------------------ |
| guild_id | snowflake | The ID of the guild |
| quote | string | The contents of the creator's review |
| quote_attribution | string | The name of the creator |
| quote_attribution_title | string | The role of the creator |
###### Creator Monetization Marketing Onboarding Section Type
| Value | Description |
| -------------- | ------------------------------- |
| HOW_IT_WORKS | Section explaining how it works |
| BENEFITS | Benefits section |
| OTHER_CREATORS | Section with other creators |
Update Creator Monetization Team
Transfers ownership of the guild's internal creator monetization application to a [team](/resources/team). User must be the owner of the current team.
###### JSON Params
| Field | Type | Description |
| ------- | --------- | ------------------------------------------- |
| team_id | snowflake | The ID of the team to transfer ownership to |
###### Response Body
| Field | Type | Description |
| ----------- | ----------------------------------------------------------------------- | ------------------------------------ |
| application | partial [application](/resources/application#application-object) object | The application that got transferred |
Accept Creator Monetization New Terms Demonetized
Accepts the guild monetization terms of use after getting demonetized. User must be the owner. Returns a 204 empty response on success. Fires a [Guild Update](/gateway/gateway-events#guild-update) Gateway event.
Remove Creator Monetization
Removes the guild's access to monetization features. Accepts an empty object. User must be the owner. Returns a 204 empty response on succses. Fires a [Guild Update](/gateway/gateway-events#guild-update) Gateway event.
Create Guild Product Listing
Creates a guild product listing. Requires the `ADMINISTRATOR` permission. Returns a [guild product listing](#guild-product-listing-object) object on success.
###### JSON Params
| Field | Type | Description |
| ---------------- | ------------------------------------------------------------------------ | ------------------------------------------------------------------------ |
| name | string | The name of the product listing (1-100 characters) |
| description? | string | The description of the product listing (max 1500 characters) |
| price_tier? | integer | The [base price](/resources/store#list-store-price-tiers) of the SKU |
| create_new_role? | boolean | Whether to create a managed role for the product listing (default false) |
| image | [image data](/reference#cdn-data) | The thumbnail of the product listing |
| image_name | string | The name of the thumbnail image (max 100 characters) |
| attachments? ^1^ | array[partial [attachment](/resources/message#attachment-object) object] | The attachments to grant |
^1^ See [Uploading Files](/reference#uploading-files) for details. The attachments must be uploaded through the [Create Guild Product Attachments](/topics/cloud-uploads#create-guild-product-attachments) endpoint.
List Guild Product Listings
Returns the product listings for the given guild ID. User must be a member of the guild.
###### Response Body
| Field | Type | Description |
| -------- | -------------------------------------------------------------------- | ---------------------------------- |
| listings | array[[guild product listing](#guild-product-listing-object) object] | The product listings for the guild |
Get Guild Product Listing
Returns a [guild product listing](#guild-product-listing-object) object for the given guild and product listing ID.
Modify Guild Product Listing
Modifies the guild product listing. Requires the `ADMINISTRATOR` permission. Returns a [guild product listing](#guild-product-listing-object) object on success.
###### JSON Params
| Field | Type | Description |
| ---------------- | ------------------------------------------------------------------------ | --------------------------------------------------------------------------------------- |
| name? | string | The name of the product listing (1-100 characters) |
| description? | string | The description of the product listing (max 1500 characters) |
| price_tier? | integer | The [base price](/resources/store#list-store-price-tiers) of the SKU |
| create_new_role? | boolean | Whether to create a managed role for the product listing |
| image? | ?[image data](/reference#cdn-data) | The thumbnail of the product listing |
| image_name? | string | The name of the thumbnail image (max 100 characters) |
| unlink_role? | boolean | Whether to unlink the currently-managed role, allowing it to be deleted (default false) |
| attachments? ^1^ | array[partial [attachment](/resources/message#attachment-object) object] | The attachments to grant |
^1^ See [Uploading Files](/reference#uploading-files) for details. The attachments must be uploaded through the [Create Guild Product Attachments](/topics/cloud-uploads#create-guild-product-attachments) endpoint.
Delete Guild Product Listing
Deletes the guild product listing. Requires the `ADMINISTRATOR` permission. Returns a 204 empty response on success.
Get Guild Product Listing Attachment URL
Returns a URL to the attachment for the given guild and product ID. Requires an entitlement to the product or the `ADMINISTRATOR` permission.
###### Response Body
| Field | Type | Description |
| ----- | ------ | ------------------------- |
| url | string | The URL to the attachment |
---
# Checkpoint
Link: https://docs.discord.food/resources/checkpoint
A recap of the user's yearly activity, inspired by [Spotify Wrapped](https://www.spotify.com/us/wrapped/).
## Endpoints
Get Checkpoint
Retrieves the user's current yearly checkpoint.
###### Response Body
| Field | Type | Description |
| ----------------------- | ---------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------- |
| card_id? | integer | The [type of checkpoint card](#checkpoint-card-type) |
| avatar_decoration | [avatar decoration collectible item](/resources/collectibles#avatar-decoration-collectible-item-structure) | A free avatar decoration granted by viewing the checkpoint |
| power_level? | float | A power level representing how active the user was on Discord |
| power_level_percentile? | float | The power level expressed as a percentile |
| messages? | [checkpoint message statistics](#checkpoint-message-statistics-structure) object | Statistics about messages sent by the current user during the year |
| emojis? | [checkpoint emoji statistics](#checkpoint-emoji-statistics-structure) object | Statistics about emojis the current user used during the year |
| voice? | [checkpoint voice statistics](#checkpoint-voice-statistics-structure) object | Statistics about voice activity from the current user during the year |
| guilds? | [checkpoint guilds statistics](#checkpoint-guilds-statistics-structure) object | Statistics about guilds the current user was active in during the year |
| sidekick? | [checkpoint sidekick](#checkpoint-sidekick-structure) object | The user the current user talk to the most |
| users? | array[[checkpoint user](#checkpoint-user-structure) object] | Additional users the current user spent the most time with during the year |
| applications? | [checkpoint games statistics](#checkpoint-games-statistics-structure) object | Games played during the year |
| quests? | [checkpoint quest statistics](#checkpoint-quest-statistics-structure) object | Number of completed quests and collected orbs during the year |
###### Checkpoint Card Type
| Value | Name |
| ----- | -------------------- |
| 0 | PLANT |
| 1 | DONUT |
| 2 | DOG_IN_SWIM_RING |
| 3 | DISCO_BALL |
| 4 | ORIGAMI_PAPER_CRANE |
| 5 | SNAIL |
| 6 | DUCK_WITH_SUNGLASSES |
| 7 | BANANA |
| 8 | CAT |
| 9 | CARTRIDGE |
###### Checkpoint Message Statistics Structure
| Field | Type | Description |
| ---------------------------- | ----------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------- |
| num_messages_sent | integer | Number of messages the current user sent during the year |
| num_messages_sent_percentile | ?float | The user's rank in message-sending activity compared to all users, expressed as a percentile |
| top_month | ?[checkpoint message top month statistics](#checkpoint-message-top-month-statistics-structure) object | The month the current user sent the most messages during the year |
###### Checkpoint Message Top Month Statistics Structure
| Field | Type | Description |
| ----------------- | ------- | --------------------------------------------------------- |
| month | integer | The top month (1-12) |
| num_messages_sent | integer | Number of messages the current user sent within the month |
###### Checkpoint Emoji Statistics Structure
| Field | Type | Description |
| --------------- | ------------------------------------------------------------ | ------------------------------------------------------------------- |
| num_emojis_sent | integer | Number of emojis used (includes messages with emojis and reactions) |
| emojis | array[partial [emoji](/resources/emoji#emoji-object) object] | Up to 5 emojis the current user used the most |
###### Checkpoint Voice Statistics Structure
| Field | Type | Description |
| ------------------------------ | ------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------- |
| total_voice_minutes | float | Duration in seconds how much time the user spent in voice channels for year |
| total_voice_minutes_percentile | ?float | The user's rank in voice activity compared to all users, expressed as a percentile |
| top_month | ?[checkpoint voice top month statistics](#checkpoint-voice-top-month-statistics-structure) object | The month the current user participated in calls the most |
###### Checkpoint Voice Top Month Statistics Structure
| Field | Type | Description |
| -------------------- | ------- | --------------------------------------------------------- |
| month | integer | The top month (1-12) |
| num_minutes_in_voice | float | Duration in minutes that the current user spent in a call |
###### Checkpoint Guilds Statistics Structure
| Field | Type | Description |
| ----------------- | ----------------------------------------------------------------------------------- | -------------------------------------------------------- |
| num_guilds_joined | integer | Number of guilds the current user joined |
| guilds | array[[checkpoint guild statistics](#checkpoint-guild-statistics-structure) object] | Up to 3 guilds the current user participated in the most |
###### Checkpoint Guild Statistics Structure
| Field | Type | Description |
| ------------------ | ----------------------------------------------------- | --------------------------------------------------------------------- |
| num_messages_sent? | integer | Number of messages the current user sent in the guild during the year |
| num_voice_minutes? | float | Duration in minutes that the current user spent in guild voice |
| guild | partial [guild](/resources/guild#guild-object) object | The guild |
###### Checkpoint Sidekick Structure
| Field | Type | Description |
| ----------------- | -------------------------------------------------- | ---------------------------------------------------------------------- |
| user | partial [user](/resources/user#user-object) object | The sidekick user |
| num_messages_sent | integer | Number of messages the current user sent in the user's DM |
| num_voice_minutes | float | Duration in minutes the current user spent being in call with the user |
###### Checkpoint User Structure
| Field | Type | Description |
| ----- | -------------------------------------------------- | ----------- |
| user | partial [user](/resources/user#user-object) object | The user |
###### Checkpoint Games Statistics Structure
| Field | Type | Description |
| ------------------ | --------------------------------------------------------------------------------- | ----------------------------- |
| total_games_played | integer | Total amount of games played |
| applications | array[[checkpoint game statistics](#checkpoint-game-statistics-structure) object] | Statistics about games played |
###### Checkpoint Game Statistics Structure
| Field | Type | Description |
| ------------ | ----------------------------------------------------------------------- | ----------------------- |
| num_sessions | integer | Number of game sessions |
| game | partial [application](/resources/application#application-object) object | The game application |
###### Checkpoint Quest Statistics Structure
| Field | Type | Description |
| ------------- | ------- | ------------------------------------ |
| num_completed | integer | Number of completed quests |
| num_orbs | integer | Amount of collected Orbs from quests |
###### Example Response Body
```json
{
"card_id": 5,
"avatar_decoration": {
"type": 0,
"id": "1440174720640352344",
"sku_id": "1440174638930853954",
"asset": "a_523d7733d1b88cfbad5b082d062defc4",
"assets": {
"static_image_url": "https://cdn.discordapp.com/assets/content/0a5c302e0a0e20ee64754723466ab8cc740b304901697cf9ede00211bda6e138",
"animated_image_url": "https://cdn.discordapp.com/assets/content/d8a4a1544816b6034e28b06a52c2c0489677c6626c977671959a9e9f68915670"
},
"label": "A snail avatar decoration."
},
"power_level": 83732.32311666667,
"power_level_percentile": 87.039,
"messages": {
"num_messages_sent": 53146,
"num_messages_sent_percentile": 99.19,
"top_month": {
"month": 7,
"num_messages_sent": 6811
}
},
"emojis": {
"num_emojis_sent": 13096,
"emojis": [
{
"id": "1145727546747535412",
"name": "blobcatcozy",
"animated": false
},
{
"name": "💀"
},
{
"id": "1030570693903011921",
"name": "husk",
"animated": false
}
{
"name": "😭"
},
{
"name": "🔥"
}
]
},
"voice": {
"total_voice_minutes": 6.3231166666666665,
"total_voice_minutes_percentile": null,
"top_month": {
"month": 7,
"num_minutes_in_voice": 6.23785
}
},
"guilds": {
"num_guilds_joined": 11,
"guilds": [
{
"num_messages_sent": 3711,
"num_voice_minutes": 0.0,
"guild": {
"id": "1046920999469330512",
"name": "Alien Network",
"icon": "66b0f4d96c145970fa9d96ada8afadf3",
"description": "Where the 👽s 👽 and sometimes very 👽 things happen 😨.",
"home_header": "39ba384a31e9c285649ad00b359946ab",
"splash": "b40e61f7730b8781b9a551964570e0cc",
"discovery_splash": "0e11ae8d9f1c86958be05e61b0c90ac3",
"features": []
}
},
{
"guild": {
"id": "302094807046684672",
"name": "MINECRAFT",
"icon": "24f8bc7ec317e6eaaa0d8352720a7dfe",
"description": "The official Minecraft Discord!",
"home_header": null,
"splash": "5d84dff0dfaa9c2f4f23a0612564383b",
"discovery_splash": "5d84dff0dfaa9c2f4f23a0612564383b",
"features": [
"ANIMATED_BANNER"
"ANIMATED_ICON",
"BANNER",
"COMMUNITY",
"DISCOVERABLE",
"ENABLED_DISCOVERABLE_BEFORE",
"PREVIEW_ENABLED",
"VANITY_URLS",
"VERIFIED",
"VIP_REGIONS"
]
}
},
{
"guild": {
"id": "322850917248663552",
"name": "Official Fortnite",
"icon": "aeed50fc9dadcdb03958f66d53aed053",
"description": "The Official Fortnite Discord Server! Join to follow news & updates, LFG, and chat about all things Fortnite!",
"home_header": null,
"splash": "e942dd9672490882b3c1cccb1bddc365",
"discovery_splash": "64f47845f91d4b77ab2af0cfd4551978",
"features": [
"ANIMATED_BANNER",
"ANIMATED_ICON",
"BANNER",
"COMMUNITY",
"DISCOVERABLE",
"FEATURABLE",
"INVITE_SPLASH",
"VANITY_URL",
"VERIFIED",
"VIP_REGIONS"
]
}
}
]
},
"sidekick": {
"user": {
"id": "852892297661906993",
"username": "dolfies",
"global_name": "Dolfies",
"avatar": "c78ef8fb1db15a3d5f1b4c057856c5c9",
"avatar_decoration_data": null,
"collectibles": null,
"discriminator": "0",
"display_name_styles": null,
"public_flags": 264,
"primary_guild": null
},
"num_messages_sent": 869,
"num_voice_minutes": 0.0
},
"users": [
{
"user": {
"id": "246877849162743818",
"username": "jay_taelien",
"global_name": "Jay",
"avatar": "91b7bc37e924f78625f7ea582fdbac5d",
"avatar_decoration_data": null,
"collectibles": null,
"discriminator": "0",
"display_name_styles": null,
"public_flags": 16512,
"primary_guild": null
}
},
{
"user": {
"id": "1001086404203389018",
"username": ".dziurwa",
"global_name": "Dziurwa💕",
"avatar": "f6c0363fbab45668fcf8f88fea56db9c",
"avatar_decoration_data": null,
"collectibles": null,
"discriminator": "0",
"display_name_styles": null,
"public_flags": 16640,
"primary_guild": null
}
}
],
"applications": {
"total_games_played": 2,
"applications": [
{
"num_sessions": 7,
"game": {
"id": "363445589247131668",
"name": "Roblox",
"icon_hash": "f2b60e350a2097289b3b0b877495e55f",
"banner_hash": "e970e33dd647f87dc87f4dc4b28f4627",
"cover_image_hash": "82f092687242e81976b955927df9cd24"
}
},
{
"num_sessions": 3,
"game": {
"id": "1402418703554842694",
"name": "Fortnite",
"icon_hash": "f2b60e350a2097289b3b0b877495e55f",
"banner_hash": null,
"cover_image_hash": "c1864b38910c209afd5bf6423b672022"
}
}
]
},
"quests": {
"num_completed": 73,
"num_orbs": 22500
}
}
```
Claim Checkpoint Avatar Decoration
Claims the free avatar decoration collectible from the checkpoint. Returns a 204 empty response.
---
# Stage Instances
Link: https://docs.discord.food/resources/stage-instance
A _stage instance_ holds information about a live stage. For more information on stages, see the [channel](/resources/channel#channel-object) object.
## Definitions
Below are some definitions related to stages.
- **Liveness:** A stage channel is considered _live_ when there is an associated stage instance. Conversely, a stage channel is _not live_ when there is no associated stage instance.
- **Speakers:** A participant of a stage channel is a _speaker_ when their [voice state](/resources/voice#voice-state-object)
is not `suppress`ed, and has no `request_to_speak_timestamp`.
- **Moderators**: A member of the guild is a _moderator_ of a stage channel if they have all of the following [permissions](/topics/permissions#permissions):
- `MANAGE_CHANNELS`
- `MUTE_MEMBERS`
- `MOVE_MEMBERS`
- **Topic**: This is the blurb that gets shown below the channel's name, among other places.
- **Public**: A stage instance is public when it has a `privacy_level` of `PUBLIC`. While a channel has a public stage instance, lurkers may join it.
## Auto Closing
When a stage channel has no speakers for a certain period of time (on the order of minutes) the stage instance will be automatically deleted.
### Stage Instance Object
###### Stage Instance Structure
| Field | Type | Description |
| -------------------------------------- | ---------- | ------------------------------------------------------------------------------------------------------------------------------ |
| id | snowflake | The ID of the stage instance |
| guild_id | snowflake | The guild ID of the associated stage channel |
| channel_id | snowflake | The ID of the associated stage channel |
| topic | string | The topic of the stage instance (1-120 characters) |
| privacy_level | integer | The [privacy level](/resources/guild#privacy-level) of the stage instance |
| invite_code | ?string | The [invite code](/resources/invite#invite-object) that can be used to join the stage channel, if the stage instance is public |
| discoverable_disabled **(deprecated)** | boolean | Whether or not stage discovery is disabled |
| guild_scheduled_event_id | ?snowflake | The ID of the [scheduled event](/resources/guild-scheduled-event#guild-scheduled-event-object) for this stage instance |
###### Example Stage Instance
```json
{
"id": "840647391636226060",
"guild_id": "197038439483310086",
"channel_id": "733488538393510049",
"topic": "Testing, Testing, 123",
"privacy_level": 1,
"discoverable_disabled": false,
"guild_scheduled_event_id": "947656305244532806",
"invite_code": "xdMaxHJqp8"
}
```
Create Stage Instance
Creates a new stage instance associated to a stage channel. Requires the user to be a moderator of the stage channel. Returns a [stage instance](#stage-instance-object) object.
Fires a [Stage Instance Create](/gateway/gateway-events#stage-instance-create) and optionally an [Invite Create](/gateway/gateway-events#invite-create) and [Guild Scheduled Event Update](/gateway/gateway-events#guild-scheduled-event-update) Gateway event.
###### JSON Params
| Field | Type | Description |
| ----------------------------- | --------- | ---------------------------------------------------------------------------------------------------------------------- |
| channel_id | snowflake | The ID of the stage channel |
| topic | string | The topic of the stage instance (1-120 characters) |
| privacy_level? | integer | The [privacy level](/resources/guild#privacy-level) of the stage instance (default `GUILD_ONLY`) |
| guild_scheduled_event_id? ^1^ | snowflake | The ID of the [scheduled event](/resources/guild-scheduled-event#guild-scheduled-event-object) for this stage instance |
| send_start_notification? ^2^ | boolean | Notify @everyone that a stage instance has started (default false) |
^1^ Creating a stage instance for a scheduled event will set the scheduled event's `status` to `ACTIVE`.
^2^ The stage moderator must have the `MENTION_EVERYONE` permission for this notification to be sent.
## Endpoints
Get Stage Instance
Gets the stage instance associated with the stage channel, if it exists. Returns a [stage instance](#stage-instance-object) object.
Modify Stage Instance
Updates fields of an existing stage instance. Requires the user to be a moderator of the stage channel. Returns the updated [stage instance](#stage-instance-object) object on success. Fires a [Stage Instance Update](/gateway/gateway-events#stage-instance-update) Gateway event.
###### JSON Params
| Field | Type | Description |
| -------------- | ------- | ------------------------------------------------------------------------- |
| topic? | string | The topic of the stage instance (1-120 characters) |
| privacy_level? | integer | The [privacy level](/resources/guild#privacy-level) of the stage instance |
Delete Stage Instance
Deletes the stage instance and associated invite. Requires the user to be a moderator of the stage channel. Returns a 204 empty response on success. Fires a [Stage Instance Delete](/gateway/gateway-events#stage-instance-delete) and optionally an [Invite Delete](/gateway/gateway-events#invite-delete) and [Guild Scheduled Event Update](/gateway/gateway-events#guild-scheduled-event-update) Gateway event.
Deleting a stage instance will automatically delete the associated invite and set the associated scheduled event's `status` to `COMPLETED`.
---
# Users
Link: https://docs.discord.food/resources/user
Users in Discord are generally considered the base entity. Users can spawn across the entire platform, be members of
guilds, participate in text and voice chat, and much more. Users are separated by a distinction of "bot" vs "normal". Although they are similar, bot users are automated users that are attached to an application, "owned" by another user. Unlike normal users, bot users do
_not_ have a limitation on the number of guilds they can be a part of.
### Usernames and Nicknames
Discord enforces the following restrictions for usernames, display names, and nicknames:
1. Names can contain most valid unicode characters. We limit some zero-width and non-rendering characters.
2. Usernames must be between 2 and 32 characters long.
3. Display names and nicknames must be between 1 and 32 characters long.
4. Webhook names must be between 1 and 80 characters long.
5. Names are sanitized and trimmed of leading, trailing, and excessive internal whitespace.
The following restrictions are additionally enforced for usernames and display names:
1. Usernames cannot contain the following substrings: '@', '#', ':', '\```'.
2. Usernames and display names cannot be: 'everyone', 'here', 'system message', or contain 'discord'.
The following restrictions are additionally enforced for webhook names:
1. Webhook names cannot contain the following substrings: 'clyde'.
[Migrated usernames](#unique-usernames) are subject to a new set of restrictions in addition to the above:
1. Migrated usernames can only contain lowercase alphanumeric characters, underscores (`_`), and periods (`.`). Uppercase characters, spaces, dashes (`-`), and other special characters are not allowed.
2. Migrated usernames cannot have two or more consecutive periods (`..`).
3. Migrated usernames are unique to each user, and no two users can share the same username.
There are other rules and restrictions not shared here for the sake of spam and abuse mitigation, but the majority of users won't encounter them. It's important to properly handle all error messages returned by Discord when editing or updating names.
### Unique Usernames
Discord's username system is changing. Discriminators are being removed and new, unique usernames (`@name`) and display names are being introduced. Internally, this migration is referred to as "pomelo". You can read more details about how the changes to the username system affect user accounts in the [general Help Center article](https://dis.gd/usernames). To learn how it impacts bots specifically, you can read the [Developer Help Center article](https://dis.gd/app-usernames).
A user's legacy `username#discriminator` tag will still be usable to [send friend requests](/resources/relationships#send-friend-request), and will be available as a [profile badge](#profile-badge-structure) for migrated users.
#### Identifying Migrated Users
The value of a single zero (`0`) in the [`discriminator` field on the user object](#user-object) indicates that the user has ~~been pommeled~~ migrated to the new username system. Note that the discriminator for migrated users will _not_ be 4-digits like a standard discriminator (it is `0`, not `0000`). The value of the `username` field will become the migrated user's unique username.
#### Migrating
~~Users can only migrate their account to pomelo if they are in the rollout. A user is in the rollout if they have `pomelo` in the [`disclose` field on the Ready Supplemental event](/gateway/gateway-events#ready-supplemental) and are [in the `2023-03_pomelo` user experiment](/topics/experiments#user-experiments).~~
Migration is now complete and all non-migrated users have been automatically assigned a unique username.
To migrate, users should first [check if the username they want is available](#get-unique-username-eligibility), and then [migrate their account to that username](#create-unique-username). If the username they want is not available, they can [get a list of suggested usernames](#get-unique-username-suggestions) to choose from.
#### Display Names
As part of unique usernames, user accounts can define a non-unique display name. This value is a new nullable `global_name` field with a max length of 32 characters.
#### Default Avatars
For users with migrated accounts, default avatar URLs will be based on the user ID instead of the discriminator. The URL can be calculated using `(user_id >> 22) % 6`. For non-migrated accounts, the URL can be calculated using `discriminator % 5`.
### User Object
###### User Structure
| Field | Type | Description |
| ---------------------------- | ------------------------------------------------------------------------ | --------------------------------------------------------------------------------------------------------------- |
| id | snowflake | The ID of the user |
| username ^6^ | string | The user's username, may be unique across the platform (2-32 characters) |
| discriminator ^6^ | string | The user's stringified 4-digit Discord tag |
| global_name ^6^ | ?string | The user's display name (1-32 characters) |
| avatar | ?string | The user's [avatar hash](/reference#cdn-formatting) |
| avatar_decoration_data | ?[avatar decoration data](#avatar-decoration-data-object) object | The user's [avatar decoration](https://support.discord.com/hc/en-us/articles/13410113109911-Avatar-Decorations) |
| collectibles? | ?[collectibles](#collectibles-object) object | The user's equipped collectibles |
| display_name_styles? | ?[display name style](#display-name-style-structure) object | The user's display name style |
| primary_guild? | ?[primary guild](#primary-guild-structure) object | The primary guild of the user |
| linked_users ^1^ ^3^ | array[[linked user](/resources/family-center#linked-user-object) object] | The linked users connected to the account via [Family Center](/resources/family-center) |
| bot? | boolean | Whether the user is a bot account |
| system? | boolean | Whether the user is an official Discord System user (part of the urgent message system) |
| mfa_enabled | boolean | Whether the user has multi-factor authentication enabled on their account |
| nsfw_allowed? ^1^ | ?boolean | Whether the user is allowed to see NSFW content, `null` if not yet known |
| age_verification_status ^1^ | integer | The [age verification status](#age-verification-status) of the user |
| pronouns? ^1^ ^4^ | string | The user's pronouns (max 40 characters) |
| bio ^1^ | string | The user's bio (max 190 characters) |
| banner | ?string | The user's [banner hash](/reference#cdn-formatting) |
| accent_color | ?integer | The user's banner color encoded as an integer representation of a hexadecimal color code |
| locale? ^3^ | string | The [language option](/reference#locales) chosen by the user |
| verified ^2^ | boolean | Whether the email on this account has been verified |
| email ^2^ | ?string | The user's email address |
| phone? ^1^ | ?string | The user's E.164-formatted phone number |
| premium **(deprecated)** ^4^ | boolean | Whether the user is subscribed to Nitro |
| premium_type | integer | The [type of premium (Nitro) subscription](#premium-type) on a user's account |
| premium_state? ^4^ | [premium state](#premium-state-structure) object | The user's premium state |
| personal_connection_id? | snowflake | The ID of the user's personal, non-employee user account |
| flags ^1^ | integer | The [flags](#user-flags) on a user's account |
| public_flags? | integer | The public [flags](#user-flags) on a user's account |
| purchased_flags? ^1^ | integer | The [purchased flags](#purchased-flags) on a user's account |
| premium_usage_flags? ^1^ | integer | The [premium usage flags](#premium-usage-flags) on a user's account |
| desktop? ^1^ ^4^ | boolean | Whether the user has used the desktop client before |
| mobile? ^1^ ^4^ | boolean | Whether the user has used the mobile client before |
| has_bounced_email? ^1^ | boolean | Whether the user's email has failed to deliver and is no longer valid |
| authenticator_types? ^3^ | array[integer] | The [types of multi-factor authenticators](#authenticator-type) the user has enabled |
| analytics_token ^1^ ^5^ | string | The token used for analytical tracking requests |
^1^ Not included when fetching a user via OAuth2.
^2^ Not included when fetching a user via OAuth2 without the `email` scope.
^3^ Not included in the user object returned in the [Ready event](/gateway/gateway-events#ready).
^4^ Only included in the user object returned in the [Ready event](/gateway/gateway-events#ready).
^5^ Only included when when fetched from the [Get Current User](/resources/user#get-current-user) endpoint with `with_analytics_token` set to `true`.
^6^ See the [section on Discord's new username system](#unique-usernames) for more information.
###### Partial User Structure
| Field | Type | Description |
| ----------------------- | ---------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------- |
| id | snowflake | The ID of the user |
| username ^1^ | string | The user's username, may be unique across the platform (2-32 characters) |
| discriminator ^1^ | string | The user's stringified 4-digit Discord tag |
| global_name? ^1^ | ?string | The user's display name (1-32 characters) |
| avatar | ?string | The user's [avatar hash](/reference#cdn-formatting) |
| avatar_decoration_data? | ?[avatar decoration data](#avatar-decoration-data-object) object | The user's [avatar decoration](https://support.discord.com/hc/en-us/articles/13410113109911-Avatar-Decorations) |
| collectibles? | ?[collectibles](#collectibles-object) object | The user's equipped collectibles |
| display_name_styles? | ?[display name style](#display-name-style-structure) object | The user's display name style |
| primary_guild? | ?[primary guild](#primary-guild-structure) object | The primary guild of the user |
| bot? | boolean | Whether the user is a bot account |
| system? | boolean | Whether the user is an official Discord System user (part of the urgent message system) |
| banner? ^2^ | ?string | The user's [banner hash](/reference#cdn-formatting) |
| accent_color? ^2^ | ?integer | The user's banner color encoded as an integer representation of a hexadecimal color code |
| public_flags? | integer | The public [flags](#user-flags) on a user's account |
^1^ See the [section on Discord's new username system](#unique-usernames) for more information.
^2^ Only guaranteed to be included when fetched through the [Get User](#get-user) and [Get User Profile](#get-user-profile) endpoints. May be included in data received through other API endpoints.
^3^ Only guaranteed to be included when fetched through the [Get User](#get-user) endpoint or the [`author` field on the message object](/resources/message#message-object). May be included in data received through other API endpoints.
###### Primary Guild Structure
| Field | Type | Description |
| --------------------- | ---------- | ----------------------------------------------------- |
| identity_enabled ^1^ | ?boolean | Whether the user is displaying their guild tag |
| identity_guild_id ^2^ | ?snowflake | The ID of the guild |
| tag ^1^ | ?string | The user's guild tag (max 4 characters) |
| badge ^1^ | ?string | The [guild tag badge hash](/reference#cdn-formatting) |
^1^ This field is `null` when a user has not reaffirmed their identity after a tag change.
^2^ Only populated for users with `identity_enabled` not set to `false`.
###### Premium State Structure
| Field | Type | Description |
| -------------------------------- | ------- | ------------------------------------------------------------------------------ |
| premium_source | integer | The [source of the premium subscription](#premium-source) |
| premium_subscription_type | integer | The [type of premium subscription](#premium-subscription-type) |
| premium_subscription_group_role? | integer | The [role in the premium subscription group](#premium-subscription-group-role) |
###### Premium Source
| Value | Name | Description |
| ----- | ------------------ | -------------------------------------------- |
| 1 | SUBSCRIPTION | User has an active premium subscription |
| 2 | FRACTIONAL_PREMIUM | User has a fractional premium subscription |
| 3 | REVERSE_TRIAL | User is on a reverse trial for premium |
| 4 | SUBSCRIPTION_GROUP | User is part of a premium subscription group |
###### Premium Subscription Type
| Value | Name | Description |
| ----- | ---------- | ----------------------------------------- |
| 1 | BOOST_ONLY | User only has premium guild subscriptions |
| 2 | TIER_0 | User has [Nitro basic](#premium-type) |
| 3 | TIER_1 | User has [Nitro classic](#premium-type) |
| 4 | TIER_2 | User has [Nitro](#premium-type) |
###### Premium Subscription Group Role
| Value | Name | Description |
| ----- | ------- | ---------------------------------------- |
| 1 | PRIMARY | User is the primary account in the group |
| 2 | MEMBER | User is a member of the group |
###### User Flags
| Value | Name | Description | Public |
| ------------- | ------------------------------------ | ---------------------------------------------------------------------------------------------------------------------------------------- | ------- |
| 1 \<\< 0 | STAFF | Discord Staff | Yes |
| 1 \<\< 1 | PARTNER | Partnered Server Owner | Yes |
| 1 \<\< 2 | HYPESQUAD | HypeSquad Events | Yes |
| 1 \<\< 3 | BUG_HUNTER_LEVEL_1 | Level 1 Discord Bug Hunter | Yes |
| 1 \<\< 4 | MFA_SMS | SMS enabled as a multi-factor authentication backup | No |
| 1 \<\< 5 | PREMIUM_PROMO_DISMISSED | User has dismissed the current premium (Nitro) promotion | No |
| 1 \<\< 6 | HYPESQUAD_ONLINE_HOUSE_1 | HypeSquad Bravery | Yes |
| 1 \<\< 7 | HYPESQUAD_ONLINE_HOUSE_2 | HypeSquad Brilliance | Yes |
| 1 \<\< 8 | HYPESQUAD_ONLINE_HOUSE_3 | HypeSquad Balance | Yes |
| 1 \<\< 9 | PREMIUM_EARLY_SUPPORTER | Early Premium (Nitro) Supporter | Yes |
| 1 \<\< 10 | TEAM_PSEUDO_USER | User is a [Team](/resources/team) | Yes |
| 1 \<\< 11 | IS_HUBSPOT_CONTACT | User is registered on Discord's [HubSpot](https://www.hubspot.com/) customer platform, used for official Discord programs (e.g. partner) | No ^1^ |
| ~~1 \<\< 12~~ | ~~SYSTEM~~ | ~~User is a system user (i.e. official Discord account)~~ | ~~Yes~~ |
| 1 \<\< 13 | HAS_UNREAD_URGENT_MESSAGES | User has unread urgent system messages; an urgent message is one sent from Trust and Safety | No |
| 1 \<\< 14 | BUG_HUNTER_LEVEL_2 | Level 2 Discord Bug Hunter | Yes |
| 1 \<\< 15 | UNDERAGE_DELETED | User is scheduled for deletion for being under the minimum required age | No ^1^ |
| 1 \<\< 16 | VERIFIED_BOT | Verified Bot | Yes |
| 1 \<\< 17 | VERIFIED_DEVELOPER | Early Verified Bot Developer | Yes |
| 1 \<\< 18 | CERTIFIED_MODERATOR | Moderator Programs Alumni | Yes |
| 1 \<\< 19 | BOT_HTTP_INTERACTIONS | Bot uses only HTTP interactions and is shown in the online member list | Yes |
| 1 \<\< 20 | SPAMMER | User is marked as a spammer and has their messages collapsed in the UI | Yes |
| ~~1 \<\< 21~~ | ~~DISABLE_PREMIUM~~ | ~~User has manually disabled premium (Nitro) features~~ | ~~No~~ |
| ~~1 \<\< 22~~ | ~~ACTIVE_DEVELOPER~~ | ~~[Active Developer](https://support-dev.discord.com/hc/articles/10113997751447)~~ | ~~Yes~~ |
| 1 \<\< 23 | PROVISIONAL_ACCOUNT | User is a provisional account used with the social layer integration | Yes |
| 1 \<\< 33 | HIGH_GLOBAL_RATE_LIMIT | User has their global ratelimit raised to 1,200 requests per second | No ^1^ |
| 1 \<\< 34 | DELETED | User's account is deleted | No ^1^ |
| 1 \<\< 35 | DISABLED_SUSPICIOUS_ACTIVITY | User's account is disabled for suspicious activity and must reset their password to regain access | No ^1^ |
| 1 \<\< 36 | SELF_DELETED | User deleted their own account | No ^1^ |
| 1 \<\< 37 | PREMIUM_DISCRIMINATOR | User has a premium (Nitro) custom discriminator | No ^1^ |
| 1 \<\< 38 | USED_DESKTOP_CLIENT | User has used the desktop client | No ^1^ |
| 1 \<\< 39 | USED_WEB_CLIENT | User has used the web client | No ^1^ |
| 1 \<\< 40 | USED_MOBILE_CLIENT | User has used the mobile client | No ^1^ |
| 1 \<\< 41 | DISABLED | User's account is disabled | No ^1^ |
| 1 \<\< 43 | HAS_SESSION_STARTED | User has started at least one Gateway session and is now eligible to send messages | No ^1^ |
| 1 \<\< 44 | QUARANTINED | User is quarantined and cannot create DMs or accept invites | No |
| 1 \<\< 47 | PREMIUM_ELIGIBLE_FOR_UNIQUE_USERNAME | User is eligible for early access to [unique usernames](#create-unique-username) | No ^1^ |
| 1 \<\< 50 | COLLABORATOR | User is a collaborator and is considered staff | No |
| 1 \<\< 51 | RESTRICTED_COLLABORATOR | User is a restricted collaborator and is considered staff | No |
^1^ Not exposed to the API, can only be found in [user data harvests](#harvest-object).
###### Purchased Flags
Purchased flags denote what premium items a user has ever purchased. Visit the [Nitro](https://discord.com/nitro) page to learn more about the premium plans currently offered.
| Value | Name | Description |
| -------- | ---------------- | -------------------------------- |
| 1 \<\< 0 | NITRO_CLASSIC | User has purchased Nitro classic |
| 1 \<\< 1 | NITRO | User has purchased regular Nitro |
| 1 \<\< 2 | GUILD_BOOST | User has purchased a guild boost |
| 1 \<\< 3 | NITRO_BASIC | User has purchased Nitro basic |
| 1 \<\< 4 | ON_REVERSE_TRIAL | User has a reverse trial active |
###### Premium Usage Flags
Premium usage flags denote what premium (Nitro) features a user has utilized.
| Value | Name | Description |
| -------- | --------------------- | ---------------------------------------- |
| 1 \<\< 0 | PREMIUM_DISCRIMINATOR | User has utilized premium discriminators |
| 1 \<\< 1 | ANIMATED_AVATAR | User has utilized animated avatars |
| 1 \<\< 2 | PROFILE_BANNER | User has utilized profile banners |
###### Premium Type
Premium types denote the level of premium a user has. Visit the [Nitro](https://discord.com/nitro) page to learn more about the premium plans currently offered.
| Value | Name | Description |
| ----- | --------------------- | ------------- |
| 0 | NONE **(deprecated)** | No Nitro |
| 1 | TIER_1 | Nitro Classic |
| 2 | TIER_2 | Nitro |
| 3 | TIER_3 | Nitro Basic |
###### Age Verification Status
| Value | Name | Description |
| ----- | -------------- | ---------------------------------------------------- |
| 1 | UNVERIFIED | User has not verified their age |
| 2 | VERIFIED_TEEN | User is a verified teenager |
| 3 | VERIFIED_ADULT | User is a verified adult |
| 4 | INFERRED_ADULT | User is inferred to be an adult via internal metrics |
###### Required Action Type
Denotes an action Discord requires the user to take before they can continue using the platform. In some cases, multiple actions may be required, and the user must complete all of them before they can continue using Discord.
| Value | Description | Action |
| -------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| AGREEMENTS | The user must re-indicate their agreement of Discord's terms of service and privacy policy; this does not limit the user from using Discord | [Reaffirm agreements](#modify-user-agreements) |
| ~~REQUIRE_CAPTCHA~~ | ~~The user must complete a reCAPTCHA challenge~~ | ~~[Complete a reCAPTCHA challenge](#verify-user-captcha)~~ |
| REQUIRE_VERIFIED_EMAIL | The user must add and verify an email address to their account | [Add an email address](/topics/email-verification#adding-an-email-address) |
| REQUIRE_REVERIFIED_EMAIL | The user must reverify their existing email address | [Reverify your email address](/topics/email-verification#reverifying-your-email-address) |
| REQUIRE_VERIFIED_PHONE | The user must add a phone number to their account | [Add a phone number](/topics/phone-verification#adding-a-phone-number) |
| REQUIRE_REVERIFIED_PHONE | The user must reverify their existing phone number | [Reverify your phone number](/topics/phone-verification#reverifying-your-phone-number) |
| ~~REQUIRE_VERIFIED_PHONE_THEN_EMAIL~~ | ~~The user must add a phone number to their account and then add and verify an email address to their account~~ | ~~[Add a phone number](/topics/phone-verification#adding-a-phone-number) and [add an email address](/topics/email-verification#adding-an-email-address)~~ |
| REQUIRE_VERIFIED_EMAIL_OR_VERIFIED_PHONE | The user must add and verify an email address to their account or add a phone number to their account | [Add an email address](/topics/email-verification#adding-an-email-address) or [add a phone number](/topics/phone-verification#adding-a-phone-number) |
| REQUIRE_REVERIFIED_EMAIL_OR_VERIFIED_PHONE | The user must reverify their existing email address or add a phone number to their account | [Reverify your email address](/topics/email-verification#reverifying-your-email-address) or [add a phone number](/topics/phone-verification#adding-a-phone-number) |
| REQUIRE_VERIFIED_EMAIL_OR_REVERIFIED_PHONE | The user must add and verify an email address to their account or reverify their existing phone number | [Add an email address](/topics/email-verification#adding-an-email-address) or [reverify your phone number](/topics/phone-verification#reverifying-your-phone-number) |
| REQUIRE_REVERIFIED_EMAIL_OR_REVERIFIED_PHONE | The user must reverify their existing email address or reverify their existing phone number | [Reverify your email address](/topics/email-verification#reverifying-your-email-address) or [reverify your phone number](/topics/phone-verification#reverifying-your-phone-number) |
###### Example User
```json
{
"id": "80351110224678912",
"username": "nelly",
"global_name": "Nelly",
"avatar": "8342729096ea3675442027381ff50dfe",
"discriminator": "0",
"public_flags": 64,
"flags": 96,
"purchased_flags": 10,
"premium_usage_flags": 4,
"banner": "06c16474723fe537c283b8efa61a30c8",
"accent_color": null,
"bio": "I'm not a bot!",
"locale": "en-US",
"nsfw_allowed": true,
"mfa_enabled": true,
"premium_type": 2,
"avatar_decoration_data": {
"sku_id": "1144058844004233369",
"asset": "a_fed43ab12698df65902ba06727e20c0e",
"expires_at": null
},
"email": "nelly@discord.com",
"verified": true,
"phone": "+18885940085",
"authenticator_types": [1, 2, 3],
"primary_guild": {
"identity_guild_id": "80351110224678913",
"identity_enabled": true,
"tag": "MEOW",
"badge": "7d1734ae5a615e82bc7a4033b98fade8"
}
}
```
###### Example Partial User
```json
{
"id": "80351110224678912",
"username": "nelly",
"avatar": "8342729096ea3675442027381ff50dfe",
"discriminator": "0",
"public_flags": 64,
"banner": "06c16474723fe537c283b8efa61a30c8",
"accent_color": 16711680,
"global_name": "Nelly",
"avatar_decoration_data": {
"sku_id": "1144058844004233369",
"asset": "a_fed43ab12698df65902ba06727e20c0e",
"expires_at": null
},
"primary_guild": {
"identity_guild_id": "80351110224678913",
"identity_enabled": true,
"tag": "MEOW",
"badge": "7d1734ae5a615e82bc7a4033b98fade8"
}
}
```
### Avatar Decoration Data Object
A user's active avatar decoration.
###### Avatar Decoration Data Structure
| Field | Type | Description |
| ---------- | --------- | ------------------------------------------------------------ |
| asset | string | The [avatar decoration hash](/reference#cdn-formatting) |
| sku_id | snowflake | The ID of the avatar decoration's SKU |
| expires_at | ?integer | Unix timestamp of when the current avatar decoration expires |
###### Example Avatar Decoration Data
```json
{
"sku_id": "1144058844004233369",
"asset": "a_fed43ab12698df65902ba06727e20c0e",
"expires_at": 1740124800
}
```
### Collectibles Object
A user's equipped collectibles, excluding avatar decorations and profile effects.
###### Collectibles Structure
| Field | Type | Description |
| --------- | --------------------------------------------------- | --------------------------------------------------------------------------------------------------- |
| nameplate | ?[nameplate data](#nameplate-data-structure) object | The user's [nameplate](https://support.discord.com/hc/en-us/articles/30408457944215-Nameplates-FAQ) |
###### Nameplate Data Structure
| Field | Type | Description |
| ---------- | --------- | -------------------------------------------------------------------------------- |
| asset | string | The [nameplate asset path](/reference#cdn-formatting) |
| sku_id | snowflake | The ID of the nameplate's SKU |
| label | string | The nameplate's accessibility description |
| palette | string | The nameplate's [color palette](/resources/collectibles#nameplate-color-palette) |
| expires_at | ?integer | Unix timestamp of when the current nameplate expires |
###### Example Collectibles Object
```json
{
"nameplate": {
"asset": "nameplates/nameplatetest/angel/",
"palette": "bubble_gum",
"label": "COLLECTIBLES_NAMEPLATETEST_ANGEL_A11Y",
"sku_id": "1344802364934062152",
"expires_at": null
}
}
```
### Display Name Style Object
How a user's name gets displayed, such as font, colors, gradient, glow.
###### Display Name Style Structure
| Field | Type | Description |
| --------- | -------------- | ---------------------------------------------------------------------------------------------- |
| font_id | integer | The [font](#display-name-font) to use |
| effect_id | integer | The [effect](#display-name-effect) to use |
| colors | array[integer] | The colors to use encoded as an array of integers representing hexadecimal color codes (max 2) |
###### Display Name Font
| Value | Name | Display Name | Description |
| ----- | -------------------------- | ------------ | -------------------------------------------------------------------- |
| 11 | DEFAULT | gg Sans | Default font (gg Sans) |
| 1 | BANGERS **(deprecated)** | N/A | [Bangers](https://fonts.google.com/specimen/Bangers) |
| 2 | BIO_RHYME **(deprecated)** | N/A | [BioRhyme](https://fonts.google.com/specimen/BioRhyme) |
| 3 | CHERRY_BOMB | Sakura | [Cherry Bomb One](https://fonts.google.com/specimen/Cherry+Bomb+One) |
| 4 | CHICLE | Jellybean | [Chicle](https://fonts.google.com/specimen/Chicle) |
| 5 | COMPAGNON **(deprecated)** | N/A | [Compagnon](https://velvetyne.fr/fonts/compagnon/) |
| 6 | MUSEO_MODERNO | Modern | [MuseoModerno](https://fonts.google.com/specimen/MuseoModerno) |
| 7 | NEO_CASTEL | Medieval | [Néo-Castel](https://maxlilllo.gumroad.com/l/neo-castel) |
| 8 | PIXELIFY | 8Bit | [Pixelify Sans](https://fonts.google.com/specimen/Pixelify+Sans) |
| 9 | RIBES **(deprecated)** | N/A | [Ribes](https://www.collletttivo.it/typefaces/ribes) |
| 10 | SINISTRE | Vampyre | [Sinistre](https://www.collletttivo.it/typefaces/sinistre) |
| 12 | ZILLA_SLAB | Tempo | [Zilla Slab](https://fonts.google.com/specimen/Zilla+Slab) |
| 13 | PLAYPEN_SANS | Monkey Bars | [Playpen Sans](https://fonts.google.com/specimen/Playpen+Sans) |
| 14 | ORBITRON | Mainframe | [Orbitron](https://fonts.google.com/specimen/Orbitron) |
| 15 | NEW_ROCKER | Headbang | [New Rocker](https://fonts.google.com/specimen/New+Rocker) |
| 16 | KALAM | Journal | [Kalam](https://fonts.google.com/specimen/Kalam?preview.script=Latn) |
###### Display Name Effect
| Value | Name | Description |
| ----- | -------- | ---------------------------------------------- |
| 1 | SOLID | Displays the first color provided |
| 2 | GRADIENT | Two color gradient |
| 3 | NEON | Glow around the name |
| 4 | TOON | Subtle vertical gradient and stroke |
| 5 | POP | Colored dropshadow |
| 6 | GLOW | Alternate gradient style |
| 7 | PRISM | Scrolling five color gradient |
| 8 | GUMMY | Four color pattern, letters squash and stretch |
| 1001 | TEST_1 | Falls back to solid |
| 1002 | TEST_2 | Falls back to solid |
| 1003 | TEST_3 | Falls back to solid |
| 1004 | TEST_4 | Falls back to solid |
### Profile Metadata Object
A user's profile metadata.
###### Profile Metadata Structure
| Field | Type | Description |
| ------------------------------------------------ | --------------------------------------------------- | --------------------------------------------------------------------------------------------------------- |
| guild_id? | snowflake | The guild ID this profile applies to, if it is a guild profile |
| pronouns | string | The user's pronouns (max 40 characters) |
| bio? | string | The user's bio (max 190 characters) |
| banner? | ?string | The user's [banner hash](/reference#cdn-formatting) |
| accent_color? ^1^ | ?integer | The user's banner color encoded as an integer representation of a hexadecimal color code |
| theme_colors? | ?array[integer, integer] | The user's two theme colors encoded as an array of integers representing hexadecimal color codes |
| popout_animation_particle_type? **(deprecated)** | ?snowflake | The user's profile popout animation particle type |
| emoji? **(deprecated)** | ?[emoji](/resources/emoji#emoji-object) object | The user's profile emoji |
| profile_effect? | ?[profile effect](#profile-effect-structure) object | The user's [profile effect](https://support.discord.com/hc/en-us/articles/17828465914263-Profile-Effects) |
^1^ Not respected on guild profiles.
###### Profile Effect Structure
| Field | Type | Description |
| ---------- | --------- | --------------------------------------------------------- |
| id | snowflake | The ID of the profile effect |
| expires_at | ?integer | Unix timestamp of when the current profile effect expires |
###### Example Profile Metadata
```json
{
"guild_id": "80351110224678913",
"pronouns": "gnarp/gnap",
"bio": "👽 Professional alien",
"banner": null,
"accent_color": null,
"theme_colors": [1, 1],
"popout_animation_particle_type": null,
"emoji": {
"name": "meowlien",
"roles": [],
"id": "1090395834966880336",
"require_colons": true,
"managed": false,
"animated": false,
"available": true
},
"profile_effect": {
"id": "1139323097930027068",
"expires_at": 1740124800
}
}
```
### Authenticator Object
###### Authenticator Structure
| Field | Type | Description |
| --------- | ------------------ | ------------------------------------------------ |
| id | string | The ID of the authenticator |
| type | string | The [type of authenticator](#authenticator-type) |
| name | string | The name of the authenticator |
| last_used | ?ISO8601 timestamp | When the authenticator was last used |
| cred_id? | string | The WebAuthn credential ID |
###### Authenticator Type
Authenticator types represent enabled multi-factor authentication methods. See the [MFA verification documentation](/authentication#mfa-verification) for more information.
| Value | Name | Description |
| ----- | -------- | --------------------------------- |
| 1 | WEBAUTHN | WebAuthn credentials |
| 2 | TOTP | Time-based One-Time Password code |
| 3 | SMS | SMS code |
###### Example Authenticator
```json
{
"id": "1219430671865610261",
"type": 1,
"name": "AlienKey",
"last_used": null,
"cred_id": "rtUF6QazxhTeLnk9wHw1jJeePF8F206iKK4Joy8GgHM"
}
```
### Backup Code Object
A multi-factor authentication backup code.
###### Backup Code Structure
| Field | Type | Description |
| -------- | --------- | ------------------------------------- |
| user_id | snowflake | The ID of the user |
| code | string | The backup code |
| consumed | boolean | Whether the backup code has been used |
###### Example Backup Code
```json
{
"user_id": "852892297661906993",
"code": "zqs8oqxk",
"consumed": false
}
```
### Harvest Object
A user's data harvest.
This object is more verbose than needed as it is used internally by Discord employees to archive user data.
###### Harvest Structure
| Field | Type | Description |
| ---------------- | ------------------------------------------------------ | ----------------------------------------------------------------------------------------------------- |
| harvest_id | snowflake | The ID of the harvest |
| user_id | snowflake | The ID of the user being harvested |
| email | string | The email the harvest will be sent to |
| state | string | The [state](#harvest-state) of the harvest |
| status | integer | The [status](#harvest-status) of the harvest |
| created_at | ISO8601 timestamp | When the harvest was created |
| completed_at | ?ISO8601 timestamp | When the harvest was completed |
| polled_at | ?ISO8601 timestamp | When the harvest was last polled |
| backends | map[string, string] | The [state](#harvest-backend-state) of each [backend](#harvest-backend-internal-type) being harvested |
| updated_at | ISO8601 timestamp | When the harvest was last updated |
| shadow_run | boolean | Whether the harvest is a shadow run |
| harvest_metadata | [harvest metadata](#harvest-metadata-structure) object | Additional metadata about the harvest |
###### Example Harvest
```json
{
"harvest_id": "1319498748052639754",
"user_id": "852892297661906993",
"email": "alien@dolfi.es",
"state": "DELIVERED",
"status": 3,
"created_at": "2024-12-20T02:56:56.639579+00:00",
"completed_at": "2024-12-21T11:05:41.462828+00:00",
"polled_at": "2024-12-21T11:05:41.462828+00:00",
"backends": {
"zendesk": "EXTRACTED",
"ads": "EXTRACTED",
"users": "EXTRACTED",
"guilds": "EXTRACTED",
"hubspot": "EXTRACTED",
"messages": "EXTRACTED",
"analytics": "EXTRACTED",
"activities_e": "EXTRACTED",
"activities_w": "EXTRACTED"
},
"updated_at": "2024-12-21T11:05:41.462828+00:00",
"shadow_run": false,
"harvest_metadata": {
"user_is_staff": false,
"sla_email_sent": false,
"bypass_cooldown": false,
"is_provisional": false
}
}
```
###### Harvest Metadata Structure
| Field | Type | Description |
| ----------------- | -------------------- | ------------------------------------------------------------------------------------------------- |
| user_is_staff | boolean | Whether the user being harvested is a Discord employee |
| sla_email_sent | boolean | Whether an email has been sent informing the user that the archive is taking longer than expected |
| bypass_cooldown | boolean | Whether the harvest bypasses the cooldown period for requesting harvests |
| is_provisional? | boolean | Whether the user being harvested is a provisional account |
| backend_attempts? | map[string, integer] | The number of attempts made for each backend being harvested |
###### Harvest State
| Value | Description |
| ---------- | ------------------------------------------ |
| INCOMPLETE | The harvest is not yet complete |
| DELIVERED | The harvest has been delivered to the user |
| CANCELLED | The harvest has been cancelled |
###### Harvest Status
| Value | Name | Description |
| ----- | --------- | ---------------------------------------------- |
| 0 | QUEUED | The harvest is queued and has not been started |
| 1 | RUNNING | The harvest is currently running |
| 2 | FAILED | The harvest has failed |
| 3 | COMPLETED | The harvest has completed successfully |
| 4 | CANCELLED | The harvest has been cancelled |
###### Harvest Backend Internal Type
| Value | Description |
| ------------ | ------------------------------------------------------------------------------------------------------------- |
| users | All account information |
| analytics | Actions the user has taken in Discord |
| activities_e | First-party embedded activity information |
| activities_w | First-party embedded activity information |
| messages | All user messages |
| hubspot | Discord's [HubSpot](https://www.hubspot.com/) contact data, used for official Discord programs (e.g. partner) |
| guilds | All guilds the user is currently a member of |
| ads | Quest data |
| zendesk | Zendesk support tickets |
###### Harvest Backend State
| Value | Description |
| --------- | ----------------------------------- |
| INITIAL | The backend has not been processed |
| RUNNING | The backend is currently processing |
| EXTRACTED | The backend has been processed |
### User Survey Object
A user survey.
###### User Survey Structure
| Field | Type | Description |
| ------------------ | ------------------------- | ------------------------------------------------------------------------ |
| id | snowflake | The ID of the survey |
| key | snowflake | The ID of the survey |
| prompt | string | The title of the survey |
| cta | string | The call-to-action text |
| url | string | The URL to the survey |
| guild_requirements | array[string] | [User requirements](#survey-requirement-type) for the survey to be shown |
| guild_size | array[?integer, ?integer] | The guild member count requirements (min, max) |
| guild_permissions | array[string] | The [guild permissions bitwise value](/topics/permissions) requirements |
###### Survey Requirement Type
| Value | Description | Field |
| ----------------- | ------------------------------------------------------------------------------------------- | ------------------- |
| IS_OWNER | The user must be the owner of a guild | - |
| IS_ADMIN | The user must have the `ADMINISTRATOR` permission in any guild | - |
| IS_COMMUNITY | The user must be in a guild with the [`COMMUNITY` feature](/resources/guild#guild-features) | - |
| GUILD_SIZE | The user must be in a guild with a member count in a given range | `guild_size` |
| GUILD_SIZE_ALL | All guilds the user is in must have a member count in a given range | `guild_size` |
| IS_HUB | The user must be in a guild with the [`HUB` feature](/resources/guild#guild-features) | - |
| IS_VIEWING | The user must be currently viewing a guild | - |
| GUILD_PERMISSIONS | The user must have the given permissions in any guild | `guild_permissions` |
###### Example User Survey
```json
{
"id": "1301267751645483122",
"key": "1301267751645483122",
"prompt": "Share your experience with Discord",
"cta": "Take the survey!",
"url": "https://discord.sjc1.qualtrics.com/jfe/form/SV_123456",
"guild_requirements": [],
"guild_size": [null, null],
"guild_permissions": []
}
```
### User Identity Verification Object
An Identity Verification used for application verification.
###### User Identity Verification Structure
| Field | Type | Description |
| ---------------- | --------- | ------------------------------------------------------------------------------------- |
| id | snowflake | The ID for the team verification |
| status | number | The current [status of the identity verification](#user-identity-verification-status) |
| last_error | ?number | The [error code of the last verification attempt](#user-identity-verification-error) |
| redirect_url ^1^ | string | The Stripe identity verification URL to redirect the user to |
^1^ Only returned on newly-created identity verification attempts.
###### User Identity Verification Status
| Value | Name | Description |
| ----- | ---------------------- | ------------------------------------------------------------------- |
| 1 | REQUIRES_ACTION | User action is required to complete verification |
| 2 | PROCESSING | The verification is currently in progress |
| 3 | CANCELED | The verification was cancelled before completion |
| 4 | SUCCEEDED | The verification succeeded |
| 5 | MANUALLY_SUCCEEDED | The verification was manually approved by staff |
| 6 | DELETED | The verification was deleted |
| 7 | SUCCEEDED_GRACE_PERIOD | The verification is currently in a grace period before finalization |
###### User Identity Verification Error
| Value | Name | Description |
| ----- | ---------------------------------------- | ---------------------------------------------------------------------------------- |
| 1 | CONSENT_DECLINED | User declined consent at the beginning of verification |
| 2 | UNVERIFIED | Verification was aborted or Stripe failed to verify the user's identity |
| 3 | DEVICE_UNSUPPORTED | The device used for verification is unsupported |
| 4 | VERIFICATION_DOCUMENT_EXPIRED | The submitted document has expired |
| 5 | VERIFICATION_DOCUMENT_INVALID | The submitted document is invalid |
| 6 | VERIFICATION_UNEXPECTED_DOCUMENT_COUNTRY | The submitted document has an unexpected issuing country |
| 7 | VERIFICATION_UNEXPECTED_DOCUMENT_TYPE | The submitted document has an unexpected document type |
| 8 | VERIFICATION_SCAN_NOT_READABLE | The scan is not readable by the verification system |
| 9 | VERIFICATION_SCAN_MISSING_BACK | The scan is missing the back side of the document |
| 10 | VERIFICATION_SCAN_ID_TYPE_NOT_SUPPORTED | The scan contains a document type that is not supported by the verification system |
| 11 | VERIFICATION_SCAN_CORRUPT | The scan is incomplete or corrupted |
| 12 | VERIFICATION_SCAN_FAILED_COPY | The verification system determined the scan is a copy of the original document |
| 13 | VERIFICATION_SCAN_MANIPULATED_DOCUMENT | The verification system determined the document was manipulated or damaged with |
| 14 | VERIFICATION_SCAN_FAILED_GRAYSCALE | The scan failed due to the uploaded document having been uploaded in grayscale |
| 15 | VERIFICATION_UNDER_SUPPORTED_AGE | The user is under the minimum supported age for verification |
## Endpoints
Get Current User
Returns the [user](#user-object) object of the requester's account.
###### Query String Params
| Field | Type | Description |
| --------------------- | ------- | ---------------------------------------------------------------------- |
| with_analytics_token? | boolean | Whether to include the analytics token in the response (default false) |
Modify Current User
Modifies the requester's user account settings. Returns a [user](#user-object) object with an extra `token` field representing the user's new authorization token on success. Fires a [User Update](/gateway/gateway-events#user-update) Gateway event.
At least one active Gateway session is required to modify a user account's username.
###### JSON Params
| Field | Type | Description |
| ------------------------- | ---------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| username? ^5^ | string | The user's username (2-32 characters) |
| discriminator? ^5^ | string | The user's stringified 4-digit Discord tag; can only be changed for users with an applicable premium plan, which triggers a reroll after the subscription expires |
| global_name? ^5^ | ?string | The user's display name (1-32 characters) |
| avatar? | ?[image data](/reference#cdn-data) | The user's avatar; can be animated when the user has an applicable premium plan |
| avatar_description? | ?string | The description of the new user avatar, usually in the format "\{filename\}, added \{date\}" (max 1024 characters) |
| avatar_id? | string | The ID of the recent avatar to use |
| avatar_decoration_sku_id? | ?snowflake | The SKU ID of the user's avatar decoration |
| nameplate_sku_id? | ?snowflake | The SKU ID of the user's nameplate |
| display_name_font_id? | ?integer | The [display name font](#display-name-font) to use; can only be changed for premium users |
| display_name_effect_id? | ?integer | The [display name effect](#display-name-effect) to use; can only be changed for premium users |
| display_name_colors? | ?array[integer] | The display name colors to use encoded as an array of integers representing hexadecimal color codes (max 2); can only be changed for premium users |
| email? | string | The user's email address; if changing from a verified email, `email_token` must be provided |
| email_token? ^4^ | string | The user's email token from their previous email |
| pronouns? | ?string | The user's pronouns (max 40 characters) |
| bio? | ?string | The user's bio (max 190 characters) |
| banner? | ?[image data](/reference#cdn-data) | The user's banner; can only be changed for premium users |
| accent_color? | ?integer | The user's banner color encoded as an integer representation of a hexadecimal color code |
| flags? | integer | The user's [flags](#user-flags) (only `PREMIUM_PROMO_DISMISSED` and `HAS_UNREAD_URGENT_MESSAGES` can be set) |
| date_of_birth? ^2^ | ISO8601 timestamp | The user's date of birth; can only be set once |
| password? ^1^ | string | The user's current password; if the account does not have a password, this sets it |
| new_password? ^3^ | string | The user's new password (8-72 characters) |
| push_provider? ^6^ | string | The [push notification provider](/topics/push-notifications#push-notification-provider) of the device |
| push_token? ^6^ | string | The push notification token to register |
| push_voip_provider? ^6^ | string | The VOIP [push notification provider](/topics/push-notifications#push-notification-provider) of the device |
| push_voip_token? ^6^ | string | The VOIP push notification token to register |
^1^ Required for changing `username`, `discriminator`, `email`, `date_of_birth`, or `new_password`.
^2^ Setting this defines the `nsfw_allowed` field of the user based on whether they are over 18.
^3^ Changing the account password invalidates all active tokens. Don't fret though, as the `token` key in the response will be valid.
^4^ This value can be obtained by requesting a verification code as outlined in the [email verification documentation](/topics/email-verification#changing-your-email-address).
^5^ If using unique usernames, the `username` field must be unique across Discord, and `discriminator` cannot be changed. Else, the `username` and `discriminator` fields must be unique across Discord, and changing the username may cause the discriminator to be randomized. See the [section on Discord's new username system](#unique-usernames) for more information. See the [Usernames and Nicknames section](#usernames-and-nicknames) for information on username restrictions.
^6^ Mobile clients attach the device's push notification token to this request, since it returns a new authentication token. See [registering tokens](/topics/push-notifications#registering-tokens) for more information.
Modify Current User Account
Modifies the requester's user account settings. Returns a partial [user](#user-object) object on success. Fires a [User Update](/gateway/gateway-events#user-update) Gateway event.
This endpoint is only usable with an OAuth2 access token with the `account.global_name.update` scope.
###### JSON Params
| Field | Type | Description |
| ------------ | ------- | ----------------------------------------- |
| global_name? | ?string | The user's display name (1-32 characters) |
Report Meaningfully Online
Reports that the current user should be considered meaningfully online for friend online notifications. Returns a 204 empty response on success.
Clients should this after the current user's [status](/resources/presence#status-type) has remained `online` or `streaming` for 5 minutes,
if the user has the [`notify_friends_on_come_online` setting](/resources/user-settings-proto#notification-settings-structure) enabled. Clients should also maintain a 1 hour cooldown between successful reports.
List Recent Avatars
Returns the user's 6 most recent avatars.
###### Response Body
| Field | Type | Description |
| ------- | ----------------------------------------- | ------------------------------- |
| avatars | array[[avatar](#avatar-structure) object] | The recent avatars for the user |
###### Avatar Structure
| Field | Type | Description |
| ------------ | ------- | ------------------------------------------------------ |
| id | string | The avatar ID |
| storage_hash | string | The [avatar hash](/reference#cdn-formatting) |
| description | ?string | The description specified when the avatar was uploaded |
###### Example Response
```json
{
"avatars": [
{
"id": "1357011390585507910",
"storage_hash": "212aed0ac14cf7804051218f99624a9f",
"description": "alien, added April 2, 2025 at 5:09 PM"
}
]
}
```
Delete Recent Avatar
Deletes a recent avatar for the user. Returns a 204 empty response on success.
Get User
Returns a partial [user](#user-object) object for a given user ID.
Get User Profile
Returns a user profile object for a given user ID.
This endpoint requires one of the following:
- The user is a bot
- The user shares a mutual guild with the current user
- The user is a friend of the current user
- The user is a friend suggestion of the current user
- The user has an outgoing friend request to the current user
- A valid [`join_request_id`](/resources/guild#guild-join-request-object) is provided
###### Query String Params
| Field | Type | Description |
| -------------------------- | --------- | -------------------------------------------------------------------------------------------------- |
| with_mutual_guilds? | boolean | Whether to include the mutual guilds of the user with the current user (default true) |
| with_mutual_friends? | boolean | Whether to include mutual friends the user has with the current user (default false) |
| with_mutual_friends_count? | boolean | Whether to include the number of mutual friends the user has with the current user (default false) |
| guild_id? | snowflake | The guild ID to get the user's member profile in |
| connections_role_id? | snowflake | The role ID to get the user's application role connection metadata in |
| join_request_id? | snowflake | The join request ID to use for the request |
| type? | string | The [profile analytics location](#profile-request-type) |
###### Profile Request Type
| Value | Description |
| -------------- | ----------------------------------- |
| popout | The profile popout |
| modal | The full profile modal |
| sidebar | The profile DM sidebar |
| account_popout | The current user's account popout |
| action_sheet | A user profile action sheet |
| you_screen | The current user's profile overview |
###### Response Body
| Field | Type | Description |
| ----------------------------- | ------------------------------------------------------------------------------------------------------ | ----------------------------------------------------------------------------- |
| application? | [profile application](#profile-application-structure) object | The bot's application profile |
| user | partial [user](#user-object) object | The user object, with an extra `bio` key denoting the user's bio |
| user_profile ^1^ | [profile metadata](#profile-metadata-object) object | The user's profile metadata |
| badges ^1^ | array[[profile badge](#profile-badge-structure) object] | The user's profile badges |
| guild_member? ^1^ | private [guild member](/resources/guild#guild-member-object) object | The guild member in the guild specified |
| guild_member_profile? ^1^ | [profile metadata](#profile-metadata-object) object | The guild member's profile in the guild specified |
| guild_badges ^1^ | array[[profile badge](#profile-badge-structure) objcet] | The guild member's guild-specific profile badges |
| widgets? ^1^ | array[[game widget](/resources/widgets#game-widget-object) object] | The user's game widgets |
| legacy_username? ^1^ ^2^ | ?string | The user's pre-migration `username#discriminator`, if applicable and shown |
| mutual_guilds? ^1^ | array[[mutual guild](#mutual-guild-structure) object] | The mutual guilds of the user with the current user |
| mutual_friends? ^1^ ^3^ | array[partial [user](#user-object) object] | The mutual friends the user has with the current user |
| mutual_friends_count? ^1^ ^3^ | integer | The number of mutual friends the user has with the current user |
| connected_accounts | array[partial [connection](/resources/connected-accounts#connection-object) object] | The user's public connected accounts |
| application_role_connections? | array[[application role connection](/resources/application#application-role-connection-object) object] | The user's application role connections for the role specified |
| premium_type ^1^ | ?integer | The [type of premium (Nitro) subscription](#premium-type) on a user's account |
| premium_since ^1^ | ?ISO8601 timestamp | The date the user's premium subscription started |
| premium_guild_since ^1^ | ?ISO8601 timestamp | The date the user's premium guild (boosting) subscription started |
| private? ^4^ | boolean | Whether the user's extended profile is hidden (default false) |
^1^ These fields are unexpectedly missing or `null` if the user has blocked the current user.
^2^ See the [section on Discord's new username system](#unique-usernames) for more information.
^3^ This will always be empty for bots, even if the user has mutual friends with it.
^4^ Private profiles will have `bio`, `pronouns`, `badges`, `guild_badges`, `connected_accounts`, `premium_since`, and `premium_guild_since` redacted.
###### Profile Application Structure
| Field | Type | Description |
| -------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------- |
| id | snowflake | The ID of the application |
| flags | integer | The [application's flags](/resources/application#application-flags) |
| verified | boolean | Whether the application is verified |
| storefront_available | boolean | Whether the application has monetization enabled (i.e. subscriptions or products available for purchase) |
| primary_sku_id? | snowflake | The ID of the application's primary SKU (game, application subscription, etc.) |
| install_params? | [application install params](/resources/application#application-install-params-object) object | The default in-app authorization link for the integration |
| integration_types_config? | map[integer, ?[application integration type configuration](/resources/application#application-integration-type-configuration-structure) object] | The configuration for each [integration type](/resources/application#application-integration-type) supported by the application |
| popular_application_command_ids? | array[snowflake] | The IDs of the application's most popular application commands (max 5) |
| custom_install_url? | string | The default custom authorization link for the integration |
###### Profile Badge Structure
For a list of known profile badges, refer to [this Gist](https://gist.github.com/XYZenix/c45156b7c883b5301c9028e39d71b479).
| Field | Type | Description |
| ----------- | ------ | -------------------------------------------------- |
| id | string | The reference ID of the badge |
| description | string | A description of the badge |
| icon | string | The badge's [icon hash](/reference#cdn-formatting) |
| link? | string | A link representing the badge |
###### Mutual Guild Structure
| Field | Type | Description |
| ----- | --------- | -------------------------------- |
| id | snowflake | The guild ID |
| nick | ?string | The user's nickname in the guild |
###### Example Response
```json
{
"user": {
"id": "852892297661906993",
"username": "alien",
"global_name": "Alien",
"avatar": "9d52298a3ad006da31ac66a86230d9f2",
"avatar_decoration_data": null,
"discriminator": "0",
"public_flags": 64,
"flags": 64,
"banner": "a_17a0757cf6121ccc07546de9bff3edb2",
"accent_color": null,
"bio": "👽 Professional smoothbrain",
"avatar_decoration_data": null,
"primary_guild": null
},
"connected_accounts": [
{
"type": "twitter",
"id": "123456",
"name": "discord",
"verified": true,
"metadata": {
"verified": "1",
"followers_count": "100000",
"statuses_count": "100000",
"created_at": "2016-01-01T00:00:00"
}
}
],
"premium_since": "2016-01-01T00:00:00.00+00:00",
"premium_type": 2,
"premium_guild_since": "2016-01-01T00:00:00.00+00:00",
"mutual_friends_count": 100,
"mutual_guilds": [
{
"id": "80351110224678913",
"nick": "Liena"
}
],
"guild_member": {
"avatar": null,
"communication_disabled_until": null,
"unusual_dm_activity_until": null,
"flags": 0,
"joined_at": "2016-01-01T00:00:00.00+00:00",
"nick": null,
"pending": false,
"premium_since": "2016-01-01T00:00:00.00+00:00",
"roles": [],
"user": {
"id": "852892297661906993",
"username": "alien",
"global_name": "Alien",
"avatar": "9d52298a3ad006da31ac66a86230d9f2",
"discriminator": "0",
"public_flags": 4194368,
"avatar_decoration_data": null,
"primary_guild": null
},
"bio": "👽 Professional alien",
"banner": null,
"mute": false,
"deaf": false
},
"application_role_connections": [
{
"platform_name": "Aliens United",
"platform_username": "Alien",
"metadata": {
"real": "1",
"certified": "1"
},
"application": {
"id": "891436233903964161",
"name": "Lightbulb",
"icon": "4d47160ec8c45f22e2bdbe75ac3e1bbd",
"description": "<:support_icon:853084466016288828> Imagine a bot.",
"summary": "",
"type": null,
"bot": {
"id": "891436233903964161",
"username": "lightbulb",
"global_name": "Lightbulb",
"avatar": "59fb354bf144ed784aa8bdef88d135bb",
"avatar_decoration_data": null,
"discriminator": "0",
"public_flags": 0,
"bot": true
}
},
"application_metadata": {
"real": {
"type": 7,
"key": "real",
"name": "Real",
"description": "Are you real alier?"
},
"certified": {
"type": 7,
"key": "certified",
"name": "Certified",
"description": "Are you certified alier?"
}
}
}
],
"user_profile": {
"bio": "👽 Professional smoothbrain",
"accent_color": null,
"pronouns": "gnarp/gnap",
"banner": "a_17a0757cf6121ccc07546de9bff3edb2",
"theme_colors": [1, 1],
"popout_animation_particle_type": 100000,
"emoji": null,
"profile_effect": {
"id": "1139323097930027068",
"expires_at": null
}
},
"guild_member_profile": {
"guild_id": "80351110224678913",
"pronouns": "",
"bio": "👽 Professional alien",
"banner": null,
"accent_color": null,
"theme_colors": [1, 1],
"popout_animation_particle_type": null,
"emoji": null,
"profile_effect": {
"id": "1139323097930027068",
"expires_at": null
}
}
}
```
Modify User Profile
Modifies the current user's profile. Returns the updated [profile metadata](#profile-metadata-object) object on success. Fires a [User Update](/gateway/gateway-events#user-update) Gateway event.
###### JSON Params
| Field | Type | Description |
| ------------------------------------------------ | ---------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------- |
| pronouns? | ?string | The user's pronouns (max 40 characters) |
| bio? | ?string | The user's bio (max 190 characters) |
| banner? | ?[image data](/reference#cdn-data) | The user's banner; can only be changed for premium users |
| accent_color? | ?integer | The user's banner color encoded as an integer representation of a hexadecimal color code |
| theme_colors? | ?array[integer, integer] | The user's two theme colors encoded as an array of integers representing hexadecimal color codes; can only be changed for premium users |
| popout_animation_particle_type? **(deprecated)** | ?snowflake | The user's profile popout animation particle type; can only be changed for premium users |
| emoji_id? **(deprecated)** | ?snowflake | The user's profile emoji ID; can only be changed for premium users |
| profile_effect_id? | ?snowflake | The user's profile effect ID; can only be changed for premium users |
List Mutual Relationships
Returns a list of partial [user](#user-object) objects that are friends with the user and current user.
This endpoint will always return an empty list for bots, even if the user has mutual friends with it.
Enable TOTP MFA
Enables TOTP multi-factor authentication for the current user. Fires a [User Update](/gateway/gateway-events#user-update) Gateway event.
The `secret` and `code` fields are optional as this endpoint is intended to be used to validate the user's password first before prompting the user to save the secret.
If the password is valid, the request will fail with a [`60005` JSON error code](/topics/errors#json-error-codes), prompting the client to continue with the setup flow.
###### JSON Params
| Field | Type | Description |
| -------- | ------ | ------------------------------------------------- |
| password | string | The user's password |
| secret? | string | The generated TOTP secret (32 characters) |
| code? | string | The TOTP code to verify the secret (6 characters) |
###### Response Body
| Field | Type | Description |
| ------------ | ------------------------------------------------ | ------------------------------------------- |
| token | string | The new authorization token for the session |
| backup_codes | array[[backup code](#backup-code-object) object] | MFA backup codes |
Disable TOTP MFA
Disables TOTP multi-factor authentication for the current user. Fires a [User Update](/gateway/gateway-events#user-update) Gateway event.
MFA cannot be disabled for administrators of guilds with published creator monetization listings.
###### Response Body
| Field | Type | Description |
| ----- | ------ | ------------------------------------------- |
| token | string | The new authorization token for the session |
Enable SMS MFA
Enables SMS multi-factor authentication for the current user. Requires that TOTP-based MFA is already enabled and the user has a verified phone number. Returns a 204 empty response on success. Fires a [User Update](/gateway/gateway-events#user-update) Gateway event.
###### JSON Params
| Field | Type | Description |
| -------- | ------ | ------------------- |
| password | string | The user's password |
Disable SMS MFA
Disables SMS multi-factor authentication for the current user. Returns a 204 empty response on success. Fires a [User Update](/gateway/gateway-events#user-update) Gateway event.
###### JSON Params
| Field | Type | Description |
| -------- | ------ | ------------------- |
| password | string | The user's password |
List WebAuthn Authenticators
Returns a list of [WebAuthn authenticator](#authenticator-object) objects for the current user.
Create WebAuthn Authenticator
Creates a WebAuthn authenticator for the current user. Fires [User Update](/gateway/gateway-events#user-update) and [Authenticator Create](/gateway/gateway-events#authenticator-create) Gateway events once the authenticator is created.
All parameters to this endpoint are optional as the intended flow is to first use it to generate a `ticket` and `challenge` that is then used to create the authenticator.
###### JSON Params
| Field | Type | Description |
| ----------- | ------ | ---------------------------------------------------------------------------------------------------------------------------------------------- |
| name? | string | The name of the authenticator (1-32 characters) |
| ticket? | string | The MFA ticket returned from the same endpoint |
| credential? | string | A stringified JSON object of the [public key credential response](https://developer.mozilla.org/en-US/docs/Web/API/PublicKeyCredential/toJSON) |
###### Response Body
| Field | Type | Description |
| ---------------- | ------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| ticket ^1^ | string | The MFA ticket |
| challenge ^1^ | string | The stringified JSON [public key credential request options](https://developer.mozilla.org/en-US/docs/Web/API/CredentialsContainer/get#web_authentication_api) challenge |
| id ^2^ | string | The ID of the authenticator |
| type ^2^ | string | The [type of authenticator](#authenticator-type) (always `WEBAUTHN`) |
| name ^2^ | string | The name of the authenticator |
| backup_codes ^2^ | array[[backup code](#backup-code-object) object] | MFA backup codes |
^1^ Only returned when no parameters are provided.
^2^ Only returned when parameters are provided.
###### Example Response (Ticket)
```json
{
"ticket": "ODUyODkyMjk3NjYxOTA2OTkz.H2Rpq0.WrhGhYEhM3lHUPN61xF6JcQKwVutk8fBvcoHjo",
"challenge": "{\"publicKey\":{\"challenge\":\"a8a1cHP7_zYheggFG68zKUkl8DwnEqfKvPE-GOMvhss\",\"timeout\":60000,\"rpId\":\"discord.com\",\"allowCredentials\":[{\"type\":\"public-key\",\"id\":\"izrvF80ogrfg9dC3RmWWwW1VxBVBG0TzJVXKOJl__6FvMa555dH4Trt2Ub8AdHxNLkQsc0unAGcn4-hrJHDKSO\"}],\"userVerification\":\"preferred\"}}"
}
```
###### Example Response (Authenticator)
```json
{
"id": "1219430671865610261",
"type": 1,
"name": "AlienKey",
"backup_codes": [
{
"user_id": "852892297661906993",
"code": "zqs8oqxk",
"consumed": false
}
]
}
```
Modify WebAuthn Authenticator
Modifies the given WebAuthn authenticator. Returns the updated [authenticator](#authenticator-object) object on success. Fires an [Authenticator Update](/gateway/gateway-events#authenticator-update) Gateway event.
###### JSON Params
| Field | Type | Description |
| ----- | ------ | ----------------------------------------------- |
| name? | string | The name of the authenticator (1-32 characters) |
Delete WebAuthn Authenticator
Deletes the given WebAuthn authenticator. Returns a 204 empty response on success. Fires [User Update](/gateway/gateway-events#user-update) and [Authenticator Delete](/gateway/gateway-events#authenticator-delete) Gateway events.
If this is the last remaining authenticator, this disables MFA for the current user. MFA cannot be disabled for administrators of guilds with published creator monetization listings.
Send Backup Codes Challenge
Sends an email to the current user with a verification code that allows them to view their backup codes. Returns a 204 empty response on success.
Each generated nonce can only be used once and expires after 30 minutes.
###### JSON Params
| Field | Type | Description |
| -------- | ------ | ------------------- |
| password | string | The user's password |
###### Response Body
| Field | Type | Description |
| ---------------- | ------ | ------------------------------------------------------------------- |
| nonce | string | The one-time verification nonce used to view the backup codes |
| regenerate_nonce | string | The one-time verification nonce used to regenerate the backup codes |
Get Backup Codes
Returns the user's MFA backup codes.
###### JSON Params
| Field | Type | Description |
| -------------- | ------- | ------------------------------------------------------------------------ |
| key ^1^ | string | The backup code verification key received in the email |
| nonce ^1^ ^2^ | string | The one-time verification nonce used to view/regenerate the backup codes |
| regenerate ^2^ | boolean | Whether to regenerate the backup codes |
^1^ This value can be obtained by requesting a verification code with the [Send Backup Codes Challenge](#send-backup-codes-challenge) endpoint.
^2^ The nonce used must correspond to the action being performed. Each action can only be performed once.
###### Response Body
| Field | Type | Description |
| ------------ | ------------------------------------------------ | ---------------- |
| backup_codes | array[[backup code](#backup-code-object) object] | MFA backup codes |
###### Example Response
```json
{
"backup_codes": [
{
"user_id": "852892297661906993",
"code": "zqs8oqxk",
"consumed": false
}
]
}
```
Disable User Account
Disables the current user's account. Invalidates all active tokens. Returns a 204 empty response on success.
###### JSON Params
| Field | Type | Description |
| -------- | ------ | ------------------- |
| password | string | The user's password |
Delete User Account
Marks the current user's account for deletion. Invalidates all active tokens. Returns a 204 empty response on success.
###### JSON Params
| Field | Type | Description |
| -------- | ------- | --------------------------- |
| password | ?string | The user's password, if any |
Verify User Captcha
Verifies a reCAPTCHA solution when needed by the [`REQUIRE_CAPTCHA` required action](#required-action-type). Returns a 204 empty response on success. Fires a [User Required Action Update](/gateway/gateway-events#user-required-action-update) Gateway event.
###### reCAPTCHA Site Key
```
6Lef5iQTAAAAAKeIvIY-DeexoO3gj7ryl9rLMEnn
```
###### JSON Params
| Field | Type | Description |
| ----------- | ------ | ---------------------- |
| captcha_key | string | The reCAPTCHA solution |
Modify User Agreements
Reaffirms the user's agreements to Discord's [Terms of Service](https://discord.com/terms) and [Privacy Policy](https://discord.com/privacy) when needed by the [`AGREEMENTS` required action](#required-action-type), which is assigned when a policy change occurs.
Returns a 204 empty response on success. Fires a [User Required Action Update](/gateway/gateway-events#user-required-action-update) Gateway event.
###### JSON Params
| Field | Type | Description |
| -------- | ------- | ----------------------------------------------- |
| terms? | boolean | Whether the user agrees to the Terms of Service |
| privacy? | boolean | Whether the user agrees to the Privacy Policy |
Get Unique Username Suggestions
Returns a suggested unique username string based on the current user's username.
This endpoint is used during the pomelo migration flow. The user must be in the rollout to use this endpoint. See the [section on Discord's new username system](#unique-usernames) for more information.
###### Response Body
| Field | Type | Description |
| -------- | ------ | ---------------------- |
| username | string | The suggested username |
###### Example Response
```json
{ "username": "gnarp.gnap" }
```
Get Unique Username Eligibility
Checks whether a unique username is available for the user to claim.
See the [Usernames and Nicknames section](/resources/user#usernames-and-nicknames) for more information on username restrictions.
###### JSON Params
| Field | Type | Description |
| -------- | ------ | --------------------- |
| username | string | The username to check |
###### Response Body
| Field | Type | Description |
| ----- | -------- | ----------------------------- |
| taken | ?boolean | Whether the username is taken |
###### Example Response
```json
{ "taken": true }
```
Create Unique Username
Claims a unique username for the user. Returns the updated [user](#user-object) object on success. Fires a [User Update](/gateway/gateway-events#user-update) Gateway event.
This endpoint is used during the pomelo migration flow. The user must be in the rollout to use this endpoint. See the [section on Discord's new username system](#unique-usernames) for more information.
###### JSON Params
| Field | Type | Description |
| -------- | ------ | --------------------- |
| username | string | The username to claim |
Set Guild Identity
Sets the current user's primary guild. Returns a [user](#user-object) object on success. Fires a [User Update](/gateway/gateway-events#user-update) Gateway event.
###### JSON Params
| Field | Type | Description |
| ------------------ | ---------- | --------------------------------------------------- |
| identity_enabled? | ?boolean | Whether the user has enabled the feature |
| identity_guild_id? | ?snowflake | The ID of the guild whose identity is being adopted |
List Recent Mentions
Returns a list of [message](/resources/message#message-object) objects that the current user has been mentioned in during the past 7 days.
###### Query String Params
| Field | Type | Description |
| --------- | --------- | -------------------------------------------------------------- |
| before? | snowflake | Get messages before this message ID |
| limit? | integer | Max number of messages to return (1-100, default 25) |
| guild_id? | snowflake | The guild to limit returned messages by |
| roles? | boolean | Whether to include role mentions (default true) |
| everyone? | boolean | Whether to include @everyone and @here mentions (default true) |
Delete Recent Mention
Acknowledges a message the current user has been mentioned in. Returns a 204 empty response on success. Fires a [Recent Mention Delete](/gateway/gateway-events#recent-mention-delete) Gateway event.
Get User Harvest
In an OAuth2 context, only provisional accounts are supported.
If it exists, returns a [harvest](#harvest-object) object representing the current user's most recent user data harvest request. Otherwise, returns a 204 empty response.
Create User Harvest
In an OAuth2 context, only provisional accounts are supported.
Creates a user data harvest request for the current user. Returns a [harvest](#harvest-object) object on success.
###### JSON Params
| Field | Type | Description |
| ------------- | -------------- | ---------------------------------------- |
| backends? ^1^ | ?array[string] | The types of user data being requested |
| email ^2^ | string | The email address to send the harvest to |
^1^ Invalid options are ignored. If the array contains no valid values, all data types are requested.
^2^ Only applicable in OAuth2 contexts.
###### Harvest Backend Type
See [the official support page](https://support.discord.com/hc/en-us/articles/360004957991) for more information.
| Value | Description |
| ------------ | -------------------------------------------- |
| Accounts | All account information |
| Ads | Quest data |
| Analytics | Actions the user has taken in Discord |
| Activities | First-party embedded activity information |
| Messages | All user messages |
| ~~Programs~~ | ~~Official Discord programs (e.g. partner)~~ |
| Servers | All guilds the user is currently a member of |
| Zendesk | Zendesk support tickets |
Get User Survey
Returns the current user's active survey.
The active survey should be cached and refetched at most once per day.
###### Query String Params
| Field | Type | Description |
| -------------------- | --------- | --------------------------------------------------------------------------- |
| disable_auto_seen? | boolean | Whether to prevent automatically marking the survey as seen (default false) |
| survey_override? ^1^ | snowflake | The ID of the survey to return |
^1^ Only usable by Discord employees.
###### Response Body
| Field | Type | Description |
| ------ | ------------------------------------------ | -------------------------------- |
| survey | ?[user survey](#user-survey-object) object | The user's active survey, if any |
Acknowledge User Survey
Marks a user survey as seen. Returns a 204 empty response on success.
When a survey is marked as seen, it will not be shown to the user again.
Get User Notes
Returns a mapping of user IDs to notes for the current user.
###### Example Response
```json
{
"852892297661906993": "This is a note",
"787017887877169173": "This is another note"
}
```
Get User Note
Returns the note for the given user.
###### Response Body
| Field | Type | Description |
| ------------ | --------- | ----------------------------------------------------------------- |
| note | string | The note (max 256 characters) |
| note_user_id | snowflake | The ID of the user the note is on |
| user_id | snowflake | The ID of the user who created the note (always the current user) |
###### Example Response
```json
{
"note": "This is a note",
"note_user_id": "787017887877169173",
"user_id": "852892297661906993"
}
```
Modify User Note
Sets the note for the given user. Returns a 204 empty response on success. Fires a [User Note Update](/gateway/gateway-events#user-note-update) Gateway event.
Users may have a maximum of 1,500 note entries on their account.
###### JSON Params
| Field | Type | Description |
| ----- | ------- | ----------------------------- |
| note | ?string | The note (max 256 characters) |
List User Affinities
Returns the current user's affinity scores for other users. Affinity scores are a measure of how likely a user is to be friends with another user.
User affinities that share a mutual guild are also [implicit relationships](/resources/relationships#relationship-object).
###### Response Body
| Field | Type | Description |
| --------------- | ------------------------------------------------------- | ------------------------------------------ |
| user_affinities | array[[user affinity](#user-affinity-structure) object] | The user's affinity scores for other users |
###### User Affinity Structure
| Field | Type | Description |
| -------- | --------- | ------------------ |
| user_id | snowflake | The user's ID |
| affinity | float | The affinity score |
List User Affinities v2
Returns more detailed user affinity scores for the current user.
###### Response Body
| Field | Type | Description |
| --------------- | ------------------------------------------------------------- | ------------------------------------------ |
| user_affinities | array[[user affinity v2](#user-affinity-v2-structure) object] | The user's affinity scores for other users |
###### User Affinity v2 Structure
| Field | Type | Description |
| -------------------------- | --------- | ----------------------------------------------------------- |
| other_user_id | snowflake | The user's ID |
| user_segment | string | The [usage segment](#user-segment-type) of the current user |
| other_user_segment | string | The [usage segment](#user-segment-type) of the user |
| is_friend | boolean | Whether the user is a friend |
| dm_probability | float | The affinity score for direct messaging |
| dm_rank | integer | The rank of the direct message affinity |
| vc_probability | float | The affinity score for voice calling |
| vc_rank | integer | The rank of the voice call affinity |
| server_message_probability | float | The affinity score for guild messaging |
| server_message_rank | integer | The rank of the guild message affinity |
| communication_probability | float | The overall communication affinity score |
| communication_rank | integer | The rank of the overall communication affinity |
###### User Segment Type
| Value | Description |
| ----------- | -------------------------------------------- |
| HFU_MAU | High Frequency User, Monthly Active User |
| NON_HFU_MAU | Non-High Frequency User, Monthly Active User |
| NON_MAU | Non-Monthly Active User |
###### Example User Affinities v2
```json
{
"other_user_id": "1001086404203389018",
"user_segment": "HFU_MAU",
"other_user_segment": "HFU_MAU",
"is_friend": true,
"dm_probability": 0.869776725769043,
"dm_rank": 1,
"vc_probability": 0.004896213300526142,
"vc_rank": 4,
"server_message_probability": 0.846949577331543,
"server_message_rank": 6,
"communication_probability": 0.573874172133704,
"communication_rank": 1
}
```
List Guild Affinities
Returns the current user's affinity scores for their joined guilds. Affinity scores are a measure of how likely a user is to interact with a guild.
###### Response Body
| Field | Type | Description |
| ---------------- | --------------------------------------------------------- | ------------------------------------------- |
| guild_affinities | array[[guild affinity](#guild-affinity-structure) object] | The user's affinity scores for their guilds |
###### Guild Affinity Structure
| Field | Type | Description |
| -------- | --------- | ------------------ |
| guild_id | snowflake | The guild's ID |
| affinity | float | The affinity score |
List Channel Affinities
Returns the current user's affinity scores for their participated channels. Affinity scores are a measure of how likely a user is to interact with a channel.
###### Response Body
| Field | Type | Description |
| ------------------ | ------------------------------------------------------------- | --------------------------------------------- |
| channel_affinities | array[[channel affinity](#channel-affinity-structure) object] | The user's affinity scores for their channels |
###### Channel Affinity Structure
| Field | Type | Description |
| ---------- | --------- | ------------------ |
| channel_id | snowflake | The channel's ID |
| affinity | float | The affinity score |
Get Tutorial
Returns the current user's [tutorial](/gateway/gateway-events#tutorial-structure) object, which contains information about the user's tutorial progress. If no tutorial is available, returns a 204 empty response instead.
Confirm Tutorial Indicator
Confirms the given [tutorial](/gateway/gateway-events#tutorial-structure) indicator. Returns a 204 empty response on success.
Suppress Tutorial
Suppresses all [tutorial](/gateway/gateway-events#tutorial-structure) indicators. Returns a 204 empty response on success.
Join HypeSquad Online
Joins a HypeSquad house and applies the relevant [user flag](#user-flags) to the current user. Returns a 204 empty response on success. Fires a [User Update](/gateway/gateway-events#user-update) Gateway event.
###### JSON Params
| Field | Type | Description |
| -------- | ------- | ----------------------------------------------- |
| house_id | integer | The [HypeSquad house](#hypesquad-house) to join |
###### HypeSquad House
| Value | Description |
| ----- | -------------------- |
| 1 | HypeSquad Bravery |
| 2 | HypeSquad Brilliance |
| 3 | HypeSquad Balance |
Leave HypeSquad Online
Leaves the current user's HypeSquad house and removes the relevant [user flag](#user-flags). Returns a 204 empty response on success. Fires a [User Update](/gateway/gateway-events#user-update) Gateway event.
Submit Developer Portal CSAT Survey
Submits a customer satisfaction survey response for the development experience on Discord. Returns a 204 empty response on success.
###### JSON Params
| Field | Type | Description |
| ------------- | --------- | ---------------------------------- |
| user_id | snowflake | The ID of the client user |
| csat_response | integer | The rating given by the user (1-5) |
Get User Premium Usage
Returns the current user's premium usage for various perks. Only available for users with Nitro.
###### Response Body
| Field | Type | Description |
| --------------------- | ------------------------------------------------ | ----------------------------------------------- |
| nitro_sticker_sends | [premium usage](#premium-usage-structure) object | The number of Nitro sticker the user has sent |
| total_animated_emojis | [premium usage](#premium-usage-structure) object | The number of animated emoji the user has sent |
| total_global_emojis | [premium usage](#premium-usage-structure) object | The number of global emoji the user has sent |
| total_large_uploads | [premium usage](#premium-usage-structure) object | The number of large uploads the user has made |
| total_hd_streams | [premium usage](#premium-usage-structure) object | The number of streams the user has made in HD |
| hd_hours_streamed | [premium usage](#premium-usage-structure) object | The number of hours the user has streamed in HD |
###### Premium Usage Structure
| Field | Type | Description |
| ----- | ------- | -------------------------------------- |
| value | integer | The total number of uses for this perk |
###### Example Response
```json
{
"total_large_uploads": {
"value": 50
},
"total_global_emojis": {
"value": 967
},
"total_animated_emojis": {
"value": 217
},
"nitro_sticker_sends": {
"value": 303
},
"hd_hours_streamed": {
"value": 100
},
"total_hd_streams": {
"value": 50
}
}
```
List Saved Messages
Returns message bookmarks and reminders for the current user.
###### Response Body
| Field | Type | Description |
| ------- | ------------------------------------------------------- | -------------------------- |
| results | array[[saved message](#saved-message-structure) object] | The list of saved messages |
###### Saved Message Structure
| Field | Type | Description |
| --------- | ---------------------------------------------------- | ----------------------------- |
| message | ?[message](/resources/message#message-object) object | The saved message |
| save_data | [save data](#save-data-structure) object | The save data for the message |
###### Save Data Structure
| Field | Type | Description |
| --------------- | ------------------ | ---------------------------------------- |
| channel_id | snowflake | The ID of the channel |
| message_id | snowflake | The ID of the message |
| guild_id? | snowflake | The ID of the guild |
| saved_at | ISO8601 timestamp | The timestamp when the message was saved |
| author_summary | string | Unknown |
| channel_summary | string | Unknown |
| message_summary | string | Unknown |
| notes | string | Unknown |
| due_at | ?ISO8601 timestamp | When the reminder is due |
Save Message
Saves a message for the current user. Returns a [saved message](#saved-message-structure) object on success. Fires a [Saved Message Create](/gateway/gateway-events#saved-message-create) Gateway event.
A maximum number of 200 saved messages without a reminder can be saved per user.
###### JSON Params
| Field | Type | Description |
| ------- | ------------------ | ------------------------ |
| due_at? | ?ISO8601 timestamp | When the reminder is due |
Unsave Message
Unsaves a message for the current user. Returns a 204 empty response on success. Fires a [Saved Message Delete](/gateway/gateway-events#saved-message-delete) Gateway event.
Verify Age
Starts the age verification process using a third-party age verification provider. After the process is complete, a [age verification system message](/resources/message#age-verification-system-message) is sent to the user.
###### Response Body
| Field | Type | Description |
| ------------------------ | ------ | -------------------------------------------------------------------------- |
| verification_request_id | string | UUID generated by the server to track the current age verification request |
| verification_vendor_name | string | The third party age verification provider (currently always `K_ID`) |
| verification_webview_url | string | The webview URL to iframe into the client |
Create User Identity Verification
Creates a new verification attempt for the user. Returns a [user identity verification](#user-identity-verification-object) object on success.
This endpoint is deprecated. Applications must now belong to a team to be verified. As such it is replaced by [Create Team Identity Verification](/resources/team#create-team-identity-verification).
###### JSON Params
| Field | Type | Description |
| ---------- | ------ | --------------------------------------------------------- |
| return_url | string | The URL to redirect to after Stripe verification succeeds |
Get User Identity Verification
Returns a [user identity verification](#user-identity-verification-object) object representing the most recent verification attempt.
This endpoint is deprecated. Applications must now belong to a team to be verified. As such it is replaced by [Get Team Identity Verification](/resources/team#get-team-identity-verification).
---
# Notification Center
Link: https://docs.discord.food/resources/notification-center
Notification center is a feature that aggregates important notifications for users in one place. It includes various types of notifications such as friend requests, mentions, and activity updates.
### Notification Center Item Object
###### Notification Center Item Structure
| Field | Type | Description |
| ------------------------ | ------------------------------------------------------------------------ | ---------------------------------------------------------------------------------------------------------------- |
| id | snowflake | The ID of the notification center item |
| bundle_id | string | An ID that can be used to group related notification center items together |
| type | string | The [type of notification center item](#notification-center-item-type) |
| item_enum | ?integer | The [sub-type](#notification-center-item-enum) of the notification center item (only for `lifecycle_item` items) |
| body | string | The body text of the notification center item |
| acked | boolean | Whether the notification center item is acknowledged |
| deeplink | string | The URL used for deep linking |
| icon_url ^1^ | ?string | The URL of the icon to display |
| icon_name ^1^ | ?string | The internal name of the icon to display |
| other_user | ?partial [user](/resources/user#user-object) object | The other user associated with the item |
| message | ?[message](/resources/message#message-object) object | The message associated with the item |
| completed | boolean | Whether the item is completed |
| guild_id | ?snowflake | The ID of the guild associated with the item |
| message_id | ?snowflake | The ID of the message associated with the item |
| message_channel_id | ?snowflake | The ID of the channel of the message associated with the item |
| guild_scheduled_event_id | ?snowflake | The ID of the scheduled event associated with the item |
| disable_action | boolean | Whether the item is non-actionable |
| callout | ?string | Additional information about the item (e.g. poll question) |
| application | ?partial [application](/resources/application#application-object) object | The application associated with the item |
| emoji_id ^2^ | ?snowflake | The ID of the custom emoji associated with the item |
| emoji_name ^2^ | ?string | The unicode character of the emoji associated with the item |
| message_content | ?string | Contents of the message associated with the item |
| message_embed_count | ?integer | Number of the embeds that the associated message has |
| message_attachment_count | ?integer | Number of the attachments that the associated message has |
| message_sticker_count | ?integer | Number of the stickers that the associated message has |
| is_voice_message | boolean | Whether the associated message is a voice message |
^1^ Only either `icon_url` or `icon_name` may be present.
^2^ At most one of `emoji_id` and `emoji_name` may be set to a non-null value.
###### Notification Center Item Type
| Value | Description |
| ------------------------------------ | ----------------------------------------------------- |
| go_live_push | Friend started a stream |
| friend_request_accepted | Outgoing friend request was accepted |
| friend_request_pending | A friend request is pending |
| friend_suggestion_created | A friend suggestion was created |
| friend_request_reminder | Reminder about pending friend requests |
| dm_friend_nudge | Reminder to message friends |
| recent_mention | Recent mention |
| reply_mention | Mention through a reply ping |
| scheduled_guild_event_started | A guild scheduled event started |
| system_demo | Demo notification |
| missed_messages | Missed messages from frequently read channel |
| top_messages **(deprecated)** | Top messages from a frequently read guild's home feed |
| lifecycle_item | New user tutorial item |
| trending_content | Unknown |
| referral_program_entrypoint_reminder | Referral program entrypoint reminder |
| ~~poll_ended~~ | ~~Poll ended~~ |
| game_friend_request_accepted | Outgoing game friend request was accepted |
| reaction_sent | Reaction was added on the user's message |
###### Notification Center Item Enum
| Value | Name | Description |
| ----- | -------------- | -------------- |
| 0 | UPDATE_PROFILE | Update profile |
| 1 | FIND_FRIENDS | Find friends |
| 2 | ADD_FRIEND | Add friend |
| 3 | FIRST_MESSAGE | First message |
## Endpoints
List Notification Center Items
Returns the user's notification center items. Items are ordered by most recent first.
###### Query String Params
| Field | Type | Description |
| ---------------- | --------- | --------------------------------------------------------------------- |
| after? | snowflake | Get notification center items after this notification center item ID |
| with_mentions? | boolean | Whether to include recent mention notifications (default false) |
| roles_filter? | boolean | Whether to include role mentions (default true) |
| everyone_filter? | boolean | Whether to include @everyone and @here mentions (default true) |
| limit? | integer | Max number of notification center items to return (1-100, default 25) |
###### Response Body
| Field | Type | Description |
| -------- | -------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------- |
| limit | integer | The requested limit |
| items | array[[notification center item](#notification-center-item-object) object] | The notification center items |
| cursor | ?snowflake | The cursor for pagination |
| has_more | boolean | Whether there are potentially additional notification center items that could be returned on a subsequent call |
Delete Notification Center Item
Deletes a notification center item. Returns a 204 empty response on success. Fires a [Notification Center Item Delete](/gateway/gateway-events#notification-center-item-delete) Gateway event.
###### JSON Params
| Field | Type | Description |
| ---------- | ------ | ----------------------------------------------------------------------------------------- |
| item_type? | string | The [type of notification center item](#notification-center-item-deletion-type) to delete |
###### Notification Center Item Deletion Type
| Value | Description |
| ------- | ------------------------------------------------------------------------------------------------------- |
| mention | The item is a mention (`type` of [`reply_mention` or `recent_mention`](#notification-center-item-type)) |
| regular | The item is a regular item |
Acknowledge Notification Center Item
Acknowledges a notification center item. Returns a 204 empty response on success. Fires a [Notification Center Items Ack](/gateway/gateway-events#notification-center-items-ack) Gateway event.
This acknowledges the individual notification center item. To acknowledge the notification center's overall unread badge threshold, use the [`NOTIFICATION_CENTER` read state acknowledgement](/topics/read-state#acknowledge-user-feature) instead.
Bulk Acknowledge Notification Center Items
Acknowledges multiple notification center items in bulk. Returns a 204 empty response on success. Fires multiple [Notification Center Items Ack](/gateway/gateway-events#notification-center-items-ack) Gateway events.
This does not replace the `NOTIFICATION_CENTER` read state acknowledgement; clients may need to keep both the item `acked` state and the read state badge threshold in sync.
###### Query String Parameters
| Field | Type | Description |
| -------- | ---------------- | ------------------------------------------------------- |
| item_ids | array[snowflake] | The IDs of the notification center items to acknowledge |
---
# Directory Entries
Link: https://docs.discord.food/resources/directory-entry
A directory in Discord is a special type of channel that contains a list of directory entries, which are guilds and scheduled events that have been added and made discoverable by the community. Any user that can access a directory can view the entries and join the guilds.
Directories are most commonly found in [student hubs](https://support.discord.com/hc/en-us/articles/4406046651927).
### Directory Entry Object
###### Directory Entry Structure
| Field | Type | Description |
| -------------------------- | ------------------------------------------------------------------------------------ | -------------------------------------------------------- |
| type | integer | The [type of directory entry](#directory-entry-type) |
| directory_channel_id | snowflake | The ID of the directory channel that the entry is in |
| entity_id | snowflake | The ID of the guild or scheduled event |
| created_at | string | When the entry was created |
| primary_category_id? | integer | The [primary category](#directory-category) of the entry |
| description | ?string | The description of the entry |
| author_id | snowflake | The ID of the user that created the entry |
| guild? ^1^ | [directory guild](#directory-guild-structure) object | The guild entry |
| guild_scheduled_event? ^1^ | [directory guild scheduled event](#directory-guild-scheduled-event-structure) object | The guild scheduled event entry |
^1^ Not included when fetched from [List Partial Directory Entries](#list-partial-directory-entries).
###### Directory Guild Structure
This object is a partial [guild object](/resources/guild#guild-object) with the following additional fields:
| Field | Type | Description |
| ----------------------- | ------- | ------------------------------------------------------------- |
| featurable_in_directory | boolean | Whether the guild is eligible to be featured in the directory |
###### Directory Guild Scheduled Event Structure
This object is a [guild scheduled event object](/resources/guild-scheduled-event#guild-scheduled-event-object) with the following additional fields:
| Field | Type | Description |
| ---------- | ----------------------------------------------------- | ---------------------------------------- |
| guild | partial [guild object](/resources/guild#guild-object) | The guild that the event is for |
| user_rsvp? | boolean | Whether the user has RSVP'd to the event |
###### Directory Entry Type
| Value | Name | Description |
| ----- | --------------------- | ----------------- |
| 0 | GUILD | A guild |
| 1 | GUILD_SCHEDULED_EVENT | A scheduled event |
###### Directory Category
| Value | Name | Description |
| ----- | ----------------- | --------------------------- |
| 0 | UNCATEGORIZED | Uncategorized entry |
| 1 | SCHOOL_CLUB | School club or organization |
| 2 | CLASS | Class or subject |
| 3 | STUDY_SOCIAL | Study or social group |
| ~~4~~ | ~~SUBJECT_MAJOR~~ | ~~For a subject or major~~ |
| 5 | MISC | Miscellaneous entry |
## Endpoints
Get Directory Counts
Returns a mapping of [directory categories](#directory-category) to their entry count in the given directory channel. Requires the `VIEW_CHANNEL` permission.
List Directory Entries
Returns a list of [directory entry](#directory-entry-object) objects in the given directory channel. Requires the `VIEW_CHANNEL` permission.
###### Query String Parameters
| Field | Type | Description |
| ------------ | ------- | ----------------------------------------------------------------- |
| type? | integer | The [type of directory entry](#directory-entry-type) to filter by |
| category_id? | integer | The [primary category](#directory-category) to filter by |
List Partial Directory Entries
Returns a list of partial [directory entry](#directory-entry-object) objects in the given directory channel. Requires the `VIEW_CHANNEL` permission.
###### Query String Parameters
| Field | Type | Description |
| ----------- | ---------------- | ------------------------------------------------------ |
| entity_ids? | array[snowflake] | The IDs of the directory entries to retrieve (max 100) |
Search Directory Entries
Returns a list of [directory entry](#directory-entry-object) objects in the given directory channel that match the query. Requires the `VIEW_CHANNEL` permission.
###### Query String Parameters
| Field | Type | Description |
| ------------ | ------- | ----------------------------------------------------------------- |
| query | string | The query to search for (1-100 characters) |
| type? | integer | The [type of directory entry](#directory-entry-type) to filter by |
| category_id? | integer | The [primary category](#directory-category) to filter by |
Get Directory Entry
Returns a [directory entry](#directory-entry-object) object for the given entity ID in the directory channel. Requires the `VIEW_CHANNEL` permission.
Create Directory Entry
Creates a new [directory entry](#directory-entry-object) in the given directory channel. Requires the `VIEW_CHANNEL` permission and the `MANAGE_GUILD` permission on the entity being added.
Returns the new [directory entry](#directory-entry-object) object on success. Fires a [Guild Directory Entry Create](/gateway/gateway-events#guild-directory-entry-create) Gateway event.
###### JSON Params
| Field | Type | Description |
| -------------------- | ------- | ---------------------------------------------------------------------------------- |
| type? | integer | The [type of directory entry](#directory-entry-type) to create (default `GUILD`) |
| primary_category_id? | integer | The [primary category](#directory-category) of the entry (default `UNCATEGORIZED`) |
| description? | ?string | The description of the entry (max 200 characters) |
Modify Directory Entry
Modifies an existing directory entry in the given directory channel. Requires the `VIEW_CHANNEL` permission and the `MANAGE_GUILD` permission on the entity being modified.
Returns the updated [directory entry](#directory-entry-object) object on success. Fires a [Guild Directory Entry Update](/gateway/gateway-events#guild-directory-entry-update) Gateway event.
###### JSON Params
| Field | Type | Description |
| -------------------- | ------- | -------------------------------------------------------- |
| primary_category_id? | integer | The [primary category](#directory-category) of the entry |
| description? | string | The description of the entry (max 200 characters) |
Delete Directory Entry
Deletes a directory entry in the given directory channel. Requires the `VIEW_CHANNEL` permission and the `MANAGE_GUILD` permission on the entity being deleted.
Returns a 204 empty response on success. Fires a [Guild Directory Entry Delete](/gateway/gateway-events#guild-directory-entry-delete) Gateway event.
Get Directory Broadcast Info
Returns the broadcast information for the given guild and directory entry type. User must be a member of the guild.
###### Query String Parameters
| Field | Type | Description |
| ---------- | ------- | ------------------------------------------------------------------------------ |
| type | integer | The [type of directory entry](#directory-entry-type) to get broadcast info for |
| entity_id? | integer | The ID of the directory entry to get broadcast info for |
###### Response Body
| Field | Type | Description |
| ------------------ | ------- | ----------------------------------------------------------------- |
| can_broadcast | boolean | Whether the user can broadcast in any linked directory channels |
| has_broadcast? ^1^ | boolean | Whether the entity has been broadcasted in any directory channels |
^1^ Only included when `entity_id` is provided.
---
# User Settings
Link: https://docs.discord.food/resources/user-settings
User settings are options that a user can configure to change the behavior of their account or client. User guild settings are used to control notifications and other customization options on a per-guild basis.
### User Settings Object
Contains general user settings.
In OAuth2 contexts, only certain fields are available. If a required scope is missing, the field will be omitted.
This is deprecated in favor of the [protobuf user settings implementation](/resources/user-settings-proto).
###### User Settings Structure
| Field | Type | Description | Required Scopes |
| ---------------------------------------------- | ------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------- | --------------------------------------- |
| activity_restricted_guild_ids | array[snowflake] | The IDs of guilds your activity presence will be hidden in | |
| activity_joining_restricted_guild_ids | array[snowflake] | The IDs of guilds that will not be able to join your current activity | |
| afk_timeout | integer | Duration (in seconds) the user needs to be inactive until clients update their AFK state | |
| allow_accessibility_detection | boolean | Whether to allow Discord to track screen reader usage | |
| allow_activity_party_privacy_friends | boolean | Whether to allow friends to join your activity without sending a request (default true) | `activities.read` or `presences.read` |
| allow_activity_party_privacy_voice_channel ^1^ | boolean | Whether to allow people in the same voice channel as you to join your activity without sending a request (default true) | `activities.read` or `presences.read` |
| animate_emoji | boolean | Whether to play animated emoji in chat | |
| animate_stickers | integer | [When to animate stickers in chat](#sticker-animation-option) | |
| contact_sync_enabled | boolean | Whether to enable contact sync on Discord mobile | |
| convert_emoticons | boolean | Whether to convert emoticons into emoji (e.g. `:)` -> `🙂`) | |
| custom_status | ?[custom status](#custom-status-structure) object | The overall custom status of the user, used to sync presence across clients | `activities.read` or `presences.read` |
| default_guilds_restricted | boolean | Whether to automatically disable DMs between you and members of new guilds you join | |
| detect_platform_accounts | boolean | Whether to automatically detect accounts from services like Steam and Blizzard when opening the Discord client | |
| developer_mode | boolean | Whether to enable developer mode in-client | |
| disable_games_tab | boolean | Whether to disable the showing of the Games tab | |
| enable_tts_command | boolean | Whether to allow TTS messages to be sent and played | |
| explicit_content_filter | integer | The [explicit content filter](#explicit-content-filter) for explicit content in all messages | |
| friend_discovery_flags | integer | The user's [friend discovery flags](#friend-discovery-flags) | |
| friend_source_flags | ?[friend source flags](#friend-source-flags-structure) object | The user's friend source flags (default all false) | |
| gif_auto_play | boolean | Whether GIFs are automatically played when the Discord client is in focus | |
| guild_folders | array[[guild folder](#guild-folder-structure) object] | The guild folders | `guilds` |
| inline_attachment_media | boolean | Whether to display attachments when they are uploaded in chat | |
| inline_embed_media | boolean | Whether to display videos and images from links posted in chat | |
| locale | string | The [language option](/reference#locales) chosen by the user | |
| message_display_compact | boolean | Whether to use the compact Discord display mode | |
| native_phone_integration_enabled | boolean | Whether to enable the new Discord mobile phone number friend requesting feature | |
| passwordless **(deprecated)** | boolean | Whether to enable passwordless login | |
| render_embeds | boolean | Whether to render message embeds | |
| render_reactions | boolean | Whether to render message reactions | |
| restricted_guilds | array[snowflake] | The IDs of guilds that you will not receive DMs from | |
| show_current_game | boolean | Whether to display the currently active game in user presence (default true) | `activities.read` or `presences.read` |
| slayer_sdk_receive_dms_in_game ^2^ | integer | Setting for [receiving in-game DMs](/resources/user-settings-proto#slayer-sdk-receive-in-game-dms) via the social layer SDK | `activities.write` or `presences.write` |
| soundboard_volume ^3^ | float | Volume level for soundboard playback (0-100) | `voice` |
| status | string | The [overall status](/resources/presence#status-type) of the user, used to sync presence across clients | `activities.read` or `presences.read` |
| stream_notifications_enabled | boolean | Whether to receive stream notifications for friends | |
| theme | string | The user's [client theme](#theme) | |
| timezone_offset | integer | The timezone offset from UTC to use (in minutes) | |
| view_nsfw_commands | boolean | Whether NSFW application commands are shown in DMs | |
| view_nsfw_guilds | boolean | Whether NSFW guilds are shown on iOS | |
^1^ Does not apply to community guilds.
^2^ Not available in the [Ready](/gateway/gateway-events#ready) event in OAuth2 contexts.
^3^ Only available in the [Ready](/gateway/gateway-events#ready) event in OAuth2 contexts.
###### Sticker Animation Option
| Value | Name | Description |
| ----- | ---------------------- | ------------------------------ |
| 0 | ALWAYS_ANIMATE | Always animate stickers |
| 1 | ANIMATE_ON_INTERACTION | Animate sticker on interaction |
| 2 | NEVER_ANIMATE | Never animate stickers |
###### Custom Status Structure
| Field | Type | Description |
| -------------- | ------------------ | ---------------------------------- |
| text | ?string | The custom status text (max 128) |
| emoji_id ^1^ | ?snowflake | The ID of a guild's custom emoji |
| emoji_name ^1^ | ?string | The unicode character of the emoji |
| expires_at | ?ISO8601 timestamp | When the custom status will expire |
^1^ At most one of `emoji_id` and `emoji_name` may be set to a non-null value.
###### Theme
| Value | Description |
| -------- | -------------- |
| dark | Dark theme |
| light | Light theme |
| darker | Darker theme |
| midnight | Midnight theme |
###### Explicit Content Filter
Whose messages will be scanned for explicit content.
| Value | Name | Description |
| ----- | ------------ | ------------------------------------------------- |
| 0 | DISABLED | Don't scan any direct messages |
| 1 | NON_FRIENDS | Scan all direct messages that aren't from friends |
| 2 | ALL_MESSAGES | Scan all direct messages from everyone |
###### Friend Discovery Flags
Determines how you get recommended friends.
| Value | Name | Description |
| -------- | ------------- | ----------------------------------------------------- |
| 1 \<\< 1 | FIND_BY_PHONE | Whether the current user can be found by phone number |
| 1 \<\< 2 | FIND_BY_EMAIL | Whether the current user can be found by email |
###### Friend Source Flags Structure
Determines who can add the user as a friend.
| Field | Type | Description |
| --------------- | ------- | --------------------------------------------------------------- |
| all? | boolean | Whether everyone can add the user as a friend |
| mutual_friends? | boolean | Whether mutual friends can add the user as friend |
| mutual_guilds? | boolean | Whether members in the user's guilds can add the user as friend |
###### Guild Folder Structure
A collection of guilds.
If `id` is `null` and `guild_ids` is a single element array, this folder is not displayed and instead represents a single guild's position in the sidebar.
| Field | Type | Description |
| --------- | ---------------- | ---------------------------------------------------------------------------------------- |
| color | ?integer | The color of the folder encoded as an integer representation of a hexadecimal color code |
| guild_ids | array[snowflake] | The IDs of guilds this folder contains |
| id | ?integer | The ID of the folder |
| name | ?string | The name of the folder (default `', '.join(guild.name for guild in folder.guilds)`) |
### Consents Object
Contains the user's tracking feature consent status.
Disabling tracking features will result in reduced exposure to experiments and certain features such as affinities being disabled.
###### Consents Structure
This object is a map of [consent types](#consent-type) to their [status](#consent-status-structure).
##### Consent Type
| Value | Description |
| -------------------- | ---------------------------------------------------------------------------- |
| personalization | Whether the user has consented to their data being used for personalization |
| usage_statistics ^1^ | Whether the user has consented to their data being used for usage statistics |
^1^ Only included when fetched from the [Get User Consents](#get-user-consents) endpoint.
###### Consent Status Structure
| Field | Type | Description |
| --------- | ------- | --------------------------------------------- |
| consented | boolean | Whether the user has consented to the feature |
### Email Settings Object
Email communication preferences.
###### Email Settings Structure
| Field | Type | Description |
| ----------- | -------------------- | ---------------------------------------------------------------------------------- |
| initialized | boolean | Whether the email settings have been initialized |
| categories | map[string, boolean] | The [email settings categories](#email-settings-category) and their enabled status |
###### Email Settings Category
| Value | Description |
| -------------------------- | ----------------------------------------------------------------- |
| communication | Receive emails for missed calls and messages |
| social | Receive emails for friend requests, friend suggestions, or events |
| recommendations_and_events | Receive emails for recommended guilds and events |
| tips | Receive emails for advice and tricks |
| updates_and_announcements | Receive emails for updates and new features |
| family_center_digest | Receive weekly emails for recent family activity |
### Notification Settings Object
User-wide notification settings.
###### Notification Settings Structure
| Field | Type | Description |
| ----- | ------- | --------------------------------------------------------------- |
| flags | integer | The [notification settings flags](#notification-settings-flags) |
###### Notification Settings Flags
| Value | Name | Description |
| -------- | ----------------------- | ---------------------------------------------------------------------------------------------------------------------- |
| 1 \<\< 4 | USE_NEW_NOTIFICATIONS | Whether to separate unreads from the overall message notification level |
| 1 \<\< 5 | MENTION_ON_ALL_MESSAGES | Whether to increment the mention count on all messages in channels with a message notification level of `ALL_MESSAGES` |
###### Example Notification Settings
```json
{ "flags": 16 }
```
### Notification Settings Snapshot Object
A snapshot of the user's guild settings.
###### Notification Settings Snapshot Structure
| Field | Type | Description |
| ----------- | ----------------- | ----------------------------------- |
| id | snowflake | The ID of the snapshot |
| label | ?string | The label of the snapshot |
| recorded_at | ISO8601 timestamp | When the snapshot was recorded |
| length | integer | The length of the snapshot in bytes |
###### Example Notification Settings Snapshot
```json
{
"id": "1189703042711425185",
"label": "Before the Great Mute",
"recorded_at": "2023-12-27T22:55:08.998082+00:00",
"length": 145750
}
```
### Video Filter Asset Object
A user-uploaded custom video background asset.
###### Video Filter Asset Structure
| Field | Type | Description |
| ---------- | --------- | ---------------------------------------------------------------- |
| id | snowflake | The ID of the video filter asset |
| type | integer | The [type](#video-filter-type) of video filter |
| user_id | snowflake | The ID of the user who owns the asset |
| asset | string | The [asset hash](/reference#cdn-formatting) |
| last_used? | integer | Unix timestamp (in milliseconds) of when the asset was last used |
###### Video Filter Type
| Value | Name | Description |
| ----- | ---------- | ----------------------- |
| 0 | BACKGROUND | A video call background |
### User Guild Settings Object
Guild-specific settings for the current user.
###### User Guild Settings Structure
| Field | Type | Description |
| --------------------- | ------------------------------------------------------------- | ------------------------------------------------------------------------------------------- |
| channel_overrides | array[[channel override](#channel-override-structure) object] | The overrides for channels |
| flags | integer | The [user guild settings flags](#user-guild-settings-flags) |
| guild_id ^1^ | ?snowflake | The ID of the guild |
| hide_muted_channels | boolean | Whether to hide muted channels from the UI |
| message_notifications | integer | The [message notification level](/resources/guild#message-notification-level) for the guild |
| mobile_push | boolean | Whether to send push notifications to mobile clients |
| mute_scheduled_events | boolean | Whether new guild scheduled event notifications are muted |
| muted | boolean | Whether the guild is muted |
| mute_config | ?[mute config](#mute-config-object) object | The mute metadata for the guild |
| notify_highlights | integer | The [highlight notification level](#highlight-level) for the guild |
| suppress_everyone | boolean | Whether to suppress @everyone notifications |
| suppress_roles | boolean | Whether to suppress role notifications |
| version | integer | The version of guild settings |
^1^ A value of `null` is used to indicate these settings are for the user's private channel notifications.
###### Partial User Guild Settings Structure
Used when modifying user guild settings.
| Field | Type | Description |
| ---------------------- | ---------------------------------------------------------------------- | ------------------------------------------------------------------------------------------- |
| channel_overrides? | map[snowflake, [channel override](#channel-override-structure) object] | The channel overrides to modify |
| flags? | integer | The [user guild settings flags](#user-guild-settings-flags) |
| hide_muted_channels? | boolean | Whether to hide muted channels from the UI |
| message_notifications? | integer | The [message notification level](/resources/guild#message-notification-level) for the guild |
| mobile_push? | boolean | Whether to send push notifications to mobile clients |
| mute_scheduled_events? | boolean | Whether new guild scheduled event notifications are muted |
| muted? | boolean | Whether the guild is muted |
| mute_config? | ?[mute config](#mute-config-object) object | The mute metadata for the guild |
| notify_highlights? | integer | The [highlight notification level](#highlight-level) for the guild |
| suppress_everyone? | boolean | Whether to suppress @everyone notifications |
| suppress_roles? | boolean | Whether to suppress role notifications |
###### Channel Override Structure
| Field | Type | Description |
| --------------------- | ------------------------------------------ | --------------------------------------------------------------------------------------------- |
| channel_id | snowflake | The ID of the channel |
| collapsed | boolean | Whether the category channel is collapsed |
| flags? | integer | The [channel override's flags](#channel-override-flags) |
| message_notifications | integer | The [message notification level](/resources/guild#message-notification-level) for the channel |
| muted | boolean | Whether the channel is muted |
| mute_config | ?[mute config](#mute-config-object) object | The mute metadata for the channel |
###### Channel Override Flags
| Value | Name | Description |
| --------- | ------------------------- | ----------------------------------------------------------------- |
| 1 \<\< 9 | UNREADS_ONLY_MENTIONS ^1^ | Channel is marked unread on mentions |
| 1 \<\< 10 | UNREADS_ALL_MESSAGES ^1^ | Channel is marked unread on new messages |
| 1 \<\< 11 | FAVORITED | Channel is favorited |
| 1 \<\< 12 | OPT_IN_ENABLED | Channel is shown in the UI |
| 1 \<\< 13 | NEW_FORUM_THREADS_OFF | Thread-only channel is not marked unread when a thread is created |
| 1 \<\< 14 | NEW_FORUM_THREADS_ON | Thread-only channel is marked unread when a thread is created |
^1^ When these flags are unset, unreads follow the [`message_notifications` field](#channel-override-structure).
###### User Guild Settings Flags
| Value | Name | Description |
| --------- | ------------------------- | ----------------------------------------------- |
| 1 \<\< 11 | UNREADS_ALL_MESSAGES ^1^ | Guild is marked unread on new messages |
| 1 \<\< 12 | UNREADS_ONLY_MENTIONS ^1^ | Guild is marked unread on mentions |
| 1 \<\< 13 | OPT_IN_CHANNELS_OFF | Whether to show all guild channels in the UI |
| 1 \<\< 14 | OPT_IN_CHANNELS_ON | Whether to hide non-opted in channels in the UI |
^1^ When these flags are unset, unreads follow the [`message_notifications` field](#user-guild-settings-object).
###### Highlight Level
| Value | Name | Description |
| ----- | -------- | --------------------------- |
| 0 | DEFAULT | Default (same as `ENABLED`) |
| 1 | DISABLED | Suppress highlights |
| 2 | ENABLED | Don't suppress highlights |
###### Example User Guild Settings
```json
{
"guild_id": 373,
"suppress_everyone": false,
"suppress_roles": false,
"mute_scheduled_events": false,
"message_notifications": 1,
"flags": 0,
"mobile_push": true,
"muted": true,
"mute_config": {
"end_time": null,
"selected_time_window": -1
},
"hide_muted_channels": false,
"channel_overrides": [
{
"channel_id": "362165922212872202",
"message_notifications": 3,
"muted": false,
"mute_config": null,
"collapsed": true
}
],
"notify_highlights": 0,
"version": 2016
}
```
### Mute Config Object
The duration of a mute.
###### Mute Config Structure
| Field | Type | Description |
| --------------------- | ------------------ | ------------------------------------------------------- |
| end_time? | ?ISO8601 timestamp | Timestamp representing when the mute ends |
| selected_time_window? | integer | Duration of the mute in seconds, or `-1` for indefinite |
### Audio Context Object
###### Audio Context Structure
| Field | Type | Description |
| ---------------- | ------- | ------------------------------------------- |
| muted | boolean | Whether the audio is muted |
| volume | float | Volume level of the user or stream (0-200) |
| soundboard_muted | boolean | Whether the soundboard is muted (user only) |
###### Audio Context Type
| Value | Description |
| ------ | -------------------- |
| user | Voice audio context |
| stream | Stream audio context |
## Endpoints
Get User Settings
Returns the requester's [user settings](#user-settings-object) object.
Modify User Settings
Modifies the requester's user settings. Returns a [user settings](#user-settings-object) object on success. Fires a [User Settings Proto Update](/gateway/gateway-events#user-settings-proto-update) and [User Settings Update](/gateway/gateway-events#user-settings-update) Gateway event.
For OAuth2 requests, only the `status`, `custom_status` and `slayer_sdk_receive_dms_in_game` fields can be modified. Similarly, the response object will only contain these three fields.
###### JSON Params
| Field | Type | Description |
| -------------------------------------- | ------------------------------------------------------------ | --------------------------------------------------------------------------------------------------------------------------- |
| activity_joining_restricted_guild_ids? | array[snowflake] | The IDs of guilds that will not be able to join your current activity |
| activity_restricted_guild_ids? | array[snowflake] | The IDs of guilds your activity presence will be hidden in |
| afk_timeout? | integer | Duration (in seconds) the user needs to be inactive until clients update their AFK state |
| allow_accessibility_detection? | boolean | Whether to allow Discord to track screen reader usage |
| animate_emoji? | boolean | Whether to play animated emoji in chat |
| animate_stickers? | integer | [When to animate stickers in chat](#sticker-animation-option) |
| contact_sync_enabled? | boolean | Whether to enable contact sync on Discord mobile |
| convert_emoticons? | boolean | Whether to convert emoticons into emoji (`:)` -> `🙂`) |
| custom_status? | ?[custom status](#custom-status-structure) object | The custom status of the user, used to sync presence across clients |
| default_guilds_restricted? | boolean | Whether to automatically disable DMs between you and members of new guilds you join |
| detect_platform_accounts? | boolean | Whether to automatically detect accounts from services like Steam and Blizzard when opening the Discord client |
| developer_mode? | boolean | Whether to enable developer mode in-client |
| disable_games_tab? | boolean | Whether to disable the showing of the Games tab |
| enable_tts_command? | boolean | Whether to allow TTS messages to be played/sent |
| explicit_content_filter? | integer | The [explicit content filter](#explicit-content-filter) for explicit content in all messages |
| friend_discovery_flags? | integer | The [friend discovery flags](#friend-discovery-flags) |
| friend_source_flags? | [friend source flags](#friend-source-flags-structure) object | The friend source flags |
| gif_auto_play? | boolean | Whether GIFs are automatically played when Discord client is in focus |
| guild_folders? | array[[guild folder](#guild-folder-structure) object] | The guild folders |
| inline_attachment_media? | boolean | Whether to display attachments when they are uploaded in chat |
| inline_embed_media? | boolean | Whether to display videos and images from links posted in chat |
| locale? | string | The [language option](/reference#locales) chosen by the user |
| message_display_compact? | boolean | Whether to use the compact Discord display mode |
| native_phone_integration_enabled? | boolean | Whether to enable the new Discord mobile phone number friend requesting feature |
| passwordless? **(deprecated)** | boolean | Whether to enable passwordless login |
| render_embeds? | boolean | Whether to render message embeds |
| render_reactions? | boolean | Whether to render message reactions |
| restricted_guilds? | array[snowflake] | The IDs of guilds that you will not receive DMs from |
| show_current_game? | boolean | Whether to display the currently active game in user presence |
| slayer_sdk_receive_dms_in_game? | integer | Setting for [receiving in-game DMs](/resources/user-settings-proto#slayer-sdk-receive-in-game-dms) via the social layer SDK |
| status? | string | The [status](/resources/presence#status-type) of the user, used to sync presence across clients |
| stream_notifications_enabled? | boolean | Whether to receive stream notifications for friends |
| theme? | string | The [theme](#theme) |
| timezone_offset? | integer | The timezone offset from UTC to use (in minutes) |
| view_nsfw_guilds? | boolean | Whether NSFW guilds are shown on iOS |
Get User Consents
Returns a [consents](#consents-object) object representing the tracking features the requestor has consented to.
Modify User Consents
Modifies the requestor's tracking consent status. Returns a [consents](#consents-object) object on success.
###### JSON Params
| Field | Type | Description |
| ------ | ------------- | -------------------------------------------- |
| grant | array[string] | The [consent types](#consent-type) to grant |
| revoke | array[string] | The [consent types](#consent-type) to revoke |
Get Email Settings
Returns the requester's [email settings](#email-settings-object) object.
Modify Email Settings
Modifies the requester's email settings. Returns an [email settings](#email-settings-object) object on success.
###### JSON Params
| Field | Type | Description |
| -------- | ------------------------------------------------------- | ---------------------------- |
| settings | partial [email settings](#email-settings-object) object | The email settings to modify |
Modify Notification Settings
Replaces the notification settings for the user. Returns a [notification settings](#notification-settings-object) object on success. Fires a [Notification Settings Update](/gateway/gateway-events#notification-settings-update) Gateway event.
All parameters to this endpoint are optional and nullable. Omitting or setting a `null` value will set it to default.
###### JSON Params
| Field | Type | Description |
| ------ | -------- | ---------------------------------------------------------------------- |
| flags? | ?integer | The [notification settings flags](#notification-settings-flags) to set |
List Notification Settings Snapshots
Returns a list of [notification settings snapshot](#notification-settings-snapshot-object) objects for the user.
Create Notification Settings Snapshot
Creates a new notification settings snapshot for the user. Returns a list of [notification settings snapshot](#notification-settings-snapshot-object) objects on success.
A maximum of 5 snapshots or **1 MiB** of data can be stored per user.
###### JSON Params
| Field | Type | Description |
| ------ | ------- | ---------------------------------------------- |
| label? | ?string | The label of the snapshot (max 100 characters) |
Restore Notification Settings Snapshot
Restores a notification settings snapshot. Returns a mapping of guild IDs to [user guild settings](#user-guild-settings-object) objects on success. Fires multiple [User Guild Settings Update](/gateway/gateway-events#user-guild-settings-update) Gateway events.
Delete Notification Settings Snapshot
Deletes a notification settings snapshot. Returns a list of [notification settings snapshot](#notification-settings-snapshot-object) objects on success.
Modify User Guild Settings
Modifies a guild's settings. Accepts a [partial user guild settings](#partial-user-guild-settings-structure) object. Returns a [user guild settings](#user-guild-settings-object) object on success. Fires a [User Guild Settings Update](/gateway/gateway-events#user-guild-settings-update) Gateway event.
A value of `@me` for `guild.id` is used to indicate these settings are for the user's private channel notifications.
Bulk Modify User Guild Settings
Modifies multiple guilds' settings. Returns a list of [user guild settings](#user-guild-settings-object) objects on success. Fires multiple [User Guild Settings Update](/gateway/gateway-events#user-guild-settings-update) Gateway events.
This endpoint cannot be used to modify the user's private channel notification settings.
###### JSON Params
| Field | Type | Description |
| ------ | -------------------------------------------------------------------------------------------- | --------------------------------- |
| guilds | map[snowflake, [partial user guild settings](#partial-user-guild-settings-structure) object] | The user guild settings to modify |
Modify Audio Settings
Modifies the user's audio context settings. Returns a 204 empty response on success. Fires a [Audio Settings Update](/gateway/gateway-events#audio-settings-update) Gateway event.
###### JSON Params
| Field | Type | Description |
| ----------------- | ------- | ------------------------------------------- |
| muted? | boolean | Whether the audio is muted |
| volume? | float | Volume level of the user or stream (0-200) |
| soundboard_muted? | boolean | Whether the soundboard is muted (user only) |
List Video Filter Assets
Returns a list of [video filter asset](#video-filter-asset-object) objects for the current user.
Create Video Filter Asset
Uploads a custom video filter asset. Returns a [video filter asset](#video-filter-asset-object) object on success.
###### JSON Params
| Field | Type | Description |
| ----- | --------------------------------- | ---------------------------------------------- |
| type | integer | The [type](#video-filter-type) of video filter |
| asset | [image data](/reference#cdn-data) | The asset |
Delete Video Filter Asset
Deletes a video filter asset. Returns a 204 empty response on success.
Mark Video Filter Asset Last Used
Marks a video filter asset as the current user's last used custom background. Returns the updated [video filter asset](#video-filter-asset-object) object on success.
---
# Discovery
Link: https://docs.discord.food/resources/discovery
Discovery is a feature that allows users to find and join new communities on Discord, open to all guilds that meet the requirements. Discovery happens within the client or the [marketing page](https://discord.com/servers).
## Definitions
A guild is considered discoverable by the API if it has the [`DISCOVERABLE` guild feature](/resources/guild#guild-features).
Additionally, any guilds within a directory channel the user has access to (guilds that have the [`HAS_DIRECTORY_ENTRY` guild feature](/resources/guild#guild-features)), like in a student hub, are also considered discoverable relative to the user.
## Searching Discovery
Discord utilizes [Algolia](https://www.algolia.com/) to power search for discovery. You can search for guilds by name, description, keywords, and more. Reference the [Algolia Search documentation](https://www.algolia.com/doc/rest-api/search/) for more information on how to search. A [proxied version of the Algolia Search API](#search-discoverable-guilds) is available, with limited parameter support.
All hits returned from Algolia are [discoverable guild](#discoverable-guild-object) objects. However, some fields such as `features` are truncated to only include values that are relevant to discovery.
###### Algolia Credentials
As of December 2024, Discord has revoked the Algolia credentials used for searching discovery. This means that the Algolia index can no longer be accessed directly.
These credentials are for production only.
```
Application ID: NKTZZ4AIZU
API Key: <...>
```
### Discoverable Guild Object
A partial guild object returned from discovery, [Get Emoji Guild](/resources/emoji#get-emoji-guild), [Get Sticker Guild](/resources/sticker#get-sticker-guild), and [Get Soundboard Sound Guild](/resources/soundboard#get-soundboard-sound-guild).
###### Discoverable Guild Structure
| Field | Type | Description |
| -------------------------- | ------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------ |
| id | snowflake | The ID of the guild |
| name | string | The name of the guild (2-100 characters) |
| icon | ?string | The guild's [icon hash](/reference#cdn-formatting) |
| description | ?string | The description for the guild (max 300 characters) |
| banner | ?string | The guild's [banner hash](/reference#cdn-formatting) |
| splash | ?string | The guild's [splash hash](/reference#cdn-formatting) |
| discovery_splash | ?string | The guild's [discovery splash hash](/reference#cdn-formatting) |
| features | array[string] | Enabled [guild features](/resources/guild#guild-features) |
| vanity_url_code | ?string | The guild's vanity invite code |
| preferred_locale | string | The preferred locale of the guild; used in discovery and notices from Discord (default "en-US") |
| premium_subscription_count | integer | The number of premium subscriptions (boosts) the guild currently has |
| approximate_member_count | integer | Approximate number of members in the guild |
| approximate_presence_count | integer | Approximate number of online members in the guild |
| emojis? ^1^ | array[[emoji](/resources/emoji#emoji-object) object] | Custom guild emoji; limited to 30 entries |
| emoji_count? ^1^ | integer | Total number of custom guild emoji |
| stickers? ^1^ | array[[sticker](/resources/sticker#sticker-object) object] | Custom guild stickers; limited to 30 entries |
| sticker_count? ^1^ | integer | Total number of custom guild stickers |
| auto_removed | boolean | Whether the guild has automatically been removed from discovery for not hitting required targets |
| primary_category_id | integer | The ID of the primary [discovery category](#discovery-category-object) set for the guild |
| primary_category? ^3^ | [discovery category](#discovery-category-object) | The primary [discovery category](#discovery-category-object) set for the guild |
| keywords | ?array[string] | The discovery search keywords for the guild (max 30 characters, max 10) |
| is_published | boolean | Whether the guild's landing web page is currently published |
| reasons_to_join? ^2^ | array[[discovery reason object](#discovery-reason-structure)] | The reasons to join the guild shown in the discovery web page (max 4) |
| social_links? ^2^ | ?array[string] | The guild's social media links shown in the discovery web page (max 256 characters, max 9) |
| about? ^2^ | ?string | The guild's long description shown in the discovery web page (max 2400 characters) |
| category_ids? ^2^ | array[snowflake] | The IDs of [discovery subcategories](#discovery-category-object) set for the guild (max 5) |
| categories? ^3^ | array[[discovery category](#discovery-category-object)] | The [discovery categories](#discovery-category-object) set for the guild (max 5) |
| created_at? ^2^ | ISO8601 timestamp | When the guild was created |
| nsfw_properties? | ?[discovery NSFW properties](#discovery-nsfw-properties-structure) object | Disallowed terms found in the guild's name, description, and channel names |
^1^ The presence of these fields is dependent on the endpoint used to retrieve the guild. [Get Emoji Guild](/resources/emoji#get-emoji-guild) will return emoji-related fields, and [Get Sticker Guild](/resources/sticker#get-guild-sticker) will return sticker-related fields.
^2^ Only included when fetched from the [Get Discovery Slug](#get-discovery-slug) endpoint.
^3^ Only included when [searching discovery](#searching-discovery).
###### Example Discoverable Guild
```json
{
"id": "752630786561409076",
"name": "Elite Creative",
"description": "The largest Fortnite Creative server across the globe. Join a Creative community offering events, 1v1s. and more!",
"icon": "278da1c7740e394657c1179f4782aef1",
"splash": "2b4ae5cdd71038b4880b1b57a6e5dacb",
"banner": "57e939e67aebaf232d28205603020b55",
"approximate_presence_count": 21125,
"approximate_member_count": 155455,
"premium_subscription_count": 17,
"preferred_locale": "en-US",
"auto_removed": false,
"discovery_splash": "9d7ec672b89b320ef7a51e5b6ae453b8",
"primary_category_id": 1,
"vanity_url_code": "creative",
"is_published": true,
"keywords": [
"Fortnite",
"Creative",
"Fortnite Creative",
"Boxfights",
"Zonewars",
"Buildfights",
"1v1",
"EU",
"NA",
"Creator"
],
"features": [
"ANIMATED_BANNER",
"ANIMATED_ICON",
"AUTO_MODERATION",
"BANNER",
"COMMUNITY",
"DISCOVERABLE",
"ENABLED_DISCOVERABLE_BEFORE",
"GUILD_ONBOARDING_EVER_ENABLED",
"GUILD_WEB_PAGE_VANITY_URL",
"INVITE_SPLASH",
"NEWS",
"PREVIEW_ENABLED",
"RAID_ALERTS_ENABLED",
"ROLE_ICONS",
"VANITY_URL",
"WELCOME_SCREEN_ENABLED"
],
"emojis": [],
"emoji_count": 339
}
```
### Discovery Requirements Object
A guild's progress on meeting the requirements of joining discovery.
###### Discovery Requirements Structure
| Field | Type | Description |
| ----------------------------------- | ------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------ |
| guild_id? | snowflake | The ID of the guild |
| safe_environment? | boolean | Whether the guild has not been flagged by Trust & Safety |
| healthy? | boolean | Whether the guild meets activity requirements |
| health_score_pending? | boolean | Whether the guild's activity metrics have not yet been calculated |
| size? | boolean | Whether the guild meets the minimum member count requirement |
| nsfw_properties? | [discovery NSFW properties](#discovery-nsfw-properties-structure) object | Disallowed terms found in the guild's name, description, and channel names |
| protected? | boolean | Whether the guild has the [MFA requirement for moderation actions](/resources/guild#mfa-level) enabled |
| sufficient ^1^ | boolean | Whether the guild meets the requirements to be in Discovery |
| sufficient_without_grace_period ^1^ | boolean | Whether the grace period can allow the guild to remain in Discovery |
| valid_rules_channel? | boolean | Whether the guild has a rules channel set |
| retention_healthy? | boolean | Whether the guild meets the new member retention requirement |
| engagement_healthy? | boolean | Whether the guild meets the weekly visitor and communicator requirements |
| age? | boolean | Whether the guild meets the minimum age requirement |
| minimum_age? | ?integer | The minimum guild age requirement (in days) |
| health_score? | [discovery health score](#discovery-health-score-structure) object | The guild's activity metrics |
| minimum_size? | ?integer | The minimum guild member count requirement |
| grace_period_end_date? | ISO8601 timestamp | When the guild's grace period ends |
^1^ Certain guilds, such as those that are [verified](https://discord.com/verification), are exempt from discovery requirements. These guilds will not have a fully populated discovery requirements object, and are guaranteed to receive only `sufficient` and `sufficient_without_grace_period`.
###### Discovery NSFW Properties Structure
| Field | Type | Description |
| ---------------------------- | ----------------------------- | -------------------------------------------------------------- |
| channels? | array[snowflake] | The IDs of the channels with names containing disallowed terms |
| channel_banned_keywords? | map[snowflake, array[string]] | The disallowed terms found in the given channel names |
| name? | string | The guild name, if it contains disallowed terms |
| name_banned_keywords? | array[string] | The disallowed terms found in the guild name |
| description? | string | The guild description, if it contains disallowed terms |
| description_banned_keywords? | array[string] | The disallowed terms found in the guild description |
###### Discovery Health Score Structure
Activity metrics are recalculated weekly, as an 8-week rolling average. If they are not yet eligible to be calculated, all fields will be `null`.
| Field | Type | Description |
| ------------------------ | ------- | ------------------------------------------------------------------------------------------ |
| avg_nonnew_communicators | ?string | Average weekly number of users who talk in the guild and have been on Discord for 8 weeks+ |
| avg_nonnew_participators | ?string | Average weekly number of users who view the guild and have been on Discord for 8 weeks+ |
| num_intentful_joiners | ?string | Average number of users who join the guild per week |
| perc_ret_w1_intentful | ?float | Percentage of new members who remain in the guild for at least a week |
###### Example Discovery Requirements
```json
{
"guild_id": "1046920999469330512",
"safe_environment": true,
"healthy": true,
"health_score_pending": false,
"size": true,
"nsfw_properties": {
"channels": ["1060703057651978261"],
"channels_banned_keywords": {
"1060703057651978261": ["risque"]
},
"name": "Alien Network",
"name_banned_keywords": ["alien"],
"description": "Where the 👽s 👽 and sometimes very 👽 things happen 😨.",
"description_banned_keywords": ["👽"]
},
"protected": true,
"sufficient": false,
"sufficient_without_grace_period": true,
"valid_rules_channel": true,
"retention_healthy": true,
"engagement_healthy": true,
"age": true,
"minimum_age": 56,
"health_score": {
"avg_nonnew_participators": "1738",
"avg_nonnew_communicators": "348",
"num_intentful_joiners": "834",
"perc_ret_w1_intentful": 0.37651924871356596
},
"minimum_size": 1000,
"grace_period_end_date": "2037-07-01T17:47:49.974000+00:00"
}
```
### Discovery Metadata Object
A guild's discovery settings.
###### Discovery Metadata Structure
| Field | Type | Description |
| ----------------------------- | -------------------------------------------------------------------- | ------------------------------------------------------------------------------------------ |
| guild_id | snowflake | The ID of the guild |
| primary_category_id | integer | The ID of the primary [discovery category](#discovery-category-object) set for the guild |
| keywords | ?array[string] | The discovery search keywords for the guild (max 30 characters, max 10) |
| emoji_discoverability_enabled | boolean | Whether the guild is shown as a source through custom guild expressions |
| partner_actioned_timestamp | ?ISO8601 timestamp | When the guild's partner application was actioned by an employee |
| partner_application_timestamp | ?ISO8601 timestamp | When the guild applied for partnership |
| is_published | boolean | Whether the guild's landing web page is currently published |
| reasons_to_join | array[[discovery reason object](#discovery-reason-structure) object] | The reasons to join the guild shown in the discovery web page (max 4) |
| social_links | ?array[string] | The guild's social media links shown in the discovery web page (max 256 characters, max 9) |
| about | ?string | The guild's long description shown in the discovery web page (max 2400 characters) |
| category_ids | array[integer] | The IDs of [discovery subcategories](#discovery-category-object) set for the guild (max 5) |
###### Discovery Reason Structure
| Field | Type | Description |
| ---------- | ---------- | ----------------------------------------------------------------- |
| reason | string | The reason to join the guild |
| emoji_id | ?snowflake | The [ID of a guild's custom emoji](/resources/emoji#emoji-object) |
| emoji_name | ?string | The unicode character of the emoji |
###### Example Discovery Metadata
```json
{
"guild_id": "1046920999469330512",
"primary_category_id": 49,
"keywords": ["test"],
"emoji_discoverability_enabled": true,
"partner_actioned_timestamp": null,
"partner_application_timestamp": null,
"is_published": false,
"reasons_to_join": [
{ "reason": "Alien", "emoji_id": null, "emoji_name": "👽" },
{ "reason": "Alien", "emoji_id": null, "emoji_name": "👽" },
{ "reason": "Alien", "emoji_id": null, "emoji_name": "👽" },
{ "reason": "Alien", "emoji_id": null, "emoji_name": "👽" }
],
"social_links": ["https://twitter.com/alien"],
"about": "Alien\nAlien\nAlien\nAlien\nAlien\nAlien",
"category_ids": [48]
}
```
### Discovery Category Object
###### Discovery Category Structure
| Field | Type | Description |
| ---------- | ------- | -------------------------------------------------------------- |
| id | integer | The ID of the category |
| name | string | The name of the category |
| is_primary | boolean | Whether the category can be used as a guild's primary category |
###### Example Discovery Category
```json
{
"id": 1,
"name": "Gaming",
"is_primary": true
}
```
### Guild Profile Object
###### Guild Profile Structure
| Field | Type | Description |
| ---------------------------- | ---------------------------------------------------------------- | --------------------------------------------------------------------------- |
| id | snowflake | The ID of the guild |
| name | string | The name of the guild (2-100 characters) |
| icon_hash | ?string | The guild's [icon hash](/reference#cdn-formatting) |
| member_count | integer | Approximate count of total members in the guild |
| online_count | integer | Approximate count of non-offline members in the guild |
| description | string | The description for the guild (max 300 characters) |
| brand_color_primary? | string | The guild's accent color as a hexadecimal color string |
| banner_hash **(deprecated)** | ?string | The guild's [clan banner hash](/reference#cdn-formatting) |
| game_application_ids | array[snowflake] | The IDs of the applications representing the games the guild plays (max 20) |
| game_activity | map[snowflake, [game activity](#game-activity-structure) object] | The activity of the guild in each game |
| tag | ?string | The tag of the guild (2-4 characters) |
| badge | integer | The [badge shown on the guild's tag](#guild-badge-type) |
| badge_color_primary | string | The primary color of the badge as a hexadecimal color string |
| badge_color_secondary | string | The secondary color of the badge as a hexadecimal color string |
| badge_hash | string | The [guild tag badge hash](/reference#cdn-formatting) |
| traits | array[[guild trait](#guild-trait-structure) object] | Terms used to describe the guild's interest and personality (max 5) |
| features ^1^ | array[string] | Enabled [guild features](/resources/guild#guild-features) |
| visibility | integer | The [visibility level](#guild-visibility) of the guild |
| custom_banner_hash | ?string | The guild's [discovery splash hash](/reference#cdn-formatting) |
| premium_subscription_count | integer | The number of premium subscriptions (boosts) the guild currently has |
| premium_tier | integer | The guild's [premium tier](/resources/guild#premium-tier) (boost level) |
^1^ This is not a complete list of all the features the guild has, and is limited to community features (`MEMBER_VERIFICATION_GATE_ENABLED`, `COMMUNITY`, `MEMBER_VERIFICATION_MANUAL_APPROVAL`, `DISCOVERABLE`, `PARTNERED`, `VERIFIED`).
###### Game Activity Structure
| Field | Type | Description |
| -------------- | ------- | ------------------------------------------- |
| activity_level | integer | The activity level of the guild in the game |
| activity_score | integer | The activity score of the guild in the game |
###### Guild Trait Structure
| Field | Type | Description |
| -------------- | ---------- | ----------------------------------------------- |
| emoji_id ^1^ | ?snowflake | The ID of the emoji associated with the trait |
| emoji_name ^1^ | ?string | The name of the emoji associated with the trait |
| emoji_animated | boolean | Whether the associated emoji is animated |
| label | string | The name of the trait |
| position | integer | The position of the trait in the array |
^1^ Only standard Unicode emoji names are accepted; custom guild emoji are not supported and will result in an error.
###### Guild Badge Type
| Value | Name |
| ---------- | -------------- |
| 0 | SWORD |
| 1 | WATER_DROP |
| 2 | SKULL |
| 3 | TOADSTOOL |
| 4 | MOON |
| 5 | LIGHTNING |
| 6 | LEAF |
| 7 | HEART |
| 8 | FIRE |
| 9 | COMPASS |
| ~~10~~ ^1^ | ~~CROSSHAIRS~~ |
| ~~11~~ ^1^ | ~~FLOWER~~ |
| ~~12~~ ^1^ | ~~FORCE~~ |
| ~~13~~ ^1^ | ~~GEM~~ |
| ~~14~~ ^1^ | ~~LAVA~~ |
| ~~15~~ ^1^ | ~~PSYCHIC~~ |
| ~~16~~ ^1^ | ~~SMOKE~~ |
| ~~17~~ ^1^ | ~~SNOW~~ |
| ~~18~~ ^1^ | ~~SOUND~~ |
| ~~19~~ ^1^ | ~~SUN~~ |
| ~~20~~ ^1^ | ~~WIND~~ |
| 21 | BUNNY |
| 22 | DOG |
| 23 | FROG |
| 24 | GOAT |
| 25 | CAT |
| 26 | DIAMOND |
| 27 | CROWN |
| 28 | TROPHY |
| 29 | MONEY_BAG |
| 30 | DOLLAR_SIGN |
| 31 | CLOVER |
| 32 | BLOSSOM |
| 33 | POTTED_PLANT |
| 34 | MAPLE |
| 35 | WILTED_FLOWER |
| 36 | BUTTERFLY |
| 37 | SNAIL |
| 38 | CATERPILLAR |
| 39 | SPIDER |
| 40 | BEE |
^1^ While these badge types can no longer be set, it is still possible to encounter users with a [primary guild badge](/resources/user#primary-guild-structure) of this type.
###### Guild Visibility
| Value | Name | Description |
| ----- | ----------------------- | ------------------------------------------------------------------------------------ |
| 1 | PUBLIC | This guild is considered public and can be viewed by anyone |
| 2 | RESTRICTED | This guild is considered private but cannot be viewed and joining requires an invite |
| 3 | PUBLIC_WITH_RECRUITMENT | The guild is considered public, allowing anyone to view it and submit a join request |
###### Example Guild Profile
```json
{
"id": "1241115476021481582",
"name": "Fehlerjäger",
"icon_hash": "b47f6747d7d6548b6f3eaf8c8e8af20c",
"member_count": 131,
"online_count": 53,
"description": "Do you enjoy finding those creepy crawlies? 🐛 We seek those with a keen eye and ability for uncovering hidden gems 🔎",
"brand_color_primary": "#7cf895",
"banner_hash": "1468ceeb0f9c384826b982b7eddbfa6f",
"game_application_ids": ["356869127241072640"],
"game_activity": {
"356869127241072640": {
"activity_level": 1,
"activity_score": 45
}
},
"tag": "BUG",
"badge": 6,
"badge_color_primary": "#32a070",
"badge_color_secondary": "#57b59e",
"badge_hash": "6082c2553b03b47ccaea5203567df3cf",
"traits": [
{
"emoji_id": null,
"emoji_name": null,
"emoji_animated": false,
"label": "Bug Hunting",
"position": 0
}
],
"features": ["MEMBER_VERIFICATION_MANUAL_APPROVAL", "COMMUNITY", "MEMBER_VERIFICATION_GATE_ENABLED"],
"visibility": 1,
"custom_banner_hash": null,
"premium_subscription_count": 13,
"premium_tier": 2
}
```
## Endpoints
List Discoverable Guilds
Returns a list of [discoverable guild](#discoverable-guild-object) objects representing the guilds that are available for the current user to discover.
When this endpoint is paginated normally, only discoverable guilds that are verified or partnered are returned. To get other discoverable guilds, you must either use the `guild_ids` query parameter or [search discovery](#searching-discovery).
###### Query String Params
| Field | Type | Description |
| -------------------- | ---------------- | -------------------------------------------------------------------------------------- |
| guild_ids? ^1^ | array[snowflake] | The IDs of the discoverable guilds to return (max 48) |
| application_ids? ^1^ | array[snowflake] | The IDs of the applications to return matching discoverable guilds for (max 48) |
| categories? ^1^ | array[integer] | The IDs of the [discovery categories](#discovery-category-object) to filter results by |
| limit? ^2^ | integer | The maximum number of guilds to return (max 48, default 30) |
| offset? ^2^ | integer | Number of guilds to skip before returning guilds |
^1^ Only one of `guild_ids`, `application_ids`, or `categories` may be specified. If both are specified, only `guild_ids` or `application_ids` is respected.
^2^ Pagination parameters are ignored if `guild_ids` or `application_ids` are specified.
###### Response Body
| Field | Type | Description |
| ------ | -------------------------------------------------------------- | ---------------------------------------------------- |
| guilds | array[[discoverable guild](#discoverable-guild-object) object] | The guilds that match the query |
| total | integer | The total number of guilds that match the query |
| limit | integer | The number of guilds returned in the response |
| offset | integer | The number of guilds skipped before returning guilds |
Search Discoverable Guilds
Returns a list of [discoverable guild](#discoverable-guild-object) objects that match the query.
This endpoint has the following immutable filters set:
- `approximate_member_count > 200`
- `approximate_presence_count > 0`
- `auto_removed: false`
###### Query String Params
| Field | Type | Description |
| ------------ | ------- | ----------------------------------------------------------------------------------- |
| query | string | The query to match (max 100 characters) |
| limit? | integer | The maximum number of guilds to return (max 48, default 24) |
| offset? | integer | Number of guilds to skip before returning guilds (max 2999) |
| category_id? | integer | The ID of the [discovery category](#discovery-category-object) to filter results by |
Search Published Guilds
Returns a list of [discoverable guild](#discoverable-guild-object) objects that have a landing web page and match the query. This endpoint is a proxy for [searching using the Algolia API](#searching-discovery). See the [Algolia Search documentation](https://www.algolia.com/doc/rest-api/search/) for more information.
This endpoint has the following immutable filters set:
- `approximate_member_count > 200`
- `approximate_presence_count > 0`
- `auto_removed: false`
- `is_published: true`
###### Query String Params
| Field | Type | Description |
| ------- | ------- | ----------------------------------------------------------- |
| query? | string | The query to match |
| limit? | integer | The maximum number of guilds to return (1-48, default 48) |
| offset? | integer | Number of guilds to skip before returning guilds (max 2999) |
Get Discovery Slug
Returns information about a guild's landing web page or monetization store page.
This endpoint requires the guild to either be discoverable and [published](#discovery-metadata-object) or have the [`CREATOR_STORE_PAGE` guild feature](/resources/guild#guild-features).
If a guild has both a landing web page and a monetization store page, the store page is prioritized.
###### Response Body
| Field | Type | Description |
| ----------- | -------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------- |
| slug | string | The guild's discovery slug; can be appended to `https://discord.com/servers/` to get the guild's discovery page |
| guild? | [discoverable guild](#discoverable-guild-object) object | The guild information, if the guild is discoverable |
| store_page? | [monetization store page](#monetization-store-page-structure) object | The guild's monetization store page, if enabled |
###### Monetization Store Page Structure
| Field | Type | Description |
| ----------------- | ------------------------------------------------------------------------------ | ----------------------------------------- |
| guild | [store page guild](#store-page-guild-structure) object | The guild information |
| role_subscription | [store page role subscription](#store-page-role-subscription-structure) object | The guild's role subscription information |
###### Store Page Guild Structure
| Field | Type | Description |
| -------------------------- | --------------------------------------------------------- | ------------------------------------------------------------------------------------- |
| id | snowflake | The ID of the guild |
| name | string | The name of the guild (2-100 characters) |
| icon_hash | ?string | The guild's [icon hash](/reference#cdn-formatting) |
| approximate_member_count | integer | Approximate number of members in the guild |
| approximate_presence_count | integer | Approximate number of online members in the guild |
| locked_server | boolean | Whether the entire guild is locked behind a role subscription |
| invite | ?partial [invite](/resources/invite#invite-object) object | A [special `CREATOR_PAGE` invite](/resources/invite#invite-target-type) for the guild |
###### Store Page Role Subscription Structure
| Field | Type | Description |
| -------------------- | -------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------- |
| settings | [role subscription settings](/resources/guild#role-subscription-settings-object) object | The guild's role subscription settings |
| group_listings | array[[role subscription group listing](/resources/guild#role-subscription-group-listing-object) object] | The guild's role subscription group listings |
| trials | array[[role subscription trial](/resources/guild#role-subscription-trial-object) object] | The guild's role subscription trials |
| subscriber_count | ?integer | The number of subscribers to the guild's role subscriptions, if public |
| benefit_channels | array[partial [channel](/resources/channel#channel-object) object] | The channels that are unlocked by role subscriptions |
| benefit_emojis | array[[emoji](/resources/emoji#emoji-object) object] | The emoji that are unlocked by role subscriptions |
| purchase_page_invite | ?partial [invite](/resources/invite#invite-object) object | A [special `ROLE_SUBSCRIPTIONS` invite](/resources/invite#invite-target-type) for the guild |
List Discovery Categories
Returns a list of [discovery category](#discovery-category-object) objects representing the available discovery categories.
###### Query String Params
| Field | Type | Description |
| ------------- | ------- | ----------------------------------------------------------------------------------------------- |
| locale? | string | The [language](/reference#locales) to return category names in (default "en-US") |
| primary_only? | boolean | Whether to only return categories that can be set as a guild's primary category (default false) |
Validate Discovery Search Term
Checks if a discovery search term is allowed.
###### Query String Params
| Field | Type | Description |
| ----- | ------ | --------------------------- |
| term | string | The search term to validate |
###### Response Body
| Field | Type | Description |
| ----- | ------- | ---------------------------------- |
| valid | boolean | Whether the provided term is valid |
###### Example Response
```json
{ "valid": true }
```
Get Guild Discovery Requirements
Returns the [discovery requirements](#discovery-requirements-object) object for the guild. Requires the `MANAGE_GUILD` permission.
Get Guild Discovery Metadata
Returns the [discovery metadata](#discovery-metadata-object) object for the guild. Requires the `MANAGE_GUILD` permission.
Modify Guild Discovery Metadata
Replaces the discovery metadata for the guild. Requires the `MANAGE_GUILD` permission. Returns the updated [discovery metadata](#discovery-metadata-object) object on success.
All parameters to this endpoint are optional and nullable. Omitting or setting a `null` value will set it to default.
###### JSON Params
| Field | Type | Description |
| ------------------------------ | ---------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------- |
| primary_category_id? | ?integer | The ID of the primary [discovery category](#discovery-category-object) set for the guild (default 0) |
| keywords? | ?array[string] | The discovery search keywords for the guild (max 10) |
| emoji_discoverability_enabled? | ?boolean | Whether the guild is shown as a source through custom emoji and stickers (default true) |
| is_published? | ?boolean | Whether the guild's landing web page is currently published (default false) |
| reasons_to_join? | ?array[[discovery reason](/resources/discovery#discovery-reason-structure) object] | The reasons to join the guild shown in the discovery web page (max 4) |
| social_links? | ?array[string] | The guild's social media links shown in the discovery web page (max 256 characters, max 9) |
| about? | ?string | The guild's long description shown in the discovery web page (max 2400 characters) |
Add Guild Discovery Subcategory
Adds a [discovery subcategory](#discovery-category-object) to the guild. Requires the `MANAGE_GUILD` permission. Returns a 204 empty response on success.
Remove Guild Discovery Subcategory
Removes a [discovery subcategory](#discovery-category-object) from the guild. Requires the `MANAGE_GUILD` permission. Returns a 204 empty response on success.
Get Guild Profile
Returns a [guild profile](#guild-profile-object) object for the given guild ID. User must be a member of the guild or the guild must be discoverable or have a [`PUBLIC` or `PUBLIC_WITH_RECRUITMENT` visibility](#guild-visibility).
Modify Guild Profile
Modifies the [guild profile](#guild-profile-object) for the given guild ID. Requires the `MANAGE_GUILD` permission. Returns the updated [guild profile](#guild-profile-object) object on success.
##### JSON Params
| Field | Type | Description |
| ------------------------- | --------------------------------------------------- | ---------------------------------------------------------------------------------------------- |
| name? | string | The name of the guild (2-100 characters) |
| icon? | ?[image data](/reference#cdn-data) | The guild's icon; animated icons are only shown when the guild has the `ANIMATED_ICON` feature |
| description? | ?string | The description for the guild (max 300 characters) |
| brand_color_primary? | string | The guild's accent color as a hexadecimal color string |
| game_application_ids? | array[snowflake] | The IDs of the applications representing the games the guild plays (max 20) |
| tag? ^1^ | ?string | The tag of the guild (2-4 characters) |
| badge ^1^ | integer | The [badge shown on the guild's tag](#guild-badge-type) |
| badge_color_primary ^1^ | ?string | The primary color of the badge as a hexadecimal color string |
| badge_color_secondary ^1^ | ?string | The secondary color of the badge as a hexadecimal color string |
| traits? | array[[guild trait](#guild-trait-structure) object] | Terms used to describe the guild's interest and personality (max 5) |
| visibility? | integer | The [visibility level](#guild-visibility) of the guild |
| custom_banner | ?[image data](/reference#cdn-data) | The guild's discovery splash |
^1^ Requires the [`GUILD_TAGS` guild feature](/resources/guild#guild-features).
---
# AI
Link: https://docs.discord.food/resources/ai
Staff-only endpoints for translating messages, paraphrasing thread titles, fixing grammar, and summarizing threads.
## Endpoints
Translate Message
Translates a message.
###### JSON Params
| Field | Type | Description |
| ------- | ------ | -------------------------------------------------------------------------------- |
| content | string | The content of the message to be translated (1-2000 characters) |
| locale | string | The [locale](/reference#locales) to translate the message into (1-10 characters) |
###### Response Body
| Field | Type | Description |
| ----------- | ------ | ------------------------------------- |
| content ^1^ | string | The translated content of the message |
^1^ If the AI cannot translate the message, the original content will be returned.
Paraphrase Thread Title
Paraphrases the title of a thread.
###### JSON Params
| Field | Type | Description |
| ------- | ------ | ---------------------------------------------------------------- |
| content | string | The content of the message to be paraphrased (1-2000 characters) |
###### Response Body
| Field | Type | Description |
| ----- | ------ | ----------------------------------- |
| title | string | The paraphrased title of the thread |
Fix Grammar
Fixes the grammar of a message.
###### JSON Params
| Field | Type | Description |
| ------- | ------ | -------------------------------------------------------------- |
| content | string | The content of the message to be corrected (1-2000 characters) |
###### Response Body
| Field | Type | Description |
| ------- | ------ | ---------------------------------- |
| content | string | The message with corrected grammar |
Summarize Thread
Summarizes the content of a thread. Returns a 204 empty response on success. The summary will be sent as a system message in the thread. Requires the `READ_MESSAGE_HISTORY` permission.
###### JSON Params
| Field | Type | Description |
| ---------- | ------- | --------------------------------------------------------------- |
| ephemeral? | boolean | Whether the summary message should be ephemeral (default false) |
---
# Guild Templates
Link: https://docs.discord.food/resources/guild-template
Templates represent a code that when used, creates a guild based on a snapshot of an existing guild. For a list of official templates, refer to [this Gist](https://gist.github.com/dolfies/f70b1de53a1d185d58563b9ca8bb248d).
### Guild Template Object
###### Guild Template Structure
| Field | Type | Description |
| --------------------------- | ----------------------------------------------------- | ------------------------------------------------------ |
| code | string | The code of the template (unique ID) |
| name | string | The name of the template (1-100 characters) |
| description | ?string | The description for the template (max 120 characters) |
| usage_count | integer | Number of times this template has been used |
| creator_id | snowflake | The ID of the user who created the template |
| creator | partial [user](/resources/user#user-object) object | The user who created the template |
| created_at | ISO8601 timestamp | When this template was created |
| updated_at | ISO8601 timestamp | When this template was last synced to the source guild |
| source_guild_id | snowflake | The ID of the guild this template is based on |
| serialized_source_guild ^1^ | partial [guild](/resources/guild#guild-object) object | The guild snapshot this template contains |
| is_dirty | ?boolean | Whether the template has unsynced changes |
^1^ This partial guild object is special in that it and the objects within always contain applicable optional fields (even if they're not applicable).
This leads to unexpected behavior, such as `available_tags` being serialized for voice channels.
Additionally, the main guild object is missing the `id` field, and all other `id` fields are not real snowflakes.
###### Example Guild Template Object
```json
{
"code": "2TffvPucqHkN",
"name": "Blank Server",
"description": null,
"usage_count": 34729,
"creator_id": "268473310986240001",
"creator": {
"id": "268473310986240001",
"username": "discordapp",
"avatar": "f749bb0cbeeb26ef21eca719337d20f1",
"discriminator": "0",
"public_flags": 4325376,
"banner": null,
"accent_color": null,
"global_name": null,
"avatar_decoration_data": null,
"primary_guild": null
},
"created_at": "2020-04-17T20:59:35+00:00",
"updated_at": "2020-04-17T20:59:35+00:00",
"source_guild_id": "700811170902179862",
"serialized_source_guild": {
"name": "Blank Server",
"description": null,
"region": "us-west",
"verification_level": 0,
"default_message_notifications": 0,
"explicit_content_filter": 0,
"preferred_locale": "en-US",
"afk_channel_id": null,
"afk_timeout": 300,
"system_channel_id": 2,
"system_channel_flags": 0,
"roles": [
{
"id": 0,
"name": "@everyone",
"permissions": "2248329584430657",
"color": 0,
"hoist": false,
"mentionable": false,
"icon": null,
"unicode_emoji": null
}
],
"channels": [
{
"id": 1,
"type": 4,
"name": "Text Channels",
"position": 0,
"topic": null,
"bitrate": 64000,
"user_limit": 0,
"nsfw": false,
"rate_limit_per_user": 0,
"parent_id": null,
"default_auto_archive_duration": null,
"permission_overwrites": [],
"available_tags": null,
"template": "",
"default_reaction_emoji": null,
"default_thread_rate_limit_per_user": null,
"default_sort_order": null,
"default_forum_layout": null,
"icon_emoji": null,
"theme_color": null
},
{
"id": 2,
"type": 0,
"name": "general",
"position": 0,
"topic": null,
"bitrate": 64000,
"user_limit": 0,
"nsfw": false,
"rate_limit_per_user": 0,
"parent_id": 1,
"default_auto_archive_duration": null,
"permission_overwrites": [],
"available_tags": null,
"template": "",
"default_reaction_emoji": null,
"default_thread_rate_limit_per_user": null,
"default_sort_order": null,
"default_forum_layout": null,
"icon_emoji": null,
"theme_color": null
},
{
"id": 3,
"type": 4,
"name": "Voice Channels",
"position": 0,
"topic": null,
"bitrate": 64000,
"user_limit": 0,
"nsfw": false,
"rate_limit_per_user": 0,
"parent_id": null,
"default_auto_archive_duration": null,
"permission_overwrites": [],
"available_tags": null,
"template": "",
"default_reaction_emoji": null,
"default_thread_rate_limit_per_user": null,
"default_sort_order": null,
"default_forum_layout": null,
"icon_emoji": null,
"theme_color": null
},
{
"id": 4,
"type": 2,
"name": "General",
"position": 0,
"topic": null,
"bitrate": 64000,
"user_limit": 0,
"nsfw": false,
"rate_limit_per_user": 0,
"parent_id": 3,
"default_auto_archive_duration": null,
"permission_overwrites": [],
"available_tags": null,
"template": "",
"default_reaction_emoji": null,
"default_thread_rate_limit_per_user": null,
"default_sort_order": null,
"default_forum_layout": null,
"icon_emoji": null,
"theme_color": null
}
]
},
"is_dirty": null
}
```
## Endpoints
Get Guild Template
Returns a [guild template](#guild-template-object) object for the given code.
Use Guild Template
Create a new guild based on a template. Returns a [guild](/resources/guild#guild-object) object on success. Fires a [Guild Create](/gateway/gateway-events#guild-create) Gateway event.
###### JSON Params
| Field | Type | Description |
| ----- | --------------------------------- | ---------------------------------------- |
| name | string | The name of the guild (2-100 characters) |
| icon? | [image data](/reference#cdn-data) | 128x128 image for the guild's icon |
List Guild Templates
Returns an array of [guild template](#guild-template-object) objects. Requires the `MANAGE_GUILD` permission.
Create Guild Template
Creates a template for the guild. Requires the `MANAGE_GUILD` permission. Returns the created [guild template](#guild-template-object) object on success.
###### JSON Params
| Field | Type | Description |
| ------------ | ------- | ----------------------------------------------------- |
| name | string | The name of the template (1-100 characters) |
| description? | ?string | The description for the template (max 120 characters) |
Sync Guild Template
Syncs the template to the guild's current state. Requires the `MANAGE_GUILD` permission. Returns the updated [guild template](#guild-template-object) object on success.
Modify Guild Template
Modifies the template's metadata. Requires the `MANAGE_GUILD` permission. Returns the updated [guild template](#guild-template-object) object on success.
###### JSON Params
| Field | Type | Description |
| ------------ | ------- | ----------------------------------------------------- |
| name? | string | The name of the template (1-100 characters) |
| description? | ?string | The description for the template (max 120 characters) |
Delete Guild Template
Deletes the template. Requires the `MANAGE_GUILD` permission. Returns the deleted [guild template](#guild-template-object) object on success.
---
# Audit Log
Link: https://docs.discord.food/resources/audit-log
When an administrative action is performed in a guild, an entry is added to its audit log. Viewing audit logs requires the `VIEW_AUDIT_LOG` permission and can be fetched using the [List Guild Audit Log Entries](#list-guild-audit-log-entries) endpoint. All audit log entries are stored for 45 days.
### Audit Reason
When performing an eligible action using the API, users can pass an `X-Audit-Log-Reason` header to indicate why the action was taken. More information is in the [audit log entry](#audit-log-entry-object) section.
### Audit Log Entry Object
Each audit log entry represents a single administrative action (or [event](#audit-log-action-type)), indicated by `action_type`. Most entries contain one to many changes in the `changes` array that affected an entity in Discord—whether that's a user, channel, guild, emoji, or something else.
The information (and structure) of an entry's changes will be different depending on its type. For example, in `MEMBER_ROLE_UPDATE` events there is only one change: a member is either added or removed from a specific role. However, in `CHANNEL_CREATE` events there are many changes, including (but not limited to) the channel's name, type, and permission overwrites added. More details are in the [change object](#audit-log-change-object) section.
Users can specify why an administrative action is being taken by passing an `X-Audit-Log-Reason` request header, which will be stored as the audit log entry's `reason` field. The `X-Audit-Log-Reason` header supports up to 512 URL-encoded UTF-8 characters. Reasons are visible in the client and when fetching audit log entries with the API.
###### Audit Log Entry Structure
| Field | Type | Description |
| ----------- | -------------------------------------------------------------- | ---------------------------------------------------------- |
| target_id | ?snowflake | ID of the affected entity (webhook, user, role, etc.) |
| changes? | array[[audit log change](#audit-log-change-object) object] | Changes made to the `target_id`` |
| user_id | ?snowflake | The user who made the changes |
| id | snowflake | The ID of the entry |
| action_type | integer | The [type of action](#audit-log-action-type) that occurred |
| options? | [optional audit entry info](#optional-audit-entry-info) object | Additional info for certain action types |
| reason? | string | The reason for the change (max 512 characters) |
For `APPLICATION_COMMAND_PERMISSION_UPDATE` events, the `target_id` is the command ID or the application ID since the `changes` array represents the entire `permissions` property on the [guild permissions](/interactions/application-commands#guild-application-command-permissions-structure) object.
###### Audit Log Action Type
The table below lists audit log events and values (the `action_type` field) that you may receive.
The **Object Changed** column notes which object's values may be included in the entry. Though there are exceptions, possible keys in the `changes` array typically correspond to the object's fields. The descriptions and types for those fields can be found in the linked documentation for the object.
If no object is noted, there won't be a `changes` array in the entry, though other fields like the `target_id` still exist and many have fields in the [`options` array](#optional-audit-entry-info).
You should assume that you may run into any field for the changed object, though none are guaranteed to be present. In most cases only a subset of the object's fields will be in the `changes` array.
| Value | Name | Description | Object Changed |
| ------- | ------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------- |
| 1 | GUILD_UPDATE | Guild settings were updated | [Guild](/resources/guild#guild-object) |
| 10 | CHANNEL_CREATE | Channel was created | [Channel](/resources/channel#channel-object) |
| 11 | CHANNEL_UPDATE | Channel settings were updated | [Channel](/resources/channel#channel-object) |
| 12 | CHANNEL_DELETE | Channel was deleted | [Channel](/resources/channel#channel-object) |
| 13 | CHANNEL_OVERWRITE_CREATE | Permission overwrite was added to a channel | [Channel Overwrite](/resources/channel#permission-overwrite-object) |
| 14 | CHANNEL_OVERWRITE_UPDATE | Permission overwrite was updated for a channel | [Channel Overwrite](/resources/channel#permission-overwrite-object) |
| 15 | CHANNEL_OVERWRITE_DELETE | Permission overwrite was deleted from a channel | [Channel Overwrite](/resources/channel#permission-overwrite-object) |
| 20 | MEMBER_KICK | Member was removed from guild | |
| 21 | MEMBER_PRUNE | Members were pruned from guild | |
| 22 | MEMBER_BAN_ADD | Member was banned from guild | |
| 23 | MEMBER_BAN_REMOVE | Member was unbanned from guild | |
| 24 | MEMBER_UPDATE | Member was updated in guild | [Member](/resources/guild#guild-member-object) |
| 25 | MEMBER_ROLE_UPDATE | Member was added or removed from a role | [Partial Role](#partial-role-object) ^1^ |
| 26 | MEMBER_MOVE | Member was moved to a different voice channel | |
| 27 | MEMBER_DISCONNECT | Member was disconnected from a voice channel | |
| 28 | BOT_ADD | Bot user was added to guild | |
| 30 | ROLE_CREATE | Role was created | [Role](/resources/guild#role-object) |
| 31 | ROLE_UPDATE | Role was edited | [Role](/resources/guild#role-object) |
| 32 | ROLE_DELETE | Role was deleted | [Role](/resources/guild#role-object) |
| 40 | INVITE_CREATE | Guild invite was created | [Invite](/resources/invite#invite-object) and [Invite Metadata](/resources/invite#invite-metadata-object) ^1^ |
| 41 | INVITE_UPDATE | Guild invite was updated | [Invite](/resources/invite#invite-object) and [Invite Metadata](/resources/invite#invite-metadata-object) ^1^ |
| 42 | INVITE_DELETE | Guild invite was deleted | [Invite](/resources/invite#invite-object) and [Invite Metadata](/resources/invite#invite-metadata-object) ^1^ |
| 50 | WEBHOOK_CREATE | Webhook was created | [Webhook](/resources/webhook#webhook-object) ^1^ |
| 51 | WEBHOOK_UPDATE | Webhook properties or channel were updated | [Webhook](/resources/webhook#webhook-object) ^1^ |
| 52 | WEBHOOK_DELETE | Webhook was deleted | [Webhook](/resources/webhook#webhook-object) ^1^ |
| 60 | EMOJI_CREATE | Emoji was created | [Emoji](/resources/emoji#emoji-object) |
| 61 | EMOJI_UPDATE | Emoji name was updated | [Emoji](/resources/emoji#emoji-object) |
| 62 | EMOJI_DELETE | Emoji was deleted | [Emoji](/resources/emoji#emoji-object) |
| 72 | MESSAGE_DELETE ^2^ | Single message was deleted | |
| 73 | MESSAGE_BULK_DELETE | Multiple messages were deleted | |
| 74 | MESSAGE_PIN | Message was pinned to a channel | |
| 75 | MESSAGE_UNPIN | Message was unpinned from a channel | |
| 80 | INTEGRATION_CREATE | Integration was added to guild | [Integration](/resources/integration#integration-object) |
| 81 | INTEGRATION_UPDATE | Integration was updated (e.g. its scopes were updated) | [Integration](/resources/integration#integration-object) |
| 82 | INTEGRATION_DELETE | Integration was removed from guild | [Integration](/resources/integration#integration-object) |
| 83 | STAGE_INSTANCE_CREATE | Stage instance was created (stage channel becomes live) | [Stage Instance](/resources/stage-instance#stage-instance-object) |
| 84 | STAGE_INSTANCE_UPDATE | Stage instance details were updated | [Stage Instance](/resources/stage-instance#stage-instance-object) |
| 85 | STAGE_INSTANCE_DELETE | Stage instance was deleted (stage channel no longer live) | [Stage Instance](/resources/stage-instance#stage-instance-object) |
| 90 | STICKER_CREATE | Sticker was created | [Sticker](/resources/sticker#sticker-object) |
| 91 | STICKER_UPDATE | Sticker details were updated | [Sticker](/resources/sticker#sticker-object) |
| 92 | STICKER_DELETE | Sticker was deleted | [Sticker](/resources/sticker#sticker-object) |
| 100 | GUILD_SCHEDULED_EVENT_CREATE | Event was created | [Guild Scheduled Event](/resources/guild-scheduled-event#guild-scheduled-event-object) |
| 101 | GUILD_SCHEDULED_EVENT_UPDATE | Event was updated | [Guild Scheduled Event](/resources/guild-scheduled-event#guild-scheduled-event-object) |
| 102 | GUILD_SCHEDULED_EVENT_DELETE | Event was cancelled | [Guild Scheduled Event](/resources/guild-scheduled-event#guild-scheduled-event-object) |
| 110 | THREAD_CREATE | Thread was created in a channel | [Thread](/resources/channel#thread-metadata-object) |
| 111 | THREAD_UPDATE | Thread was updated | [Thread](/resources/channel#thread-metadata-object) |
| 112 | THREAD_DELETE | Thread was deleted | [Thread](/resources/channel#thread-metadata-object) |
| 121 | APPLICATION_COMMAND_PERMISSION_UPDATE | Permissions were updated for a command | [Application Command Permission](/interactions/application-commands#application-command-permissions-object) ^1^ |
| 130 | SOUNDBOARD_SOUND_CREATE | Soundboard sound was created | [Soundboard Sound](/resources/soundboard#soundboard-sound-object) |
| 131 | SOUNDBOARD_SOUND_UPDATE | Soundboard sound was updated | [Soundboard Sound](/resources/soundboard#soundboard-sound-object) |
| 132 | SOUNDBOARD_SOUND_DELETE | Soundboard sound was deleted | [Soundboard Sound](/resources/soundboard#soundboard-sound-object) |
| 140 | AUTO_MODERATION_RULE_CREATE | AutoMod rule was created | [AutoMod Rule](/resources/auto-moderation#automod-rule-object) |
| 141 | AUTO_MODERATION_RULE_UPDATE | AutoMod rule was updated | [AutoMod Rule](/resources/auto-moderation#automod-rule-object) |
| 142 | AUTO_MODERATION_RULE_DELETE | AutoMod rule was deleted | [AutoMod Rule](/resources/auto-moderation#automod-rule-object) |
| 143 | AUTO_MODERATION_BLOCK_MESSAGE | Message was blocked by AutoMod | |
| 144 | AUTO_MODERATION_FLAG_TO_CHANNEL | Message was flagged by AutoMod | |
| 145 | AUTO_MODERATION_USER_COMMUNICATION_DISABLED | Member was timed out by AutoMod | |
| 146 | AUTO_MODERATION_QUARANTINE_USER | Member was quarantined by AutoMod | |
| 150 | CREATOR_MONETIZATION_REQUEST_CREATED | Creator monetization request was created | |
| 151 | CREATOR_MONETIZATION_TERMS_ACCEPTED | Creator monetization terms were accepted | |
| 163 | ONBOARDING_PROMPT_CREATE | Onboarding prompt was created | [Onboarding Prompt](/resources/guild#onboarding-prompt-structure) |
| 164 | ONBOARDING_PROMPT_UPDATE | Onboarding prompt was updated | [Onboarding Prompt](/resources/guild#onboarding-prompt-structure) |
| 165 | ONBOARDING_PROMPT_DELETE | Onboarding prompt was deleted | [Onboarding Prompt](/resources/guild#onboarding-prompt-structure) |
| 166 | ONBOARDING_CREATE | Onboarding was initialized | [Onboarding](/resources/guild#onboarding-object) |
| 167 | ONBOARDING_UPDATE | Onboarding was updated | [Onboarding](/resources/guild#onboarding-object) |
| 171 | GUILD_HOME_FEATURE_ITEM | Message was featured in guild home | |
| 172 | GUILD_HOME_REMOVE_ITEM | Message was removed from guild home | |
| ~~180~~ | ~~HARMFUL_LINKS_BLOCKED_MESSAGE~~ | ~~Message blocked by harmful links filter~~ | |
| 190 | HOME_SETTINGS_CREATE | New member welcome was initialized | [New Member Welcome](/resources/guild#new-member-welcome-object) |
| 191 | HOME_SETTINGS_UPDATE | New member welcome was updated | [New Member Welcome](/resources/guild#new-member-welcome-object) |
| 192 | VOICE_CHANNEL_STATUS_CREATE | Voice channel status was updated | [Channel](/resources/channel#channel-object) |
| 193 | VOICE_CHANNEL_STATUS_DELETE | Voice channel status was deleted | [Channel](/resources/channel#channel-object) |
| ~~194~~ | ~~CLYDE_AI_PROFILE_UPDATE~~ | ~~Clyde AI profile was updated~~ | |
| 200 | GUILD_SCHEDULED_EVENT_EXCEPTION_CREATE | Exception was created for a guild scheduled event | [Guild Scheduled Event Exception](/resources/guild-scheduled-event#guild-scheduled-event-exception-object) |
| 201 | GUILD_SCHEDULED_EVENT_EXCEPTION_UPDATE | Exception was updated for a guild scheduled event | [Guild Scheduled Event Exception](/resources/guild-scheduled-event#guild-scheduled-event-exception-object) |
| 202 | GUILD_SCHEDULED_EVENT_EXCEPTION_DELETE | Exception was deleted for a guild scheduled event | [Guild Scheduled Event Exception](/resources/guild-scheduled-event#guild-scheduled-event-exception-object) |
| 210 | GUILD_MEMBER_VERIFICATION_UPDATE | Member verification settings were updated | [Member Verification](/resources/guild#member-verification-object) ^1^ |
| 211 | GUILD_PROFILE_UPDATE | Guild profile was updated | [Guild Profile](/resources/discovery#guild-profile-object) ^1^ |
| 212 | GUILD_MIGRATE_PIN_PERMISSION | `MANAGE_MESSAGES` permission was migrated to the new `PIN_MESSAGES` permission | |
| 213 | GUILD_MIGRATE_BYPASS_SLOWMODE_PERMISSION | `MANAGE_MESSAGES`, `MANAGE_CHANNEL`, and `MANAGE_THREADS` permissions were migrated to the new `BYPASS_SLOWMODE` permission | |
^1^ Object has exception(s) to available keys. See the [exceptions](#audit-log-change-exceptions) section below for details.
^2^ Individual messages deleted by the author or a bot are not logged.
###### Optional Audit Entry Info
| Field | Type | Description | Action Type |
| --------------------------------- | --------- | ---------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------- |
| application_id | snowflake | The ID of the application whose permissions were targeted | `APPLICATION_COMMAND_PERMISSION_UPDATE` |
| auto_moderation_rule_name | string | The name of the AutoMod rule that was triggered | `AUTO_MODERATION_BLOCK_MESSAGE`, `AUTO_MODERATION_FLAG_TO_CHANNEL`, `AUTO_MODERATION_USER_COMMUNICATION_DISABLED`, `AUTO_MODERATION_QUARANTINE_USER` |
| auto_moderation_rule_trigger_type | string | The [trigger type of the AutoMod rule](/resources/auto-moderation#automod-trigger-type) that was triggered | `AUTO_MODERATION_BLOCK_MESSAGE`, `AUTO_MODERATION_FLAG_TO_CHANNEL`, `AUTO_MODERATION_USER_COMMUNICATION_DISABLED`, `AUTO_MODERATION_QUARANTINE_USER` |
| channel_id | snowflake | The channel in which the entities were targeted | `MEMBER_MOVE`, `MESSAGE_PIN`, `MESSAGE_UNPIN`, `MESSAGE_DELETE`, `STAGE_INSTANCE_CREATE`, `STAGE_INSTANCE_UPDATE`, `STAGE_INSTANCE_DELETE` |
| count? | string | Number of entities that were targeted | `MESSAGE_DELETE`, `MESSAGE_BULK_DELETE`, `MEMBER_DISCONNECT`, `MEMBER_MOVE` |
| delete_member_days? | string | Number of days after which inactive members were kicked | `MEMBER_PRUNE` |
| event_exception_id | snowflake | The ID of the guild scheduled event exception that was targeted | `GUILD_SCHEDULED_EVENT_EXCEPTION_CREATE`, `GUILD_SCHEDULED_EVENT_EXCEPTION_UPDATE`, `GUILD_SCHEDULED_EVENT_EXCEPTION_DELETE` |
| id | snowflake | The ID of the overwritten entity | `CHANNEL_OVERWRITE_CREATE`, `CHANNEL_OVERWRITE_UPDATE`, `CHANNEL_OVERWRITE_DELETE` |
| integration_type? | string | The [type of integration](/resources/integration#integration-type) which performed the action | `MEMBER_KICK`, `MEMBER_ROLE_UPDATE` |
| members_removed? | string | Number of members removed by the prune | `MEMBER_PRUNE` |
| message_id | snowflake | The ID of the message that was targeted | `MESSAGE_PIN`, `MESSAGE_UNPIN` |
| role_name? | string | The name of the role (only present if type is "0") | `CHANNEL_OVERWRITE_CREATE`, `CHANNEL_OVERWRITE_UPDATE`, `CHANNEL_OVERWRITE_DELETE` |
| status | string | The new status of the voice channel | `VOICE_CHANNEL_STATUS_UPDATE` |
| type ^1^ | string | The [type of overwritten entity](/resources/channel#permission-overwrite-type) | `CHANNEL_OVERWRITE_CREATE`, `CHANNEL_OVERWRITE_UPDATE`, `CHANNEL_OVERWRITE_DELETE` |
^1^ Due to technical limitations, this field is always serialized as a string, not an integer.
### Audit Log Change Object
Many audit log events include a `changes` array in their [entry object](#audit-log-entry-structure). The [structure for the individual changes](#audit-log-change-structure) varies based on the event type and its changed objects, so apps shouldn't depend on a single pattern of handling audit log events.
###### Audit Log Change Structure
Some events don't follow the same pattern as other audit log events. Details about these exceptions are explained in [the next section](#audit-log-change-exceptions).
If `new_value` is not present in the change object while `old_value` is, it indicates that the property has been reset or set to `null`. If `old_value` isn't included, it indicated that the property was previously `null`.
| Field | Type | Description |
| ---------- | ----------------------------------- | --------------------------------------------------------------------------------- |
| new_value? | mixed (matches object field's type) | New value of the key |
| old_value? | mixed (matches object field's type) | Old value of the key |
| key | string | Name of the changed entity, with a few [exceptions](#audit-log-change-exceptions) |
###### Audit Log Change Exceptions
For most objects, the change keys may be any field on the changed object. The following table details the exceptions to this pattern.
In addition to the exceptions below, the `key` field may be appended with `_hash` when the change is related to a CDN asset. For example, `banner_hash` is present instead of `banner`.
| Object Changed | Change Key Exceptions | Change Object Exceptions |
| -------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| [AutoMod Rule](/resources/auto-moderation#automod-rule-object) | `$add_keyword_filter`, `$remove_keyword_filter`, `$add_regex_patterns`, `$remove_regex_patterns`, `$add_allow_list`, `$remove_allow_list` as keys | `new_value` and `old_value` are arrays of strings representing the keywords, regex patterns, or allow list items that were added or removed |
| [Application Command Permission](/interactions/application-commands#application-command-permissions-structure) | A snowflake is used as the key | The `changes` array contains objects with a `key` field representing the entity whose command was affected (role, channel, or user ID), a previous permissions object (with an `old_value` key), and an updated permissions object (with a `new_value` key) |
| [Guild Member](/resources/guild#guild-member-object) | Additional `bypasses_verification` key (instead of object's `flags`) | `new_value` and `old_value` are booleans representing whether the member bypasses verification |
| [Invite](/resources/invite#invite-object) and [Invite Metadata](/resources/invite#invite-metadata-object) | Additional `channel_id` and `inviter_id` keys (instead of object's `channel.id` and `inviter.id`) | |
| [Partial Role](#partial-role-object) | `$add` and `$remove` as keys | `new_value` is an array of objects that contain the role `id` and `name` |
| [Member Verification](/resources/guild#member-verification-object) | `verification_enabled` and `manual_approval_enabled` as keys | `new_value` and `old_value` are booleans representing whether verification or manual approval is enabled |
| [Guild Profile](/resources/discovery#guild-profile-object) | Additional `server_tag` key (instead of object's `tag`) | |
### Partial Integration Object
###### Partial Integration Structure
| Field | Type | Description |
| --------------- | ---------------------------------------------------------------------- | ------------------------------------------------------------------ |
| id | snowflake | The ID of the integration |
| name | string | The name of the integration |
| type | string | The [type of integration](/resources/integration#integration-type) |
| account | [account](/resources/integration#integration-account-structure) object | The integration's account information |
| application_id? | snowflake | The OAuth2 application for Discord integrations |
###### Example Partial Integration
```json
{
"id": "1029376264039039006",
"type": "discord",
"name": "Good University",
"account": {
"id": "971811349262917662",
"name": "Good University"
},
"application_id": "971811349262917662"
}
```
### Partial Role Object
###### Partial Role Structure
| Field | Type | Description |
| ----- | --------- | -------------------- |
| id | snowflake | The ID of the role |
| name | string | The name of the role |
###### Example Partial Role
```json
{
"name": "I am a role",
"id": "584120723283509258"
}
```
## Endpoints
List Guild Audit Log Entries
Returns the audit log for the guild. Requires the `VIEW_AUDIT_LOG` permission.
###### Query String Params
| Field | Type | Description |
| ------------ | --------- | ------------------------------------------------------------------ |
| before? | snowflake | Get entries before this entry ID |
| after? | snowflake | Get entries after this entry ID |
| limit? | integer | Max number of entries to return (1-100, default 50) |
| user_id? | snowflake | Get actions made by a specific user |
| target_id? | snowflake | Get actions affecting a specific entity |
| action_type? | integer | The [type of audit log event](#audit-log-action-type) to filter by |
###### Response Body
| Field | Type | Description |
| ---------------------- | ---------------------------------------------------------------------------------------------------- | -------------------------------------------------- |
| audit_log_entries | array[[audit log entry](#audit-log-entry-object) object] | Audit log entries |
| application_commands | array[[application command](/interactions/application-commands#application-command-object) object] | Application commands referenced in the audit log |
| auto_moderation_rules | array[[automod rule](/resources/auto-moderation#automod-rule-object) object] | AutoMod rules referenced in the audit log |
| guild_scheduled_events | array[[guild scheduled event](/resources/guild-scheduled-event#guild-scheduled-event-object) object] | Guild scheduled events referenced in the audit log |
| integrations | array[partial [integration](#partial-integration-object) object] | Partial integrations referenced in the audit log |
| threads | array[[channel](/resources/channel#channel-object) object] | Threads referenced in the audit log |
| users | array[partial [user](/resources/user#user-object) object] | Users referenced in the audit log |
| webhooks | array[[webhook](/resources/webhook#webhook-object) object] | Webhooks referenced in the audit log |
---
# Application Directory
Link: https://docs.discord.food/resources/application-directory
The application directory allows users to find fun and entertaining applications with special filters to tailor their experience and the kind of applications that are shown.
### Application Directory Entry Object
###### Application Directory Entry Structure
| Field | Type | Description |
| ----------------------------------- | -------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------ |
| guild_count | integer | Approximate number of guilds the application is in |
| carousel_items? | array[[carousel items](#application-directory-carousel-item-structure) object] | The media to show with the application |
| supported_locales | array[string] | The [locales](/reference#locales) supported by the application |
| external_urls? | array[[external url](#application-directory-external-url-structure) object] | External links related to the application |
| popular_application_command_ids? | array[snowflake] | The IDs of the application's most popular application commands (max 5) |
| popular_application_commands? | array[[application command](/interactions/application-commands#application-command-object) object] | The application's most popular application commands (max 5) |
| detailed_description? | string | The detailed overview of the application |
| short_description | string | The short overview of the application |
| short_description_localizations? | ?map[string, string] | The short overview of the application for each [locale](/reference#locales) |
| detailed_description_localizations? | ?map[string, string] | The detailed overview of the application for each [locale](/reference#locales) |
###### Application Directory Carousel Item Structure
| Field | Type | Description |
| --------- | ------- | -------------------------------------------------------------- |
| type | integer | The [type of media](#application-directory-carousel-item-type) |
| url | string | Source URL of the media |
| proxy_url | string | A proxied URL of the media |
###### Application Directory Carousel Item Type
| Value | Name | Description |
| ----- | ----- | --------------------------------------- |
| 1 | IMAGE | Supports both static images and gifs |
| 2 | VIDEO | Supports both static videos and YouTube |
###### Application Directory External URL Structure
| Field | Type | Description |
| ----- | ------ | -------------------------------- |
| name | string | The name to display for the link |
| url | string | The URL to redirect the user to |
###### Application Directory Item Type
| Value | Name | Description |
| ----- | ------------------ | ------------------------------------------ |
| 1 | APPLICATION | A regular application that's shown |
| 2 | LINK | A directory entry that redirects to a link |
| 3 | APPLICATION_BANNER | A promotional application banner |
###### Application Directory Request Surface
| Value | Name | Description |
| ----- | ---------------------------- | ----------------------------------- |
| 1 | APPLICATION_DIRECTORY | Application directory |
| 2 | APP_LAUNCHER_IN_TEXT | App Launcher |
| 3 | APP_LAUNCHER_IN_VOICE_BANNER | App Launcher within a voice context |
### Application Directory Category Object
###### Application Directory Category Structure
| Field | Type | Description |
| ----- | ------- | --------------------------------------------- |
| id | integer | The numerical ID associated with the category |
| name | string | The category label |
## Endpoints
List Application Directory Categories
Returns a list of [application directory category](#application-directory-category-object) objects representing the available application categories.
###### Query String Params
| Field | Type | Description |
| ------- | ------ | ---------------------------------------------------------------------------- |
| locale? | string | The [language](/reference#locales) to return categories in (default "en-US") |
List Application Directory Collections
Returns a list of the available [application directory collection](#application-directory-collection-structure) objects.
###### Query String Params
| Field | Type | Description |
| ----------------- | ------- | ------------------------------------------------------------------------------------------------------------------ |
| surface? | integer | The [request surface](#application-directory-request-surface), used for analytics |
| active_state? ^1^ | integer | Filter applications by their [directory active state](#application-directory-active-state-type) (default `ACTIVE`) |
| platform? | integer | The [platform](#application-directory-platform-flags) to filter by |
| locale? | string | The [language](/reference#locales) to return collections in (default "en-US") |
| cache? ^1^ | boolean | Whether to return cached results (default true) |
^1^ Only usable by Discord employees.
###### Application Directory Collection Structure
| Field | Type | Description |
| -------------------------------------- | ------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------- |
| id | string | The ID of the collection |
| type | integer | The type of [entry](#application-directory-item-type) item it is |
| position | integer | The hierarchical order to make the collection appear in |
| platforms | integer | The [platforms](#application-directory-platform-flags) the collection supports |
| active_state | integer | Returns the [active state](#application-directory-active-state-type) of the application |
| flags | integer | The application [flags](/resources/application#application-flags) |
| title | string | The collection's title |
| description | string | Short description of the collection |
| application_directory_collection_items | array[[application directory collection item](#application-directory-collection-item-structure) object] | The applications in the collection |
###### Application Directory Collection Item Structure
| Field | Type | Description |
| ----------- | --------------------------------------------------------------- | ---------------------------------------------------------------------- |
| id | snowflake | The ID of the collection item |
| type | integer | The [type of item](#application-directory-item-type) |
| position | integer | The position of the item in the collection |
| flags | integer | The application [flags](/resources/application#application-flags) |
| image_hash | ?string | The image hash of the item's [banner image](/reference#cdn-formatting) |
| application | [application](/resources/application#application-object) object | The application in the collection item |
###### Application Directory Active State Type
| Value | Name | Description |
| ----- | ------- | ------------------------------------ |
| 0 | PREVIEW | Inactive and hidden from public view |
| 1 | ACTIVE | Active and can be seen by the public |
###### Application Directory Platform Flags
| Value | Name | Description |
| -------- | ------- | ------------------------------------ |
| 1 \<\< 0 | IOS | Application supports iOS clients |
| 1 \<\< 1 | ANDROID | Application supports Android clients |
| 1 \<\< 2 | WEB | Application supports web clients |
Get Application Directory Application
Returns a partial [application](/resources/application#application-object) object for the given ID.
###### Query String Params
| Field | Type | Description |
| ------------------- | ------- | -------------------------------------------------------------------------------------------- |
| locale? | string | The [language](/reference#locales) to return application details in (default "en-US") |
| nocache? | boolean | Whether to bypass cache for the response (default false) |
| with_localizations? | boolean | Whether to also return localizations for the detailed and short descriptions (default false) |
Get Application Directory Application Embed
Returns a partial [application](/resources/application#application-object) object for the given ID.
###### Query String Params
| Field | Type | Description |
| ------------------- | ------- | -------------------------------------------------------------------------------------------- |
| with_localizations? | boolean | Whether to also return localizations for the detailed and short descriptions (default false) |
List Application Directory Similar Applications
Returns applications similar to the given application ID.
###### Query String Params
| Field | Type | Description |
| --------- | ------- | -------------------------------------------------------------------------------------- |
| guild_id? | string | The ID of the guild the request originated from |
| page? | integer | The page to fetch results from (max 1000, default 1) |
| locale? | string | The [language](/reference#locales) to return similar applications in (default "en-US") |
###### Response Body
| Field | Type | Description |
| ------------ | --------------------------------------------------------------- | ------------------------------------------------------------------- |
| applications | array[[application](/resources/application#application-object)] | Applications that are similar to the current application |
| num_pages | integer | The number of pages containing similar applications (max 1000) |
| load_id | string | The unique identifier for the application directory recommendations |
Search Applications Directory
Returns the application directory search results.
###### Query String Params
| Field | Type | Description |
| -------------------------------------------------------------- | ------- | ----------------------------------------------------------------------------------------------------------------------- |
| query? | string | The query to match (max 100 characters) |
| guild_id? | string | The ID of the guild the request originated from |
| page? | integer | The page to fetch results from (max 1000, default 1) |
| page_size? | integer | The limit of items per page (1-100) |
| category_id? | integer | The category to filter results by |
| locale? | string | The [language](/reference#locales) to return search results in (default "en-US") |
| min_user_install_command_count? | integer | The minimum amount of application user installs to filter by (max 100) (default 0) |
| exclude_apps_with_custom_install_url? | boolean | Whether to exclude applications with `custom_install_url` (default false) |
| exclude_non_embedded_apps? | boolean | Whether to exclude applications without the [`EMBEDDED` flag](/resources/application#application-flags) (default false) |
| exclude_embedded_apps_without_primary_entry_point_app_command? | boolean | Whether to exclude embedded applications without a primary entry point command (default false) |
| source? | integer | [Where](#application-directory-request-surface) the request came from |
###### Response Body
| Field | Type | Description |
| ------------------ | ----------------------------------------------------------------- | ---------------------------------------------------------------- |
| results | [results](#application-directory-search-results-structure) object | The results of the search |
| num_pages | integer | The total number of pages the search yielded (max 1000) |
| counts_by_category | map[integer, integer] | Total results per directory category ID |
| type | integer | The type of [entry](#application-directory-item-type) item it is |
| load_id | string | The unique identifier for the application directory search |
###### Application Directory Search Results Structure
| Field | Type | Description |
| ----- | --------------------------------------------------------------- | ----------------------------------------------------- |
| type | integer | The [type of entry](#application-directory-item-type) |
| data | [application](/resources/application#application-object) object | The application associated with the result |
---
# Payments
Link: https://docs.discord.food/resources/payment
Payments are made by the user to Discord in exchange for first and third-party products and services.
## Payment Clients
Payment clients are a concept used to prevent fraudulent transactions across Discord. When a client first attempts to make a payment, it generates a UUIDv4 identifier to be used as the purchase token. This token is then persisted by the client and sent along with all future payment requests.
It is mandatory that all purchase requests include this token in the `purchase_token` field of the request body. The tokens expire after 60 days and must be regenerated.
If Discord detects suspicious activity from a payment client during a transaction, it sends a verification email to the user asking them to authorize the purchase. In the meantime, all purchase requests will fail with a 400 bad request and a [`100056` JSON error code](/topics/errors#json-error-codes):
```json
{
"message": "This client needs to be authorized for purchases. We've sent you an email. Click the link on the email and then retry the purchase.",
"code": 100056,
"payment_id": "1434311883015458937"
}
```
The verification email received will contain a link that redirects to the official Discord client with a verification token present in the URL's fragment (e.g. `https://discord.com/authorize-payment#token=Wzg1Mjg5MjI5NzY2MTkwNjk5MywiN3NtVnNGYWlQNFBQTzIrREgya3JhUVJmZXFlclpvY3UvaFRwcVFBckw5Yz0iXQ.Y5ER6Q.IQhdQcfkK_eHLC16CcFZaYqRP_E`).
After receiving the token, clients can then send a request to the [Verify Purchase Request](#verify-purchase-request) endpoint to complete the authorization process. If the user has not received a link, clients can [choose to resend it](#resend-payment-verification-email).
Upon successful verification, the client will receive a [User Payment Client Add](/gateway/gateway-events#user-payment-client-add) Gateway event, which indicates that the purchase can be retried.
## Payment Confirmation
Some purchases may require additional authentication before they can be completed. In such cases, the purchase request will fail with a 400 bad request and a [`100057` JSON error code](/topics/errors#json-error-codes):
```json
{
"message": "Confirmation required",
"code": 100047,
"payment_id": "1434311883015458937"
}
```
Depending on the [payment gateway](/resources/billing#payment-gateway) used, the error response may also contain a `adyen_redirect_url` field with a URL that the user must visit to complete the authentication process.
Upon successful authentication, the purchase will be automatically confirmed. The client should _not_ retry the purchase request.
### Payment Object
###### Payment Structure
| Field | Type | Description |
| -------------------------------- | ------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------- |
| id | snowflake | The ID of the payment |
| amount | integer | The amount of the payment |
| tax | integer | The amount of tax paid |
| tax_inclusive | boolean | Whether the amount is inclusive of all taxes |
| currency ^1^ | string | The lower-cased [ISO 4217](https://en.wikipedia.org/wiki/ISO_4217) currency code |
| amount_refunded | integer | The amount refunded from the payment |
| description | string | The description of the payment |
| status | integer | The [status](#payment-status) of payment |
| created_at | ISO8601 timestamp | When the payment was created |
| sku_id? | snowflake | The ID of the SKU the payment was for |
| sku_price? | integer | The price of the SKU the payment was for |
| sku_subscription_plan_id? | snowflake | The ID of the subscription plan the payment was for |
| payment_gateway? | integer | The [payment gateway](/resources/billing#payment-gateway) the payment was made with |
| payment_gateway_payment_id? | string | The ID of the payment on the payment gateway |
| has_invoice_url? | boolean | Whether the payment has a downloadable invoice |
| has_refund_invoice_urls? | boolean | Whether the payment has downloadable refund invoices |
| downloadable_invoice? | string | The URL to download the VAT invoice for this payment |
| downloadable_refund_invoices? | array[string] | The URLs to download VAT credit notices for refunds on this payment |
| refund_disqualification_reasons? | array[integer] | The reasons why the payment cannot be refunded |
| flags | integer | The [payment's flags](#payment-flags) |
| sku? | [SKU](/resources/store#sku-object) object | The SKU the payment was for |
| payment_source? | [payment source](/resources/billing#payment-source-object) object | The payment source the payment was made with |
| subscription? | partial [subscription](/resources/subscription#partial-subscription-structure) object | The subscription the payment was for |
| metadata | [payment metadata](#payment-metadata-structure) object | The payment metadata |
^1^ The value can be `discord_orb` to represent payment via virtual currency.
###### Payment Metadata Structure
| Field | Type | Description |
| ------------------ | -------- | ---------------------------------------------------------------------- |
| billing_error_code | ?integer | The [JSON error code](/topics/errors) that occurred during the payment |
###### Payment Status
| Value | Name | Description |
| ----- | --------- | ------------------------- |
| 0 | PENDING | Payment is pending |
| 1 | COMPLETED | Payment has gone through |
| 2 | FAILED | Payment has failed |
| 3 | REVERSED | Payment has been reversed |
| 4 | REFUNDED | Payment has been refunded |
| 5 | CANCELED | Payment has been canceled |
###### Refund Disqualification Reason
| Value | Name | Description |
| ----- | ------------------------------ | ------------------------------------------------------------------------------------------------------------------ |
| 0 | OTHER | Purchase is disqualified from a refund due to other reasons |
| 1 | ALREADY_REFUNDED | Purchase is disqualified from a refund because it has already been refunded |
| 2 | NOT_USER_REFUNDABLE_TYPE | Purchase is disqualified from a refund because it is not a user-refundable type |
| 3 | PAST_REFUNDABLE_DATE | Purchase is disqualified from a refund because it is past the refundable date |
| 4 | ENTITLEMENT_ALREADY_CONSUMED | Purchase is disqualified from a refund because the purchased entitlement has already been consumed |
| 5 | ALREADY_REFUNDED_PREMIUM | Purchase is disqualified from a refund because the user has already refunded a premium subscription purchase |
| 6 | ALREADY_REFUNDED_PREMIUM_GUILD | Purchase is disqualified from a refund because the user has already refunded a premium guild subscription purchase |
###### Payment Flags
| Value | Name | Description |
| -------- | ----------------------- | ------------------------------------------------------------- |
| 1 \<\< 0 | GIFT | Payment is for a gift |
| 1 \<\< 2 | USER_REFUNDED | Payment has been self-refunded |
| 1 \<\< 3 | PREORDER | Payment is a preorder |
| 1 \<\< 4 | PENDING | Automatic payment is pending manual authorization by the user |
| 1 \<\< 5 | TEMPORARY_AUTHORIZATION | Payment is a temporary authorization |
### Invoice Object
###### Invoice Structure
| Field | Type | Description |
| ------------------------- | ----------------------------------------------------- | -------------------------------------------------------------------------------------------------- |
| id | snowflake | The ID of the invoice |
| status? | integer | The [status](#invoice-status) of the invoice |
| currency | string | The lower-cased [ISO 4217](https://en.wikipedia.org/wiki/ISO_4217) currency code the invoice is in |
| subtotal | integer | The subtotal of the invoice |
| tax | integer | The tax applied to the invoice |
| total | integer | The total of the invoice |
| tax_inclusive | boolean | Whether the subtotal is inclusive of all taxes |
| items | array[[invoice item](#invoice-item-structure) object] | The items in the invoice |
| subscription_period_start | ?ISO8601 timestamp | When the current billing period started |
| subscription_period_end | ?ISO8601 timestamp | When the current billing period ends |
| applied_discount_ids? | array[snowflake] | The IDs of the discounts applied to the invoice |
| applied_user_discounts? | map[snowflake, ?ISO8601 timestamp] | The user discount offers applied to the invoice and their expiration dates |
| orbs_reward? | integer | The amount of Orbs the invoice granted |
###### Invoice Status
| Value | Name | Description |
| ----- | ------------- | ------------------------ |
| 1 | OPEN | Invoice is open |
| 2 | PAID | Invoice is paid |
| 3 | VOID | Invoice is void |
| 4 | UNCOLLECTIBLE | Invoice is uncollectible |
###### Invoice Item Structure
| Field | Type | Description |
| --------------------------- | ------------------------------------------------------------- | ------------------------------------------------------ |
| id | snowflake | The ID of the invoice item |
| quantity | integer | How many of the item have been/are being purchased |
| amount | integer | The price of the item (includes discounts) |
| proration | boolean | Whether the item is prorated |
| subscription_plan_id | ?snowflake | The ID of the subscription plan the item represents |
| subscription_plan_price ^1^ | ?integer | The price of the subscription plan the item represents |
| discounts | array[[invoice discount](#invoice-discount-structure) object] | The discounts applied to the item |
| sku_id | ?snowflake | The ID of the SKU |
| unit_price ^1^ | ?[unit price](#unit-price-structure) | The unit price of the item |
| tenant_metadata? | map[string, any] | Tenant metadata for the invoice item |
^1^ Does not include discounts.
###### Invoice Discount Structure
| Field | Type | Description |
| ------ | ------- | ---------------------------------------------- |
| type | integer | The [type](#invoice-discount-type) of discount |
| amount | integer | How much the discount is |
###### Invoice Discount Type
| Value | Name | Description |
| ----- | -------------------------------- | ----------------------------------------------------------------- |
| 1 | SUBSCRIPTION_PLAN | Discount is from an existing subscription plan’s remaining credit |
| 2 | ENTITLEMENT | Discount is from an applied entitlement |
| 3 | PREMIUM_LEGACY_UPGRADE_PROMOTION | Discount is from a legacy premium plan promotion discount |
| 4 | PREMIUM_TRIAL | Discount is from a premium trial |
| 5 | DEFAULT | Discount is a default discount |
###### Unit Price Structure
| Field | Type | Description |
| -------- | ------- | -------------------------------------------------------------------------------- |
| currency | string | The lower-cased [ISO 4217](https://en.wikipedia.org/wiki/ISO_4217) currency code |
| amount | integer | The price amount in the smallest currency unit |
| exponent | integer | The exponent to convert the amount to the displayed currency unit |
## Endpoints
Verify Purchase Request
Verifies and authorizes a payment client for purchases. Returns a 204 empty response on success.
###### JSON Params
| Field | Type | Description |
| ----- | ------ | ------------------------------------------ |
| token | string | The verification token from the email link |
Resend Payment Verification Email
Resends the payment verification email to the user. Returns an empty object on success.
###### JSON Params
| Field | Type | Description |
| -------------- | ------ | -------------------------------------------------------------- |
| purchase_token | string | The purchase token of the payment client (max 1024 characters) |
List Payments
Returns a list of [payment](#payment-object) objects that the current user has made.
| Field | Type | Description |
| ------- | --------- | ----------------------------------------------------------- |
| limit | integer | Max number of payments to return (1-100, default unlimited) |
| before? | snowflake | Get payments before this payment ID |
| after? | snowflake | Get payments after this payment ID |
Get Payment
Returns a [payment](#payment-object) object for the given payment ID.
Void Payment
Voids the pending payment. Returns a 204 empty response on success. Fires [Payment Update](/gateway/gateway-events#payment-update) Gateway event.
Get Payment Invoice Breakdown
Returns URLs to download VAT invoices for the given payment ID.
###### Query String Params
| Field | Type | Description |
| ---------- | --------- | ------------------------------------- |
| payment_id | snowflake | The ID of the payment to get invoices |
###### Response Body
| Field | Type | Description |
| ------------------- | ------------- | ------------------------------------ |
| invoiceLink? | string | The URL to download the invoice |
| refundInvoiceLinks? | array[string] | The URLs to download refund invoices |
---
# Channels
Link: https://docs.discord.food/resources/channel
Channels are the primary way users interact with Discord. All conversations, whether over text or voice, in guilds, or a group, happen in channels.
### Channel Object
A guild or private channel within Discord.
###### Channel Structure
| Field | Type | Description |
| --------------------------------------------- | ------------------------------------------------------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| id ^8^ | snowflake | The ID of the channel |
| type | integer | The [type of channel](#channel-type) |
| guild_id? | snowflake | The ID of the guild the channel is in |
| position? ^10^ | integer | Sorting position of the channel |
| permission_overwrites? | array[[permission overwrite](#permission-overwrite-object) object] | Explicit permission overwrites for members and roles |
| name? | ?string | The name of the channel (1-100 characters) |
| topic? | ?string | The channel topic (max 4096 characters) |
| nsfw? | boolean | Whether the channel is NSFW |
| last_message_id? | ?snowflake | The ID of the last message sent (or thread created for thread-only channels, directory entry created for directory channels) in this channel (may not point to an existing resource) |
| last_pin_timestamp? | ?ISO8601 timestamp | When the last pinned message was pinned, if any |
| bitrate? | integer | The bitrate (in bits) of the voice channel |
| user_limit? ^1^ | integer | The user limit of the voice channel (max 99, 0 refers to no limit) |
| rate_limit_per_user? ^2^ | integer | Duration in seconds seconds a user has to wait before sending another message (max 21600); bots, as well as users with the permission `MANAGE_MESSAGES` or `MANAGE_CHANNELS`, are unaffected |
| recipients? | array[partial [user](/resources/user#user-object) object] | The recipients of the private channel, excluding the requesting user |
| recipient_flags? ^3^ | integer | The [recipient flags](#recipient-flags) of the DM |
| icon? | ?string | The group DM's [icon hash](/reference#cdn-formatting) |
| nicks? | array[[channel nick](#channel-nick-structure) object] | The nicknames of the users in the group DM |
| managed? | boolean | Whether the group DM is managed by an application |
| blocked_user_warning_dismissed? ^7^ | boolean | Whether the user has acknowledged the presence of blocked users in the group DM |
| safety_warnings? ^3^ | array[[safety warning](#safety-warning-structure) object] | The safety warnings for the DM channel |
| application_id? | snowflake | The ID of the application that manages the group DM |
| owner_id? | snowflake | The ID of the owner of the group DM or thread |
| owner? | ?[guild member](/resources/guild#guild-member-object) object | The owner of this thread; only included on certain API endpoints |
| parent_id? | ?snowflake | The ID of the parent category/channel for the guild channel/thread |
| rtc_region? | ?string | The [voice region](/resources/voice#voice-region-object) ID for the voice channel (automatic when `null`) |
| video_quality_mode? | integer | The camera [video quality mode](#video-quality-mode) of the voice channel (default `AUTO`) |
| total_message_sent? | integer | The number of messages ever sent in a thread; similar to `message_count` on message creation, but will not decrement the number when a message is deleted |
| message_count? | integer | The number of messages (not including the initial message or deleted messages) in a thread (if the thread was created before July 1, 2022, it stops counting at 50) |
| member_count? | integer | An approximate count of users in a thread, stops counting at 50 |
| member_ids_preview? | array[snowflake] | The IDs of some of the members in a thread |
| thread_metadata? | [thread metadata](#thread-metadata-object) object | Thread-specific channel metadata |
| member? | [thread member](#thread-member-object) object | Thread member object for the current user, if they have joined the thread; only included on certain API endpoints |
| default_auto_archive_duration? ^4^ | ?integer | Default duration in minutes for newly created threads to stop showing in the channel list after inactivity (one of 60, 1440, 4320, 10080) |
| default_thread_rate_limit_per_user? | integer | Default duration in seconds a user has to wait before sending another message in newly created threads; this field is copied to the thread at creation time and does not live update |
| permissions? ^5^ | string | Computed permissions for the invoking user in the channel, including overwrites |
| flags? | integer | The [channel's flags](#channel-flags) |
| available_tags? | array[[tag](#forum-tag-object) object] | The tags that can be used in a thread-only channel (max 20) |
| applied_tags? | array[snowflake] | The IDs of tags that are applied to a thread in a thread-only channel (max 5) |
| default_reaction_emoji? | ?[default reaction](#default-reaction-object) object | The emoji to show in the add reaction button on a thread in a thread-only channel |
| default_forum_layout? | integer | The default [layout](#forum-layout-type) of a thread-only channel |
| default_sort_order? | ?integer | The default [sort order](#sort-order-type) of a thread-only channel's threads (default `LATEST_ACTIVITY`) |
| default_tag_setting? | string | The default [tag search setting](#search-tag-setting) for a thread-only channel |
| icon_emoji? **(deprecated)** | ?[icon emoji](#icon-emoji-object) object | The emoji to show next to the channel name in channels list |
| theme_color? **(deprecated)** | ?integer | The background color of the channel icon emoji encoded as an integer representation of a hexadecimal color code |
| is_message_request? | boolean | Whether the DM is a message request |
| is_message_request_timestamp? | ?ISO8601 timestamp | When the message request was created |
| is_spam? | boolean | Whether the DM is a spam message request |
| status? ^6^ | ?string | The status of the voice channel (max 500 characters) |
| hd_streaming_until? | ?ISO8601 timestamp | When the HD streaming consumable expires for the voice channel |
| hd_streaming_buyer_id? | ?snowflake | The ID of the user who applied the HD streaming consumable to the voice channel |
| linked_lobby? | ?[linked lobby](#linked-lobby-object) object | The lobby linked to the channel |
| is_linkable? ^9^ | boolean | Whether the current user can link the channel to a lobby |
| is_viewable_and_writeable_by_all_members? ^9^ | boolean | Whether all guild members can view the channel and send messages in it |
| template? | string | String to autofill into new forum posts |
| version? ^3^ | string | The version of the guild serialized as a stringified integer |
^1^ The maximum user limit for stage channels is always 10000 and cannot be set to 0.
^2^ `rate_limit_per_user` also applies to thread creation. Users can send one message and create one thread during each `rate_limit_per_user` interval.
^3^ Only included in [Gateway events](/gateway/gateway-events#channels).
^4^ This field is not automatically copied into new threads created in the channel. It should be manually set when creating a thread.
^5^ Only returned when part of the `resolved` data received in an interaction or when `permissions` is set to `true` when fetched from the [List Guild Channels](#list-guild-channels) endpoint.
^6^ Only included in the [Gateway Guild](/gateway/gateway-events#gateway-guild-object) object.
^7^ Only included in [Gateway events](/gateway/gateway-events#channels) and when fetched from the [List Private Channels](#list-private-channels) endpoint.
^8^ For ephemeral DM channels, the channel ID will always equal the ID of the other recipient.
^9^ Only included when `with_can_link_lobby` is set to `true` when fetched from the [List Guild Channels](#list-guild-channels) endpoint.
^10^ Channels with the same position are sorted by their ID in ascending order.
###### Partial Channel Structure
A channel referenced in an [invite](/resources/invite#invite-object) or [message](/resources/message#message-object).
| Field | Type | Description |
| ------------------- | --------------------------------------------------------- | ----------------------------------------------------- |
| id | snowflake | The ID of the channel |
| type | integer | The [type of channel](#channel-type) |
| name | ?string | The name of the channel (1-100 characters) |
| recipients? ^1^ ^2^ | array[partial [user](/resources/user#user-object) object] | The recipients of the DM |
| icon? | ?string | The group DM's [icon hash](/reference#cdn-formatting) |
| guild_id? ^3^ | ?snowflake | The ID of the guild the channel is in |
^1^ Only present when the channel is fetched from an [invite](/resources/invite#invite-object) with `with_counts` set to `true`.
^2^ The recipient objects contain the `id`, `username`, and `avatar` fields.
^3^ Not present when the channel is fetched from an [invite](/resources/invite#invite-object) or [monetization store page](/resources/discovery#monetization-store-page-structure), as it can be inferred from the `guild_id` and `guild.id` fields respectively.
###### Channel Nick Structure
| Field | Type | Description |
| ----- | --------- | ------------------------ |
| id | snowflake | The ID of the user |
| nick | string | The nickname of the user |
###### Safety Warning Structure
| Field | Type | Description |
| ----------------- | ------------------ | ------------------------------------------- |
| id | string | The ID of the warning |
| type | integer | The [type of warning](#safety-warning-type) |
| expiry | ISO8601 timestamp | When the warning expires |
| dismiss_timestamp | ?ISO8601 timestamp | When the warning was dismissed by the user |
###### Safety Warning Type
| Value | Name | Description |
| ----- | --------------------------------- | -------------------------------------------------------------------------------- |
| 1 | STRANGER_DANGER | User may not want to interact with this person |
| 2 | INAPPROPRIATE_CONVERSATION_TIER_1 | User may not want to interact with this person due to inappropriate conversation |
| 3 | INAPPROPRIATE_CONVERSATION_TIER_2 | User may not want to interact with this person due to inappropriate conversation |
| 4 | LIKELY_ATO | The recipient's account is likely compromised and should be treated with caution |
###### Channel Type
Type `10`, `11` and `12` are only available in API v9 and above.
| Value | Name | Description |
| ----- | ----------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| 0 | GUILD_TEXT | A text channel within a guild |
| 1 | DM | A private channel between two users |
| 2 | GUILD_VOICE | A voice channel within a guild |
| 3 | GROUP_DM | A private channel between multiple users |
| 4 | GUILD_CATEGORY | An [organizational category](https://support.discord.com/hc/en-us/articles/115001580171-Channel-Categories-101) that contains up to 50 channels |
| 5 | GUILD_NEWS | Almost identical to `GUILD_TEXT`, a channel that [users can follow and crosspost into their own guild](https://support.discord.com/hc/en-us/articles/360032008192) |
| 6 | GUILD_STORE | A channel in which developers can showcase their SKUs |
| ~~7~~ | ~~GUILD_LFG~~ | ~~A channel where users can match up for various games~~ |
| ~~8~~ | ~~LFG_GROUP_DM~~ | ~~A private channel between multiple users for a group within an LFG channel~~ |
| ~~9~~ | ~~THREAD_ALPHA~~ | ~~The first iteration of the threads feature, never widely used~~ |
| 10 | NEWS_THREAD | A temporary sub-channel within a `GUILD_NEWS` channel |
| 11 | PUBLIC_THREAD | a temporary sub-channel within a `GUILD_TEXT`, `GUILD_FORUM`, or `GUILD_MEDIA` channel |
| 12 | PRIVATE_THREAD | a temporary sub-channel within a `GUILD_TEXT` channel that is only viewable by those invited and those with the `MANAGE_THREADS` permission |
| 13 | GUILD_STAGE_VOICE | A voice channel for [hosting events with an audience](https://support.discord.com/hc/en-us/articles/1500005513722) in a guild |
| 14 | GUILD_DIRECTORY | The main channel in a [hub](https://support.discord.com/hc/en-us/articles/4406046651927-Discord-Student-Hubs-FAQ) containing the listed guilds |
| 15 | GUILD_FORUM | A channel that can only contain threads |
| 16 | GUILD_MEDIA | A channel that can only contain threads in a gallery view |
| 17 | LOBBY | A game lobby channel |
| 18 | EPHEMERAL_DM | A private channel created by the social layer SDK |
###### Channel Flags
| Value | Name | Description |
| ------------- | --------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------- |
| 1 \<\< 0 | GUILD_FEED_REMOVED | Guild channel is hidden from the guild's feed |
| 1 \<\< 1 | PINNED | Thread is pinned to the top of its parent thread-only channel |
| 1 \<\< 2 | ACTIVE_CHANNELS_REMOVED | Guild channel has been removed from the guild's active channels |
| 1 \<\< 4 | REQUIRE_TAG | Thread-only channel requires a tag to create threads in |
| 1 \<\< 5 | IS_SPAM | Channel is marked as spam |
| 1 \<\< 7 | IS_GUILD_RESOURCE_CHANNEL | Guild channel is used as a read-only resource for onboarding and is not shown in the channel list |
| 1 \<\< 8 | CLYDE_AI | Channel is created by Clyde AI, which has full access to all message content |
| 1 \<\< 9 | IS_SCHEDULED_FOR_DELETION | Guild channel is scheduled for deletion and is not shown in the UI |
| ~~1 \<\< 10~~ | ~~IS_MEDIA_CHANNEL~~ ^1^ | ~~Forum channel is a media channel~~ |
| 1 \<\< 11 | SUMMARIES_DISABLED | Guild channel has summaries disabled |
| ~~1 \<\< 12~~ | ~~APPLICATION_SHELF_CONSENT~~ | ~~Private channel's recipients consented to the application shelf~~ |
| 1 \<\< 13 | IS_ROLE_SUBSCRIPTION_TEMPLATE_PREVIEW_CHANNEL | Role subscription tier for this guild channel has not been published yet |
| 1 \<\< 14 | IS_BROADCASTING | Group DM is used for broadcasting a live stream |
| 1 \<\< 15 | HIDE_MEDIA_DOWNLOAD_OPTIONS | Media channel has the embedded download options hidden for media attachments |
| 1 \<\< 16 | IS_JOIN_REQUEST_INTERVIEW_CHANNEL | Group DM is used for [guild join request interviews](https://support.discord.com/hc/en-us/articles/23187611406999-Guilds-FAQ#h_01HXW2MCD0BT70FB9SRV1YRPBV) |
| 1 \<\< 17 | OBFUSCATED ^2^ | User does not have permission to view the channel |
| 1 \<\< 19 | IS_MODERATOR_REPORT_CHANNEL | Forum channel is the guild's moderator queue |
| 1 \<\< 21 | IS_SPOILER_CHANNEL | Channel is marked as a spoiler channel |
^1^ Media channels are now represented by the [`GUILD_MEDIA` channel type](#channel-type).
^2^ Obfuscated channel names and topics are always returned as `___hidden___`.
###### Recipient Flags
| Value | Name | Description |
| -------- | ----------------------------- | ----------------------------------------------------------------------------------------------------------- |
| 1 \<\< 0 | DISMISSED_IN_GAME_MESSAGE_NUX | User has dismissed the [`IN_GAME_MESSAGE_NUX` message](/resources/message#message-type) for this DM channel |
###### Video Quality Mode
| Value | Name | Description |
| ----- | ---- | --------------------------------------------------- |
| 1 | AUTO | Discord chooses the quality for optimal performance |
| 2 | FULL | 720p quality |
###### Forum Layout Type
| Value | Name | Description |
| ----- | ------- | ---------------------------------------------- |
| 0 | DEFAULT | No layout type explicitly set |
| 1 | LIST | Threads are displayed in a list |
| 2 | GRID | Threads are displayed in a collection of tiles |
###### Sort Order Type
| Value | Name | Description |
| ----- | --------------- | ---------------------------------------------------------------- |
| 0 | LATEST_ACTIVITY | Sort by the most recently active threads |
| 1 | CREATION_TIME | Sort by when the thread was created (from most recent to oldest) |
###### Search Tag Setting
| Value | Description |
| ---------- | ------------------------------------------------------------------ |
| match_some | Threads with any of the selected tags will be shown in the results |
| match_all | Threads with all of the selected tags will be shown in the results |
###### Example Guild Category Channel
```json
{
"id": "399942396007890945",
"type": 4,
"name": "lounge",
"position": 0,
"flags": 0,
"parent_id": null,
"guild_id": "41771983423143937",
"permission_overwrites": []
}
```
###### Example Guild Text Channel
```json
{
"id": "41771983423143937",
"guild_id": "41771983423143937",
"name": "general",
"type": 0,
"position": 6,
"flags": 0,
"permission_overwrites": [],
"rate_limit_per_user": 2,
"nsfw": true,
"topic": "24/7 chat about how to gank Mike #2",
"last_message_id": "155117677105512449",
"parent_id": "399942396007890945",
"last_pin_timestamp": "2023-02-17T09:22:28+00:00",
"default_auto_archive_duration": 10080,
"default_thread_rate_limit_per_user": 0
}
```
###### Example Guild News Channel
Users can post or publish messages in this type of channel if they have the proper permissions. These are called "Announcement Channels" in the client.
```json
{
"id": "41771983423143937",
"guild_id": "41771983423143937",
"name": "important-news",
"type": 5,
"position": 6,
"flags": 0,
"permission_overwrites": [],
"nsfw": true,
"topic": "Rumors about Half Life 3",
"last_message_id": "155117677105512449",
"parent_id": "399942396007890945",
"last_pin_timestamp": "2023-02-17T09:22:28+00:00",
"default_auto_archive_duration": 10080,
"default_thread_rate_limit_per_user": 0
}
```
###### Example Guild Voice Channel
```json
{
"id": "155101607195836416",
"last_message_id": "174629835082649376",
"type": 2,
"name": "ROCKET CHEESE",
"position": 5,
"flags": 0,
"parent_id": null,
"bitrate": 96000,
"user_limit": 0,
"rtc_region": null,
"guild_id": "41771983423143937",
"permission_overwrites": [],
"rate_limit_per_user": 0,
"nsfw": false
}
```
###### Example Guild Stage Channel
```json
{
"id": "1053657210082836620",
"last_message_id": "1075473541174136834",
"type": 13,
"name": "EVENTS",
"position": 2,
"flags": 0,
"parent_id": null,
"topic": "",
"bitrate": 64000,
"user_limit": 10000,
"rtc_region": null,
"guild_id": "41771983423143937",
"permission_overwrites": [],
"rate_limit_per_user": 0,
"nsfw": false
}
```
###### Example Guild Forum Channel
```json
{
"id": "1074357242700247173",
"last_message_id": "1075957063890509894",
"type": 15,
"name": "bug-reports",
"position": 11,
"flags": 16,
"parent_id": "399942396007890945",
"topic": "",
"guild_id": "41771983423143937",
"permission_overwrites": [],
"rate_limit_per_user": 0,
"nsfw": false,
"available_tags": [
{
"id": "1076275719316983899",
"name": "Alien",
"emoji_id": null,
"emoji_name": "👽",
"moderated": true
}
],
"default_reaction_emoji": {
"emoji_id": "1066765913208139796",
"emoji_name": null
},
"default_auto_archive_duration": 10080,
"default_thread_rate_limit_per_user": 0,
"default_sort_order": null,
"default_forum_layout": 0,
"default_tag_setting": "match_some",
"template": "Make sure your report is descriptive!"
}
```
###### Example DM Channel
```json
{
"last_message_id": "3343820033257021450",
"type": 1,
"id": "319674150115610528",
"flags": 0,
"is_message_request": false,
"is_message_request_timestamp": "2023-02-16T00:45:10.270751+00:00",
"is_spam": false,
"recipients": [
{
"id": "728342296696979526",
"username": "splatter",
"avatar": "40ab813a6e1b6170dc4e7d1f2331bfeb",
"discriminator": "0",
"public_flags": 4194304,
"banner": "a_999640fa66eb908d8ec2f969516b97c8",
"accent_color": 11983775,
"global_name": "not splatter",
"avatar_decoration_data": null,
"primary_guild": null
}
]
}
```
###### Example Group DM Channel
```json
{
"name": "Some test channel",
"icon": null,
"recipients": [
{
"id": "728342296696979526",
"username": "splatter",
"avatar": "40ab813a6e1b6170dc4e7d1f2331bfeb",
"discriminator": "0",
"public_flags": 4194304,
"banner": "a_999640fa66eb908d8ec2f969516b97c8",
"accent_color": 11983775,
"global_name": "not splatter",
"avatar_decoration_data": null,
"primary_guild": null
},
{
"id": "211270674482724864",
"username": "11pixels",
"avatar": "40e250de9c74346c480e7e16da242b47",
"discriminator": "0",
"public_flags": 4194880,
"banner": "785814ab5375e10deafe9e7de256dd0e",
"accent_color": 47615,
"global_name": "12pixels",
"avatar_decoration_data": null,
"primary_guild": null
}
],
"last_message_id": "3343820033257021450",
"type": 3,
"id": "319674150115710528",
"flags": 0,
"owner_id": "82198810841029460",
"blocked_user_warning_dismissed": true
}
```
###### Example Thread Channel
[Threads](/topics/threads) can be either `archived` or `active`. Archived threads are generally immutable. To send a message or add a reaction, a thread must first be unarchived. The API will helpfully automatically unarchive a thread when sending a message in that thread.
Unlike with channels, the API will only sync updates to users about threads the current user can view. When receiving a [Guild Create](/gateway/gateway-events#guild-create) payload, the API will only include active threads the current user can view. Threads inside of private channels are completely private to the members of that private channel. As such, when _gaining_ access to a channel in a subscribed guild the API sends a [Thread List Sync](/gateway/gateway-events#thread-list-sync), which includes all active threads in that channel.
Threads also track membership. Users must be added to a thread before sending messages in them. The API will helpfully automatically add users to a thread when sending a message in that thread.
Guilds have limits on the number of active threads and members per thread. Once these are reached additional threads cannot be created or unarchived, and users cannot be added. Threads do not count against the per-guild channel limit.
The [threads](/topics/threads) topic has some more information.
```json
{
"id": "41771983423143937",
"guild_id": "41771983423143937",
"parent_id": "41771983423143937",
"owner_id": "41771983423143937",
"name": "don't buy dota-2",
"type": 11,
"last_message_id": "155117677105512449",
"message_count": 1,
"member_count": 5,
"rate_limit_per_user": 2,
"thread_metadata": {
"archived": false,
"auto_archive_duration": 1440,
"archive_timestamp": "2021-04-12T23:40:39.855793+00:00",
"locked": false
},
"total_message_sent": 1,
"applied_tags": []
}
```
###### Example Ephemeral DM Channel
```json
{
"flags": 0,
"id": "1001086404203389018",
"last_message_id": "1356768681543209051",
"recipients": [
{
"avatar": "c78ef8fb1db15a3d5f1b4c057856c5c9",
"avatar_decoration_data": null,
"discriminator": "0",
"global_name": "Dolfies",
"id": "852892297661906993",
"primary_guild": null,
"public_flags": 136,
"username": "dolfies"
},
{
"avatar": "f6c0363fbab45668fcf8f88fea56db9c",
"avatar_decoration_data": null,
"discriminator": "0",
"global_name": "Dziurwa💕",
"id": "1001086404203389018",
"primary_guild": null,
"public_flags": 4210944,
"username": ".dziurwa"
}
],
"type": 18
}
```
###### Example Partial Channel
```json
{
"id": "1065785999734607943",
"name": null,
"type": 3,
"icon": null,
"recipients": [
{
"id": "1001086404203389018",
"username": ".dziurwa",
"avatar": "7447ee696188f6566862eb5072033c79"
}
]
}
```
### Followed Channel Object
An object that represents a channel that has been followed by a webhook.
###### Followed Channel Structure
| Field | Type | Description |
| ---------- | --------- | ------------------------- |
| channel_id | snowflake | The source channel ID |
| webhook_id | snowflake | Created target webhook ID |
### Permission Overwrite Object
See [permissions](/topics/permissions#permissions) for more information about the `allow` and `deny` fields.
###### Permission Overwrite Structure
| Field | Type | Description |
| --------- | --------- | ------------------------------------------------------------ |
| id | snowflake | Role or user ID |
| type | integer | The [type of overwritten entity](#permission-overwrite-type) |
| allow ^1^ | string | The bitwise value of all allowed permissions |
| deny ^1^ | string | The bitwise value of all disallowed permissions |
^1^ When sending, these fields are optional and will default to `0`.
###### Permission Overwrite Type
In API v7 and below, this enum uses the strings `role` and `member` instead of integer types.
| Value | Name | Description |
| ----- | ------ | --------------------------------- |
| 0 | role | Permissions based on a role |
| 1 | member | Permissions for a specific member |
### Thread Metadata Object
The thread metadata object contains a number of thread-specific channel fields that are not needed by other channel types.
###### Thread Metadata Structure
| Field | Type | Description |
| --------------------- | ------------------ | ------------------------------------------------------------------------------------------------------------ |
| archived | boolean | Whether the thread is archived |
| auto_archive_duration | integer | Duration in minutes to stop showing in the channel list after inactivity (one of 60, 1440, 4320, 10080) |
| archive_timestamp | ISO8601 timestamp | Timestamp when the thread's archive status was last changed, used for calculating recent activity |
| locked | boolean | Whether the thread is locked; when a thread is locked, only users with `MANAGE_THREADS` can interact with it |
| invitable? | boolean | Whether non-moderators can add other non-moderators to a thread; only available on private threads |
| create_timestamp? | ?ISO8601 timestamp | Timestamp when the thread was created; only populated for threads created after 2022-01-09 |
### Thread Member Object
A thread member object contains information about a user that has joined a thread.
###### Thread Member Structure
| Field | Type | Description |
| ---------------- | ------------------------------------------------------------------ | ------------------------------------------------ |
| id? ^1^ | snowflake | The ID of the thread |
| user_id? ^1^ | snowflake | The ID of the user |
| join_timestamp | ISO8601 timestamp | The time the current user last joined the thread |
| flags | integer | The user's [thread flags](#thread-member-flags) |
| muted? ^2^ | boolean | Whether the user has muted the thread |
| mute_config? ^2^ | ?[mute config](/resources/user-settings#mute-config-object) object | The mute metadata for the thread |
| member? ^1^ ^3^ | [guild member](/resources/guild#guild-member-object) object | The member object for the user |
^1^ These fields are omitted on the member sent within each thread in the [Guild Create](/gateway/gateway-events#guild-create) event.
^2^ These fields are omitted for thread members other than the current user.
^3^ The `member` field is only present when `with_member` is set to `true` when fetching [List Thread Members](#list-thread-members) or [Get Thread Member](#get-thread-member).
###### Thread Member Flags
| Value | Name | Description |
| -------- | -------------- | ---------------------------------------------------------------- |
| 1 \<\< 0 | HAS_INTERACTED | User has interacted with the thread |
| 1 \<\< 1 | ALL_MESSAGES | User receives notifications for all messages |
| 1 \<\< 2 | ONLY_MENTIONS | User receives notifications only for messages that @mention them |
| 1 \<\< 3 | NO_MESSAGES | User does not receive any notifications |
### Default Reaction Object
An object that specifies the emoji to use as the default way to react to a `GUILD_FORUM` or `GUILD_MEDIA` channel post.
###### Default Reaction Structure
| Field | Type | Description |
| -------------- | ---------- | ---------------------------------- |
| emoji_id ^1^ | ?snowflake | The ID of a guild's custom emoji |
| emoji_name ^1^ | ?string | The unicode character of the emoji |
^1^ At most one of `emoji_id` and `emoji_name` may be set to a non-null value.
### Icon Emoji Object
An object that specifies the emoji to use as the icon displayed next to a channel's name.
###### Icon Emoji Structure
| Field | Type | Description |
| -------- | ---------- | ---------------------------------- |
| id ^1^ | ?snowflake | The ID of a guild's custom emoji |
| name ^1^ | ?string | The unicode character of the emoji |
^1^ At most one of `id` and `name` may be set to a non-null value.
### Forum Tag Object
An object that represents a tag that is able to be applied to a thread in a `GUILD_FORUM` or `GUILD_MEDIA` channel.
###### Forum Tag Structure
| Field | Type | Description |
| -------------- | ---------- | ------------------------------------------------------------------------------------------------------------- |
| id | snowflake | The ID of the tag |
| name | string | The name of the tag (max 50 characters) |
| moderated | boolean | Whether this tag can only be added to or removed from threads by members with the `MANAGE_THREADS` permission |
| emoji_id ^1^ | ?snowflake | The ID of a guild's custom emoji |
| emoji_name ^1^ | ?string | The unicode character of the emoji |
^1^ At most one of `emoji_id` and `emoji_name` may be set to a non-null value.
### Linked Lobby Object
A lobby linked to a channel.
###### Linked Lobby Structure
| Field | Type | Description |
| --------------------------------- | ----------------- | ---------------------------------------------------------------------------- |
| application_id | snowflake | The ID of the application |
| lobby_id | snowflake | The ID of the lobby |
| linked_by | snowflake | The ID of the user who linked the lobby |
| linked_at | ISO8601 timestamp | When the lobby was linked to channel |
| require_application_authorization | boolean | Whether users must authorize the application to send messages in the channel |
## Endpoints
List Private Channels
Returns a list of active [private channel](#channel-object) objects the user is participating in.
Get DM Channel
Returns an existing [DM channel](#channel-object) object with a user.
Create Private Channel
One recipient creates or returns an existing [DM channel](#channel-object), none or multiple recipients create a [group DM channel](#channel-object). Returns a [private channel](#channel-object) object. Fires a [Channel Create](/gateway/gateway-events#channel-create) Gateway event.
If multiple channels with a single recipient exist, the most recent channel is returned.
Clients should not use this endpoint to create multiple new DMs in a short period of time. A DM is only counted as created if the user sends the first message in the DM and the channel did not have existing message history. Users may only create 10 new DMs to non-bot users in a 10-minute window.
Suspicious DM activity may be flagged by Discord and require [additional verification steps](/resources/user#required-action-type) or lead to immediate account termination.
One of `recipient_id`, `recipients` or `access_tokens` is required. Bots cannot DM other bots or create group DMs without `access_tokens`.
###### JSON Params
| Field | Type | Description |
| ------------------------------ | ---------------------- | -------------------------------------------------------------------------- |
| recipient_id? **(deprecated)** | snowflake | The user ID of the recipient to DM |
| recipients? ^1^ | array[snowflake] | The users to include in the private channel |
| access_tokens? ^2^ | array[string] | The access tokens of users that have granted your app the `gdm.join` scope |
| nicks? ^3^ | map[snowflake, string] | A mapping of user IDs to their respective nicknames |
^1^ When creating a group DM, the client user's ID can optionally be included in the `recipients` array. This allows creating a group DM with only one recipient.
^2^ Only usable by bots for OAuth2 requests, which can only create group DMs.
^3^ Requires `access_tokens` to be provided.
Create Group DM Shell
Creates a group DM channel with one recipient. Returns a [private channel](#channel-object) object. Fires a [Channel Create](/gateway/gateway-events#channel-create) Gateway event.
###### JSON Params
| Field | Type | Description |
| ------------ | --------- | ---------------------------- |
| recipient_id | snowflake | The user ID of the recipient |
List Guild Channels
In the future, the channel list will only include channels the user has the `VIEW_CHANNEL` permission for.
Returns a list of [guild channel](#channel-object) objects for the guild. Does not include threads. If the user is not in the guild, the guild must be discoverable.
###### Query String Params
| Field | Type | Description |
| ------------------------ | ------- | ---------------------------------------------------------------------------------------------------------------- |
| permissions? ^1^ | boolean | Whether to return calculated permissions for the invoking user in each channel (default false) |
| with_can_link_lobby? ^2^ | boolean | Whether to include `is_linkable` and `is_viewable_and_writeable_by_all_members` for each channel (default false) |
^1^ Permissions are not returned if the user is not in the guild.
^2^ Only usable in OAuth2 contexts.
List Guild Top Read Channels
Returns a list of snowflakes representing up to 10 of the top read channels in the guild. If the user is not in the guild, the guild must be discoverable.
Create Guild Channel
Creates a new channel in the guild. Requires the `MANAGE_CHANNELS` permission. If setting permission overwrites, only permissions you have in the guild can be allowed/denied.
Setting `MANAGE_ROLES` permission in channels is only possible for guild administrators. Returns the new [channel](#channel-object) object on success. Fires a [Channel Create](/gateway/gateway-events#channel-create) Gateway event.
Guilds may have a maximum of 500 channels. Of those 500, a maximum of 50 can be categories.
For stage channels, the maximum bitrate is always **64 kbps**.
For voice channels, the limit depends on the guild's [premium tier](https://support.discord.com/hc/en-us/articles/360028038352) and [features](/resources/guild#guild-features).
These limits are summarized in the following table by [premium tier](/resources/guild#premium-tier). Note that if the guild has the [`VIP_REGIONS` feature](/resources/guild#guild-features), the applied limit is always the tier 3 one (**384 kbps**).
| Premium Tier | Bitrate Limit |
| ------------ | ------------- |
| `NONE` | **96 kbps** |
| `TIER_1` | **128 kbps** |
| `TIER_2` | **256 kbps** |
| `TIER_3` | **384 kbps** |
###### JSON Params
| Field | Type | Description | Channel Type |
| ----------------------------------- | ------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | -------------------------------------- |
| name | string | The name of the channel (1-100 characters) | All |
| position? | ?integer | Sorting position of the channel | All |
| type? | ?integer | The [type of channel](#channel-type) (default `GUILD_TEXT`) | All |
| topic? | ?string | The channel topic (max 4096 characters) | Text, News, Stage, Forum, Media |
| nsfw? | ?boolean | Whether the channel is NSFW | Text, News, Voice, Stage, Forum, Media |
| rate_limit_per_user? | ?integer | Duration in seconds a user has to wait before sending another message (max 21600); bots, as well as users with the permission `MANAGE_MESSAGES` or `MANAGE_CHANNELS`, are unaffected | Text, News, Voice, Stage, Forum, Media |
| bitrate? ^1^ | ?integer | The bitrate (in bits) of the voice channel | Voice, Stage |
| user_limit? ^2^ | ?integer | The user limit of the voice channel (max 99, 0 refers to no limit) | Voice, Stage |
| permission_overwrites? | ?array[[permission overwrite](#permission-overwrite-object) object] | Explicit permission overwrites for members and roles | All |
| parent_id? | ?snowflake | The ID of the parent category for the guild channel | Text, News, Voice, Stage, Forum, Media |
| rtc_region? | ?string | The [voice region](/resources/voice#voice-region-object) ID for the voice channel (automatic when `null`) | Voice, Stage |
| video_quality_mode? | ?integer | The camera [video quality mode](#video-quality-mode) of the voice channel | Voice, Stage |
| sku_id | snowflake | The ID of the SKU showcased by the store channel | Store |
| branch_id? | ?snowflake | The ID of the special branch granted by the store channel | Store |
| default_auto_archive_duration? | ?integer | Default duration in minutes for newly created threads to stop showing in the channel list after inactivity (one of 60, 1440, 4320, 10080) | Text, News, Forum, Media |
| default_thread_rate_limit_per_user? | ?integer | Default duration in seconds a user has to wait before sending another message in newly created threads; this field is copied to the thread at creation time and does not live update | Text, News, Forum, Media |
| available_tags? ^3^ | ?array[partial [forum tag](#forum-tag-object) object] | The tags that can be used in a thread-only channel (max 20) | Forum, Media |
| default_reaction_emoji? | ?[default reaction](#default-reaction-object) object | The emoji to show in the add reaction button on a thread in a thread-only channel | Forum, Media |
| default_forum_layout? | ?integer | The default [layout](#forum-layout-type) of a forum channel | Forum |
| default_sort_order? | ?integer | The default [sort order](#sort-order-type) of a thread-only channel's threads | Forum, Media |
| default_tag_setting? | ?string | The default [tag setting](#search-tag-setting) of a thread-only channel (default `match_some`) | Forum, Media |
| flags? | ?integer | The [channel's flags](#channel-flags) (only `IS_SPOILER_CHANNEL` can be set) | All |
^1^ For stage channels, bitrate can only be set up to **64 kbps**. See the bitrate limits section above for more information.
^2^ The maximum user limit for stage channels is always 10000 and cannot be set to 0.
^3^ Only the `name` field is required.
Modify Guild Channel Positions
Modifies the positions of a set of [channel](#channel-object) objects for the guild. Requires the `MANAGE_CHANNELS` permission. Returns a 204 empty response on success. Fires multiple [Channel Update](/gateway/gateway-events#channel-update) Gateway events.
Only channels to be modified are required. For accurate sorting, the following conventions are recommended when modifying channels, but they are not required or enforced by the API.
- When moving a category, you should include every category in the guild.
- When moving an uncategorized channel, you should include every relevant uncategorized channel.
- When moving a channel within the same category, you should include every relevant channel in that category.
- When moving a channel into a category, you should include every relevant channel in the target category. This also applies when the target category is `null`.
A relevant channel is defined as one in the same sorting bucket. For example, text, news, and forum channels are sorted together, and voice and stage channels are sorted together. The latter are always shown below the former, so they are not relevant when sorting, and vice versa.
This endpoint takes a JSON array of parameters in the following format:
###### JSON Params
| Field | Type | Description |
| ----------------- | ---------- | -------------------------------------------------------------------------------- |
| id | snowflake | The ID of the channel |
| position? | ?integer | Sorting position of the channel |
| lock_permissions? | ?boolean | Syncs the permission overwrites with the new parent, if moving to a new category |
| parent_id? | ?snowflake | The ID of the parent category for the channel |
Get Channel
Returns a [channel](#channel-object) object for a given channel ID. Requires the `VIEW_CHANNEL` permission for the guild. If the channel is a thread, a [thread member](#thread-member-object) object is included in the returned result.
Modify Channel
Updates a channel's settings. Returns a [channel](#channel-object) on success. Fires a [Channel Update](/gateway/gateway-events#channel-update) or [Thread Update](/gateway/gateway-events#channel-update) Gateway event.
###### JSON Params
If modifying a guild channel, requires the `MANAGE_CHANNELS` permission for the guild. If modifying permission overwrites, the `MANAGE_ROLES` permission is required. Only permissions you have in the guild or parent channel (if applicable) can be allowed/denied (unless you have a `MANAGE_ROLES` overwrite in the channel). Fires a [Channel Update](/gateway/gateway-events#channel-update) Gateway event. If modifying a category, individual [Channel Update](/gateway/gateway-events#channel-update) events will fire for each child channel that also changes.
If modifying a thread and setting `archived` to `false`, when `locked` is also `false`, only the `SEND_MESSAGES` permission is required. Otherwise, requires the `MANAGE_THREADS` permission. Requires the thread to have `archived` set to `false` or be set to `false` in the request. Fires a [Thread Update](/gateway/gateway-events#thread-update) Gateway event.
| Field | Type | Description | Channel Type |
| ----------------------------------- | ------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------ |
| name? | string | The name of the channel (1-100 characters) | Text, News, Voice, Category, Stage, Forum, Media, Thread, Group DM |
| type? | integer | The [type of channel](#channel-type); only conversion between text and news is supported and only in guilds with the "NEWS" feature | Text, News |
| position? | ?integer | Sorting position of the channel | Text, News, Voice, Category, Stage, Forum, Media |
| topic? | ?string | The channel topic (max 4096 characters) | Text, News, Stage, Forum, Media |
| icon? | [image data](/reference#cdn-data) | The group DM's icon | Group DM |
| nsfw? | ?boolean | Whether the channel is NSFW | Text, News, Voice, Stage, Forum |
| rate_limit_per_user? | ?integer | Duration in seconds a user has to wait before sending another message (max 21600); bots, as well as users with the permission `MANAGE_MESSAGES` or `MANAGE_CHANNELS`, are unaffected | Text, News, Voice, Stage, Forum, Media, Thread |
| bitrate? ^1^ | ?integer | The bitrate (in bits) of the voice channel | Voice, Stage |
| user_limit? ^2^ | ?integer | the user limit of the voice channel (max 99, 0 refers to no limit) | Voice, Stage |
| permission_overwrites? | ?array[[permission overwrite](#permission-overwrite-object) object] | Explicit permission overwrites for members and roles | Text, News, Voice, Category, Stage, Forum, Media |
| parent_id? | ?snowflake | The ID of the parent category for the guild channel | Text, News, Voice, Stage, Forum, Media |
| owner? | ?snowflake | The ID of the owner for the group DM | Group DM |
| rtc_region? | ?string | The [voice region](/resources/voice#voice-region-object) ID for the voice channel (automatic when `null`) | Voice, Stage |
| video_quality_mode? | ?integer | The camera [video quality mode](#video-quality-mode) of the voice channel | Voice, Stage |
| default_auto_archive_duration? | ?integer | Default duration in minutes for newly created threads to stop showing in the channel list after inactivity (one of 60, 1440, 4320, 10080) | Text, News, Forum, Media |
| default_thread_rate_limit_per_user? | integer | Default duration in seconds a user has to wait before sending another message in newly created threads; this field is copied to the thread at creation time and does not live update | Text, News, Forum, Media |
| auto_archive_duration? | integer | Duration in minutes to automatically archive the thread after recent activity (one of 60, 1440, 4320, 10080) | Thread |
| archived? | ?boolean | Whether the thread is archived | Thread |
| locked? | ?boolean | Whether the thread is locked; when a thread is locked, only users with `MANAGE_THREADS` can unarchive it | Thread |
| invitable? | ?boolean | Whether non-moderators can add other non-moderators to a thread | Private Thread |
| flags? | integer | The [channel's flags](#channel-flags) (only `GUILD_FEED_REMOVED`, `PINNED`, `ACTIVE_CHANNELS_REMOVED`, `REQUIRE_TAG`, and `IS_SPOILER_CHANNEL` can be set) | All |
| available_tags? ^3^ | array[partial [forum tag](#forum-tag-object) object] | The tags that can be used in a thread-only channel (max 20) | Forum, Media |
| applied_tags? | array[snowflake] | The IDs of tags that are applied to a thread in a thread-only channel (max 5) | Thread |
| default_reaction_emoji? | ?[default reaction](#default-reaction-object) object | The emoji to show in the add reaction button on a thread in a thread-only channel | Forum, Media |
| default_forum_layout? | ?integer | The default [layout](#forum-layout-type) of a forum channel | Forum |
| default_sort_order? | ?integer | The default [sort order](#sort-order-type) of a thread-only channel's threads | Forum, Media |
| default_tag_setting? | ?string | The default [tag setting](#search-tag-setting) of a thread-only channel (default `match_some`) | Forum, Media |
| icon_emoji? | ?[icon emoji](#icon-emoji-object) object | The emoji to show next to the channel name in channels list | Text, News, Voice, Stage, Forum, Media |
| theme_color? | ?integer | The background color of the channel icon emoji encoded as an integer representation of a hexadecimal color code | Text, News, Voice, Stage, Forum, Media |
| template? ^4^ | string | String to autofill into new forum posts | Forum, Media |
^1^ For stage channels, bitrate can only be set up to **64 kbps**. See the bitrate limits section in the [Create Guild Channel endpoint documentation](#create-guild-channel) for more information.
^2^ The maximum user limit for stage channels is always 10000 and cannot be set to 0.
^3^ Only the `name` field is required (`id` may be passed to denote an existing tag).
^4^ Only usable by Discord employees.
Delete Channel
Deletes a channel, or closes a private message. Requires the `MANAGE_CHANNELS` permission for the guild, or `MANAGE_THREADS` if the channel is a thread. Deleting a category does not delete its child channels; they will have their `parent_id` removed and a [Channel Update](/gateway/gateway-events#channel-update) Gateway event will fire for each of them. Returns a [channel](#channel-object) object on success. Fires a [Channel Delete](/gateway/gateway-events#channel-delete) or [Thread Delete](/gateway/gateway-events#thread-delete) Gateway event.
Deleting a guild channel cannot be undone. Use this with caution, as it is impossible to undo this action when performed on a guild channel. In contrast, when used with a private message, it is possible to undo the action by opening a private message with the recipient again.
For Community guilds, the Rules or Guidelines channel and the Community Updates channel cannot be deleted.
###### Query String Params
| Field | Type | Description |
| ------- | ------- | ------------------------------------------------------------------------------ |
| silent? | boolean | Whether to leave the group DM without sending a system message (default false) |
Bulk Leave Group DMs
Leave multiple group DMs. Returns a 204 empty response on success. Fires multiple [Channel Delete](/gateway/gateway-events#channel-delete) Gateway events.
###### JSON Params
| Field | Type | Description |
| ----------- | ---------------- | ------------------------------------------ |
| channel_ids | array[snowflake] | The IDs of the group DMs to leave (1-1000) |
Modify Channel Status
Sets a voice channel's status. Requires the `SET_VOICE_CHANNEL_STATUS` permission and additionally the `MANAGE_CHANNELS` permission if the current user is not connected to the voice channel. Returns a 204 empty response on success. Fires a [Voice Channel Status Update](/gateway/gateway-events#voice-channel-status-update) Gateway event.
###### JSON Params
| Field | Type | Description |
| ------ | ------- | ---------------------------------------------------- |
| status | ?string | The status of the voice channel (max 500 characters) |
Modify Channel Permissions
Edits the channel permission overwrites for a user or role in a channel. Only usable for guild channels. Requires the `MANAGE_ROLES` permission. Only permissions you have in the guild or parent channel (if applicable) can be allowed/denied (unless you have a `MANAGE_ROLES` overwrite in the channel). Returns a 204 empty response on success. Fires a [Channel Update](/gateway/gateway-events#channel-update) Gateway event. For more information about permissions, see [permissions](/topics/permissions#permissions).
###### JSON Params
| Field | Type | Description |
| ------ | ------- | ---------------------------------------------------------------------------------- |
| type | integer | Either 0 (role) or 1 (member) |
| allow? | string | The bitwise value of all [allowed permissions](/topics/permissions#permissions) |
| deny? | string | The bitwise value of all [disallowed permissions](/topics/permissions#permissions) |
Delete Channel Permission
Deletes a channel permission overwrite for a user or role in a channel. Only usable for guild channels. Requires the `MANAGE_ROLES` permission. Returns a 204 empty response on success. Fires a [Channel Update](/gateway/gateway-events#channel-update) Gateway event. For more information about permissions, see [permissions](/topics/permissions#permissions)
Follow Channel
Follows a News Channel to send messages to a target channel. Requires the `MANAGE_WEBHOOKS` permission in the target channel. Returns a [followed channel](#followed-channel-object) object on success. Fires a [Webhooks Update](/gateway/gateway-events#webhooks-update) Gateway event for the target channel.
###### JSON Params
| Field | Type | Description |
| ------------------ | --------- | ---------------------------- |
| webhook_channel_id | snowflake | The ID of the target channel |
Trigger Typing Indicator
Posts a typing indicator for the specified channel. Returns a 204 empty response on success. Fires a [Typing Start](/gateway/gateway-events#typing-start) Gateway event.
If the user has hit the specified per-user rate limit in the channel, the response will instead be a 200 OK with the below response body.
Official clients expire a typing indicator 10 seconds after the last [Typing Start](/gateway/gateway-events#typing-start) Gateway event.
###### Response Body
| Field | Type | Description |
| -------------------------- | ------ | ------------------------------------------------------------------- |
| message_send_cooldown_ms? | number | Duration (in milliseconds) before the user can send another message |
| thread_create_cooldown_ms? | number | Duration (in milliseconds) before the user can create a new thread |
Get Call Eligibility
Checks if the current user is eligible to ring a call in the DM channel.
###### Response Body
| Field | Type | Description |
| -------- | ------- | ------------------------------------------------------------------------ |
| ringable | boolean | Whether the user is additionally eligible to ring the other recipient(s) |
Modify Call
Modifies the active call in the private channel. Returns a 204 empty response on success. Fires a [Call Update](/gateway/gateway-events#call-update) Gateway event.
This endpoint requires an active call to do anything.
###### JSON Params
| Field | Type | Description |
| ------- | ------ | ------------------------------------------------------------------------ |
| region? | string | The [voice region](/resources/voice#voice-region-object) ID for the call |
Ring Channel Recipients
Rings the recipients of a private channel to notify them of an active call. Returns a 204 empty response on success. Fires a [Call Update](/gateway/gateway-events#call-update) Gateway event.
This endpoint requires an active call to do anything.
###### JSON Params
| Field | Type | Description |
| ----------- | ----------------- | ------------------------------------ |
| recipients? | ?array[snowflake] | The recipients to ring (default all) |
Stop Ringing Channel Recipients
Stops ringing the recipients of a private channel. Returns a 204 empty response on success. Fires a [Call Update](/gateway/gateway-events#call-update) Gateway event.
This endpoint requires an active call to do anything.
###### JSON Params
| Field | Type | Description |
| ----------- | ----------------- | ----------------------------------------------------- |
| recipients? | ?array[snowflake] | The recipients to stop ringing (default current user) |
Add Channel Recipient
Adds a recipient to a private channel.
If operating on a group DM, returns a 204 empty response on success. Fires a [Channel Recipient Add](/gateway/gateway-events#channel-recipient-add) Gateway event.
If operating on a DM, returns a [group DM channel](#channel-object) object on success. Fires a [Channel Create](/gateway/gateway-events#channel-create) Gateway event.
Using this endpoint on a DM will create a group DM with the current user, DM recipient, and the new recipient.
The received [Channel Create](/gateway/gateway-events#channel-create) Gateway event will contain an extra `origin_channel_id` field, which is the ID of the DM that was converted.
Regular group DMs can have up to 10 recipients. Employee group DMs can have up to 25 recipients.
In a managed group DM, only the managing application can add recipients.
###### JSON Params
| Field | Type | Description |
| ----------------- | ------ | --------------------------------------------------------------------- |
| access_token? ^1^ | string | Access token of a user that has granted your app the `gdm.join` scope |
| nick? ^2^ | string | Nickname of the user being added |
^1^ Only required for OAuth2 requests.
^2^ Not applicable when operating on a DM.
Remove Channel Recipient
Removes a recipient from a group DM. Requires ownership of the target channel. Returns a 204 empty response on success. Fires a [Channel Recipient Remove](/gateway/gateway-events#channel-recipient-remove) Gateway event.
Update Message Request
Modifies a message request's status. Returns a [DM channel](#channel-object) object on success. Fires a [Channel Update](/gateway/gateway-events#channel-update) Gateway event.
Consent statuses other than `ACCEPTED` are only usable by Discord employees.
###### JSON Params
| Field | Type | Description |
| -------------- | ------- | ----------------------------------------- |
| consent_status | integer | The new [consent status](#consent-status) |
##### Consent Status
| Value | Name | Description |
| ----- | ----------- | -------------------------------- |
| 0 | UNSPECIFIED | The DM isn't a message request |
| 1 | PENDING | The message request is pending |
| 2 | ACCEPTED | The message request was accepted |
| 3 | REJECTED | The message request was rejected |
Reject Message Request
Rejects and deletes a pending message request. Returns a [DM channel](#channel-object) object on success. Fires [Channel Update](/gateway/gateway-events#channel-update), Message ACK, [Channel Delete](/gateway/gateway-events#channel-delete), and optionally [DM Settings Upsell Show](/gateway/gateway-events#dm-settings-upsell-show) Gateway events.
Batch Reject Message Requests
Rejects and deletes multiple pending message requests. Returns a list of [DM channel](#channel-object) objects on success. Fires multiple [Channel Update](/gateway/gateway-events#channel-update), Message ACK, [Channel Delete](/gateway/gateway-events#channel-delete), and optionally [DM Settings Upsell Show](/gateway/gateway-events#dm-settings-upsell-show) Gateway events.
###### JSON Params
| Field | Type | Description |
| ----------- | ---------------- | -------------------------------------------------- |
| channel_ids | array[snowflake] | The IDs of the message requests to reject (max 50) |
Get Supplemental Message Request Data
Returns a list of [supplemental message request](#supplemental-message-request-structure) objects with the message that triggered each message request.
###### Query String Params
| Field | Type | Description |
| ----------- | ---------------- | ----------------------------------------------- |
| channel_ids | array[snowflake] | The IDs of the message requests to fetch (1-25) |
###### Supplemental Message Request Structure
| Field | Type | Description |
| --------------- | --------------------------------------------------- | ----------------------------- |
| channel_id | snowflake | The ID of the message request |
| message_preview | [message](/resources/message#message-object) object | The trigger message |
Acknowledge Blocked User Warning
Acknowledges that a group DM contains users the current user has blocked. Returns a 200 empty response on success. Fires a [Channel Update](/gateway/gateway-events#channel-update) Gateway event.
Acknowledge Safety Warnings
Dismisses safety warnings in a DM. Returns a 200 empty response on success. Fires a [Channel Update](/gateway/gateway-events#channel-update) Gateway event.
###### JSON Params
| Field | Type | Description |
| ----------- | ------------- | ------------------------------------------ |
| warning_ids | array[string] | The IDs of the warnings to dismiss (1-100) |
Add Safety Warning
Adds a safety warning to a DM. Returns a 200 empty response on success. Fires a [Channel Update](/gateway/gateway-events#channel-update) Gateway event.
This endpoint is only usable by Discord employees.
###### JSON Params
| Field | Type | Description |
| ------------------- | ------- | --------------------------------------------------------- |
| safety_warning_type | integer | The [type of safety warning](#safety-warning-type) to add |
Delete Safety Warnings
Deletes all safety warnings in a DM. Returns a 200 empty response on success. Fires a [Channel Update](/gateway/gateway-events#channel-update) Gateway event.
This endpoint is only usable by Discord employees.
Report Safety Warning False Positive
Reports all safety warnings in a DM as false positives. Returns a 200 empty response on success. Fires a [Channel Update](/gateway/gateway-events#channel-update) Gateway event.
This endpoint is only usable by Discord employees.
List Guild Active Threads
Returns all active threads in the guild, including public and private threads. Threads are ordered by their `id`, in descending order.
This endpoint is not usable by user accounts.
###### Response Body
| Field | Type | Description |
| ------- | ----------------------------------------------------- | --------------------------------------------------------------------------- |
| threads | array[[channel](#channel-object) object] | The active threads |
| members | array[[thread members](#thread-member-object) object] | A thread member object for each returned thread the current user has joined |
List Active Threads
Returns all active threads in the channel, including public and private threads. Threads are ordered by their `id`, in descending order. User must be a member of the guild.
This endpoint is not usable by user accounts.
This endpoint is deprecated and removed in v10. It is replaced by [List Guild Active Threads](#list-guild-active-threads).
###### Response Body
| Field | Type | Description |
| ------- | ---------------------------------------------------- | --------------------------------------------------------------------------- |
| threads | array[[channel](#channel-object) object] | The active threads |
| members | array[[thread member](#thread-member-object) object] | A thread member object for each returned thread the current user has joined |
List Public Archived Threads
Returns archived threads in the channel that are public. When called on a `GUILD_TEXT` channel, returns threads of [type](#channel-type) `PUBLIC_THREAD`. When called on a `GUILD_NEWS` channel returns threads of [type](#channel-type) `NEWS_THREAD`. Threads are ordered by `archive_timestamp`, in descending order. Requires the `READ_MESSAGE_HISTORY` permission.
###### Query String Params
| Field | Type | Description |
| ------- | ----------------- | --------------------------------------------------- |
| before? | ISO8601 timestamp | Get threads before this timestamp |
| limit? | integer | Max number of threads to return (2-100, default 50) |
###### Response Body
| Field | Type | Description |
| -------- | ---------------------------------------------------- | -------------------------------------------------------------------------------------------- |
| threads | array[[channel](#channel-object) object] | The public, archived threads |
| members | array[[thread member](#thread-member-object) object] | A thread member object for each returned thread the current user has joined |
| has_more | boolean | Whether there are potentially additional threads that could be returned on a subsequent call |
List Private Archived Threads
Returns archived threads in the channel that are of [type](#channel-type) `PRIVATE_THREAD`. Threads are ordered by `archive_timestamp`, in descending order. Requires both the `READ_MESSAGE_HISTORY` and `MANAGE_THREADS` permissions.
###### Query String Params
| Field | Type | Description |
| ------- | ----------------- | --------------------------------------------------- |
| before? | ISO8601 timestamp | Get threads before this timestamp |
| limit? | integer | Max number of threads to return (2-100, default 50) |
###### Response Body
| Field | Type | Description |
| -------- | ---------------------------------------------------- | -------------------------------------------------------------------------------------------- |
| threads | array[[channel](#channel-object) object] | The private, archived threads |
| members | array[[thread member](#thread-member-object) object] | A thread member object for each returned thread the current user has joined |
| has_more | boolean | Whether there are potentially additional threads that could be returned on a subsequent call |
List Joined Private Archived Threads
Returns archived threads in the channel that are of [type](#channel-type) `PRIVATE_THREAD`, and the user has joined. Threads are ordered by their `id`, in descending order. Requires the `READ_MESSAGE_HISTORY` permission.
###### Query String Params
| Field | Type | Description |
| ------- | --------- | --------------------------------------------------- |
| before? | snowflake | Get threads before this channel ID |
| limit? | integer | Max number of threads to return (2-100, default 50) |
###### Response Body
| Field | Type | Description |
| -------- | ---------------------------------------------------- | -------------------------------------------------------------------------------------------- |
| threads | array[[channel](#channel-object) object] | The private, archived threads the current user has joined |
| members | array[[thread member](#thread-member-object) object] | A thread member object for each returned thread the current user has joined |
| has_more | boolean | Whether there are potentially additional threads that could be returned on a subsequent call |
Search Threads
Returns threads in the channel that match the search parameters. Requires the `READ_MESSAGE_HISTORY` permission.
If the entity you are searching is not yet indexed, the endpoint will return a 202 accepted response. The response body will not contain any search results, and will look similar to an error response:
```json
{
"message": "Index not yet available. Try again later",
"code": 110000,
"documents_indexed": 0,
"retry_after": 2
}
```
You should retry the request after the timeframe specified in the `retry_after` field. If the `retry_after` field is `0`, you should retry the request after a short delay.
See [the unavailable resources section](/topics/rate-limits#unavailable-resources) for more information.
###### Query String Params
| Field | Type | Description |
| ------------ | ---------------- | -------------------------------------------------------------------------------------------- |
| name? | string | Search query to look for matching threads (max 100 characters) |
| slop? | integer | Max number of words to skip between matching tokens in the search query (max 100, default 2) |
| tag? | array[snowflake] | The tag IDs to filter results by (max 20) |
| tag_setting? | string | [How to restrict](#search-tag-setting) the returned threads by tag (default `match_some`) |
| archived? | boolean | Whether to restrict the search to only active or archived threads (default both) |
| sort_by? | string | The [sorting algorithm](#thread-sort-mode) to use |
| sort_order? | string | The direction to sort (`asc` or `desc`, default `desc`) |
| limit? | integer | Max number of threads to return (1-25, default 25) |
| offset? | integer | Number of threads to skip before returning results (max 9975) |
| max_id? ^1^ | snowflake | Get threads before this thread ID |
| min_id? ^1^ | snowflake | Get threads after this thread ID |
^1^ When sorting by `creation_time`, these parameters may be used for pagination instead of `offset`. This allows search to paginate through more than 10,000 results.
###### Thread Sort Mode
| Value | Description |
| ----------------- | ----------------------------------------------------- |
| last_message_time | Sort by the last message sent in the thread (default) |
| archive_time | Sort by when the thread was last archived |
| relevance | Sort by relevance to the current user |
| creation_time | Sort by when the thread was created |
###### Response Body
| Field | Type | Description |
| ------------------- | ---------------------------------------------------------- | -------------------------------------------------------------------------------------------- |
| threads | array[[channel](#channel-object) object] | The threads that match the search parameters |
| members | array[[thread member](#thread-member-object) object] | A thread member object for each returned thread the current user has joined |
| has_more | boolean | Whether there are potentially additional threads that could be returned on a subsequent call |
| total_results | integer | The total number of threads that match the search parameters |
| first_messages? ^1^ | array[[message](/resources/message#message-object) object] | The first messages of each thread |
^1^ Only returned in thread-only channels.
Create Thread from Message
Creates a new thread from an existing message. Returns a [channel](#channel-object) on success. Fires a [Thread Create](/gateway/gateway-events#thread-create) and a [Message Update](/gateway/gateway-events#message-update) Gateway event.
When called on a `GUILD_TEXT` channel, creates a `PUBLIC_THREAD`. When called on a `GUILD_NEWS` channel, creates a `NEWS_THREAD`.
The ID of the created thread will be the same as the ID of the message, and as such a message can only have a single thread created from it.
###### JSON Params
| Field | Type | Description |
| ---------------------- | ------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| name | string | The name of the channel (1-100 characters) |
| auto_archive_duration? | integer | Duration in minutes to stop showing in the channel list after inactivity (one of 60, 1440, 4320, 10080, default 4320) |
| rate_limit_per_user? | integer | Duration in seconds a user has to wait before sending another message (max 21600); bots, as well as users with the permission `MANAGE_MESSAGES` or `MANAGE_CHANNELS`, are unaffected |
| location? | string | The analytics location the request initiated from (max 100 characters) |
Create Thread
Creates a new thread that is not connected to an existing message. Requires the `CREATE_PUBLIC_THREADS` or `CREATE_PRIVATE_THREADS` permission, depending on the type of thread being created.
Returns a [channel](#channel-object) (with an optional extra [`message`](/resources/message#message-object) key containing the starter message) on success. Fires a [Thread Create](#channel-object) Gateway event.
In thread-only channels:
- The type of the created thread is `PUBLIC_THREAD`.
- See [message formatting](/reference#message-formatting) for more information on how to properly format messages.
- The current user must have the `SEND_MESSAGES` permission (`CREATE_PUBLIC_THREADS` is ignored).
- The maximum request size when sending a message is **100 MiB**.
- For the embed object, you can set every field except `type` (it will be `rich` regardless of if you try to set it), `provider`, `video`, and any `height`, `width`, or `proxy_url` values for images.
###### JSON/Form Params
| Field | Type | Description |
| ---------------------- | ---------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| name | string | The name of the channel (1-100 characters) |
| auto_archive_duration? | integer | Duration in minutes to stop showing in the channel list after inactivity (one of 60, 1440, 4320, 10080, default 4320) |
| rate_limit_per_user? | integer | Duration in seconds a user has to wait before sending another message (max 21600); bots, as well as users with the permission `MANAGE_MESSAGES` or `MANAGE_CHANNELS`, are unaffected |
| location? | string | The analytics location the request initiated from (max 100 characters) |
| type? ^1^ | integer | the [type of thread](#channel-type) to create (default `PRIVATE_THREAD`) |
| invitable? | boolean | Whether non-moderators can add other non-moderators to a thread; only available when creating a private thread |
| applied_tags? | array[snowflake] | The IDs of the tags that are applied to a thread in a thread-only channel (max 5) |
| message? ^1^ | [thread-only channel message](#thread-only-channel-message-structure) object | Contents of the first message in the thread |
^1^ In API v10, this will be changed to be a required field, with no default.
^2^ Required (and only available) when creating a thread in a thread-only channel.
###### Thread-Only Channel Message Structure
Note that when sending a message, you must provide a value for **at least one of** `content`, `embeds`, `components`, `sticker_ids`, `activity`, or `files[n]`.
| Field | Type | Description |
| ----------------- | ------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------ |
| content? | string | The message contents (max 2000 characters) |
| embeds? ^2^ | array[[embed](/resources/message#embed-object) object] | Embedded `rich` content (max 6000 characters, max 10) |
| allowed_mentions? | [allowed mention](/resources/message#allowed-mentions-object) object | Allowed mentions for the message |
| components? ^2^ | array[[message component](/resources/components#component-object) object] | Components to include with the message |
| sticker_ids? | array[snowflake] | IDs of up to 3 [stickers](/resources/sticker#sticker-object) to send in the message |
| activity? | [message activity](/resources/message#message-activity-object) object | The rich presence activity to invite users to |
| application_id? | snowflake | The application ID of the activity to create a rich presence invite for (defaults to the primary activity if unspecified) |
| flags? | integer | The [message's flags](/resources/message#message-flags) (only `SUPPRESS_EMBEDS`, `SUPPRESS_NOTIFICATIONS`, and `VOICE_MESSAGE` can be set) |
| files[n]? ^1^ | file contents | Contents of the file being sent (max 10) |
| attachments? ^1^ | array[partial [attachment](/resources/message#attachment-object) object] | Partial attachment objects with `filename` and `description` (max 10) |
^1^ See [Uploading Files](/reference#uploading-files) for details.
^2^ Cannot be used by user accounts.
Get Channel Post Data
Returns a mapping of thread IDs to their [post data](#thread-post-data-structure) in a thread-only channel. Requires the `READ_MESSAGE_HISTORY` permission.
###### JSON Params
| Field | Type | Description |
| ---------- | ---------------- | ------------------------------------------- |
| thread_ids | array[snowflake] | The IDs of the threads to get post data for |
###### Response Body
| Field | Type | Description |
| ------- | ------ | ------------------------------------------------------------------------- |
| threads | object | A mapping of thread IDs to their [post data](#thread-post-data-structure) |
###### Thread Post Data Structure
| Field | Type | Description |
| ------------- | ------------------------------------------------------------ | ------------------------------- |
| owner | ?[guild member](/resources/guild#guild-member-object) object | The owner of the thread |
| first_message | ?[message](/resources/message#message-object) object | The first message in the thread |
##### Example Response
```json
{
"threads": {
"1075957063890509894": {
"first_message": null,
"owner": null
}
}
}
```
List Thread Members
Returns an array of [thread members](#thread-member-object) objects that are members of the thread. Requires the `VIEW_CHANNEL` permission.
This endpoint is not usable by user accounts and is restricted according to whether the `GUILD_MEMBERS` [Privileged Intent](/gateway/using-gateway#privileged-intents) is enabled for the application.
Starting in API v11, this endpoint will always return paginated results. Paginated results can be enabled before API v11 by setting `with_member` to `true`.
###### Query String Params
| Field | Type | Description |
| ------------ | --------- | --------------------------------------------------------------- |
| with_member? | boolean | Whether to include a guild member object for each thread member |
| after? | snowflake | Get thread members after this user ID |
| limit? | integer | Max number of thread members to return (1-100, default 100) |
When `with_member` is set to `true`, the results will be paginated and each thread member object will include a `member` field containing a [guild member](/resources/guild#guild-member-object) object. Else, pagination is not available.
Get Thread Member
Returns a [thread member](#thread-member-object) object for the specified user if they are a member of the thread. Requires the `VIEW_CHANNEL` permission.
This endpoint is not usable by user accounts.
###### Query String Params
| Field | Type | Description |
| ------------ | ------- | -------------------------------------------------------------- |
| with_member? | boolean | Whether to include a guild member object for the thread member |
Join Thread
Adds the current user to a thread. Requires the `VIEW_CHANNEL` permission. Also requires the thread is not archived. Returns a 204 empty response on success. Fires a [Thread Members Update](/gateway/gateway-events#thread-members-update) and a [Thread Create](/gateway/gateway-events#thread-create) Gateway event.
###### Query String Params
| Field | Type | Description |
| --------- | ------ | ---------------------------------------------------------------------- |
| location? | string | The analytics location the request initiated from (max 100 characters) |
Add Thread Member
Adds another member to a thread. Requires the `SEND_MESSAGES` permission. Also requires the thread is not archived. Returns a 204 empty response on success. Fires a [Thread Members Update](/gateway/gateway-events#thread-members-update) Gateway event.
###### Query String Params
| Field | Type | Description |
| --------- | ------ | ---------------------------------------------------------------------- |
| location? | string | The analytics location the request initiated from (max 100 characters) |
Modify Thread Settings
Updates the current user's thread settings. User must be a member of the thread. Returns a [thread member](#thread-member-object) on success, or a 204 empty response if nothing changed. Fires a [Thread Member Update](/gateway/gateway-events#thread-member-update) Gateway event.
###### JSON Params
| Field | Type | Description |
| ------------ | ------------------------------------------------------------------ | ---------------------------------------------------------------------------------------- |
| flags? | integer | The user's [thread flags](#thread-member-object) flags (all except the first can be set) |
| muted? | boolean | Whether the user has muted the thread |
| mute_config? | ?[mute config](/resources/user-settings#mute-config-object) object | The mute metadata for the thread |
Leave Thread
Removes the current user from a thread. Also requires the thread is not archived. Returns a 204 empty response on success. Fires a [Thread Members Update](/gateway/gateway-events#thread-members-update) Gateway event.
###### Query String Params
| Field | Type | Description |
| --------- | ------ | ---------------------------------------------------------------------- |
| location? | string | The analytics location the request initiated from (max 100 characters) |
Remove Thread Member
Removes a member from a thread. Requires the `MANAGE_THREADS` permission, or the creator of the thread if it is a `PRIVATE_THREAD`. Also requires the thread is not archived. Returns a 204 empty response on success. Fires a [Thread Members Update](/gateway/gateway-events#thread-members-update) Gateway event.
###### Query String Params
| Field | Type | Description |
| --------- | ------ | ---------------------------------------------------------------------- |
| location? | string | The analytics location the request initiated from (max 100 characters) |
Create Channel Tag
Creates a new tag in the thread-only channel. Requires the `MANAGE_CHANNELS` permission. Returns a [channel](#channel-object) object on success. Fires a [Channel Update](/gateway/gateway-events#channel-update) Gateway event.
###### JSON Params
| Field | Type | Description |
| --------------- | ---------- | ----------------------------------------------------------------------------------------------------------------------------- |
| name | string | The name of the tag (max 50 characters) |
| moderated? | boolean | Whether this tag can only be added to or removed from threads by members with the `MANAGE_THREADS` permission (default false) |
| emoji_id? ^1^ | ?snowflake | The ID of a guild's custom emoji |
| emoji_name? ^1^ | ?string | The unicode character of the emoji |
^1^ At most one of `emoji_id` and `emoji_name` may be set to a non-null value.
Modify Channel Tag
Replaces a tag in the thread-only channel. Requires the `MANAGE_CHANNELS` permission. Returns a [channel](#channel-object) object on success. Fires a [Channel Update](/gateway/gateway-events#channel-update) Gateway event.
###### JSON Params
| Field | Type | Description |
| --------------- | ---------- | ----------------------------------------------------------------------------------------------------------------------------- |
| name | string | The name of the tag (max 50 characters) |
| moderated? | boolean | Whether this tag can only be added to or removed from threads by members with the `MANAGE_THREADS` permission (default false) |
| emoji_id? ^1^ | ?snowflake | The ID of a guild's custom emoji |
| emoji_name? ^1^ | ?string | The unicode character of the emoji |
^1^ At most one of `emoji_id` and `emoji_name` may be set to a non-null value.
Delete Channel Tag
Deletes a tag in the thread-only channel. Requires the `MANAGE_CHANNELS` permission. Returns a [channel](#channel-object) object on success. Fires a [Channel Update](/gateway/gateway-events#channel-update) Gateway event.
Get Channel Linked Accounts
This endpoint is only usable with an OAuth2 access token with the `dm_channels.read` scope.
Returns the linked accounts for users in a group DM.
###### Query String Params
| Field | Type | Description |
| --------- | ---------------- | ----------------------------------- |
| user_ids? | array[snowflake] | User IDs to get linked accounts for |
###### Response Body
| Field | Type | Description |
| --------------- | ------------------------------------------------------------------------- | -------------------------------------------- |
| linked_accounts | map[snowflake, array[[linked account](#linked-account-structure) object]] | The connected accounts for every linked user |
###### Linked Account Structure
| Field | Type | Description |
| ----- | ------ | ---------------------------- |
| id | string | The ID of the linked account |
| name | string | The name of the account |
#### Example Response
```json
{
"linked_accounts": {
"150745989836308480": [
{
"id": "3067653496106923",
"name": "Cynosphere"
},
{
"id": "OGE2N2M2MDE4ZWY4YTM1YzI4Y2RkNmU0MDkyZGNiOWE3Y2I0YjhlZTZhNDNkYThkZjQyZjNhZjRhNGRkOGE3YQ",
"name": "Cynosphere"
}
],
"1001086404203389018": [
{
"id": "3076033886540956",
"name": "Dziurwel14"
}
]
}
}
```
Remove Lobby Link
Unlinks the linked lobby from the channel. Requires the `MANAGE_CHANNELS` permission. Returns the updated [channel](#channel-object) object on success. Fires a [Lobby Update](/gateway/gateway-events#lobby-update) and [Channel Update](/gateway/gateway-events#channel-update) Gateway event.
---
# Guild Scheduled Events
Link: https://docs.discord.food/resources/guild-scheduled-event
Scheduled events are a way to plan and organize events in a guild. They can be associated with a stage channel, voice channel, or an external location.
### Guild Scheduled Event Object
###### Guild Scheduled Event Structure
| Field | Type | Description |
| -------------------------------- | ------------------------------------------------------------------------ | -------------------------------------------------------------------------- |
| id | snowflake | The ID of the scheduled event |
| guild_id | snowflake | The ID of the guild the scheduled event belongs to |
| channel_id ^2^ | ?snowflake | The ID of the channel in which the scheduled event will be hosted |
| creator_id? ^1^ | ?snowflake | The ID of the user that created the scheduled event |
| creator? | partial [user](/resources/user#user-object) object | The user that created the scheduled event |
| name | string | The name of the scheduled event (1-100 characters) |
| description? | ?string | The description for the scheduled event (1-1000 characters) |
| scheduled_start_time | ISO8601 timestamp | When the scheduled event will start |
| scheduled_end_time ^2^ | ?ISO8601 timestamp | When the scheduled event will end |
| auto_start? ^3^ | boolean | Whether the event should automatically start at the scheduled start time |
| privacy_level | integer | The [privacy level](/resources/guild#privacy-level) of the scheduled event |
| status | integer | The [status](#guild-scheduled-event-status) of the scheduled event |
| entity_type | integer | The [type](#guild-scheduled-event-entity-type) of scheduled event |
| entity_id | ?snowflake | The ID of an entity associated with the scheduled event |
| entity_metadata ^2^ | ?[entity metadata](#guild-scheduled-event-entity-metadata) object | Additional metadata for the scheduled event |
| user_count? ^4^ | integer | The number of users subscribed to the scheduled event |
| image? | ?string | The [cover image hash](/reference#cdn-formatting) for the scheduled event |
| recurrence_rule | ?[recurrence rule](#guild-scheduled-event-recurrence-rule-object) object | The definition for how often this event should recur |
| guild_scheduled_event_exceptions | array[[exception](#guild-scheduled-event-exception-object) object] | Exceptions to the recurrence rule for this event |
^1^ `creator_id` will be null and `creator` will not be included for events created before October 25th, 2021, when the concept of `creator_id` was introduced and tracked.
^2^ See [field requirements by entity type](#guild-scheduled-event-entity-type-validation) to understand the relationship between `entity_type` and the following fields: `channel_id`, `entity_metadata`, and `scheduled_end_time`.
^3^ Only included in [Gateway events](/gateway/gateway-events#guild-scheduled-events). See [the automations section](#guild-scheduled-event-status-update-automation) for more info on how to determine this manually.
^4^ Only included when fetched from the [List Guild Scheduled Events](#list-guild-scheduled-events) or [Get Guild Scheduled Event](#get-guild-scheduled-event) endpoints with `with_user_count` set to `true`.
###### Example Guild Scheduled Event
```json
{
"id": "1059954443799498922",
"guild_id": "1046920999469330512",
"name": "Alien meetup",
"description": "Aliens only!",
"channel_id": null,
"creator_id": "787017887877169173",
"creator": {
"id": "787017887877169173",
"username": "dziurwa",
"avatar": "cff3479a14360e4223f151eb8ad63dec",
"discriminator": "0",
"public_flags": 4194560,
"banner": null,
"accent_color": null,
"global_name": "Dziurwa",
"avatar_decoration_data": null,
"primary_guild": null
},
"image": "4b07ee3046773e8f2c8be856a70bd1a7",
"scheduled_start_time": "2023-12-31T23:00:00+00:00",
"scheduled_end_time": "2024-01-01T23:00:00+00:00",
"status": 1,
"entity_type": 3,
"entity_id": null,
"recurrence_rule": null,
"user_count": 7,
"privacy_level": 2,
"sku_ids": [],
"guild_scheduled_event_exceptions": [],
"entity_metadata": {
"location": "somwhere in ocean"
}
}
```
###### Guild Scheduled Event Entity Metadata
| Field | Type | Description |
| ------------- | ------ | ---------------------------------------- |
| location? ^1^ | string | Location of the event (1-100 characters) |
^1^ Required for events with an `entity_type` of `EXTERNAL`.
###### Guild Scheduled Event Status
| Value | Name | Description |
| ----- | ------------- | --------------------------------------- |
| 1 | SCHEDULED | The scheduled event has not started yet |
| 2 | ACTIVE | The scheduled event is currently active |
| 3 | COMPLETED ^1^ | The scheduled event has ended |
| 4 | CANCELED ^1^ | The scheduled event was canceled |
^1^ Once `status` is set to `COMPLETED` or `CANCELED`, the `status` can no longer be updated.
###### Guild Scheduled Event Entity Type
| Value | Name | Description |
| ----- | -------------- | ------------------------------------------------------------------ |
| 1 | STAGE_INSTANCE | The scheduled event is in a stage channel |
| 2 | VOICE | The scheduled event is in a voice channel |
| 3 | EXTERNAL | The scheduled event is somewhere else™ not associated with Discord |
| 4 | PRIME_TIME | The scheduled event is a prime time event |
###### Guild Scheduled Event Entity Type Validation
The following table shows field requirements based on current entity type.
| Entity Type | channel_id | entity_metadata | scheduled_end_time |
| -------------- | ---------- | ------------------------ | ------------------ |
| STAGE_INSTANCE | required | null | - |
| VOICE | required | null | - |
| EXTERNAL | null | required with `location` | required |
### Guild Scheduled Event Recurrence Rule Object
Discord's recurrence rule is a subset of the behaviors [defined in the iCalendar RFC](https://datatracker.ietf.org/doc/html/rfc5545) and implemented using [Python's dateutil rrule](https://dateutil.readthedocs.io/en/stable/rrule.html).
There are currently many limitations to this system. Please see "System limitations" below.
###### Guild Scheduled Event Recurrence Rule Structure
| Field | Type | Description |
| --------------- | ---------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------- |
| start | ISO8601 timestamp | Starting time of the recurrence interval |
| end ^1^ | ?ISO8601 timestamp | Ending time of the recurrence interval |
| frequency | integer | [How often the event occurs](#guild-scheduled-event-recurrence-rule---frequency) |
| interval | integer | The spacing between the events, defined by `frequency`; for example, `frequency` of `WEEKLY` and an `interval` of `2` would be "every other week" |
| by_weekday | ?array[integer] | [Specific days within a week](#guild-scheduled-event-recurrence-rule---weekday) for the event to recur on |
| by_n_weekday | ?array[[recurrence rule - n_weekday](#guild-scheduled-event-recurrence-rule---n_weekday-structure) object] | Specific days within a specific week (1-5) to recur on |
| by_month | ?array[integer] | [Specific months](#guild-scheduled-event-recurrence-rule---month) to recur on |
| by_month_day | ?array[integer] | Specific dates within a month to recur on |
| by_year_day ^1^ | ?array[integer] | Specific days within a year to recur on (1-364) |
| count ^1^ | ?integer | The total amount of times that the event is allowed to recur before stopping |
^1^ Cannot currently be set externally.
The current system limitations are present due to how reoccurring event data needs to be displayed in the client.
In the future, we would like to open the system up to have fewer / none of these restrictions.
###### The following fields cannot be set by the client
- `count`
- `end`
- `by_year_day`
###### The following combinations are mutually exclusive
- `by_weekday`
- `by_n_weekday`
- `by_month` + `by_month_day`
###### `by_weekday`
- Only valid for daily and weekly events (`frequency` of `DAILY` or `WEEKLY`)
- when used in a daily event (`frequency` is `DAILY`)
- The values present in the `by_weekday` event must be a "known set" of weekdays.
- The following are current allowed "sets"
- Monday - Friday (`[0, 1, 2, 3, 4]`)
- Tuesday - Saturday (`[1, 2, 3, 4, 5]`)
- Sunday - Thursday (`[6, 0, 1, 2, 3]`)
- Friday & Saturday (`[4, 5]`)
- Saturday & Sunday (`[5, 6]`)
- Sunday & Monday (`[6, 0]`)
- when used in a weekly event (`frequency` is `WEEKLY`)
- `by_weekday` array currently can only be have length of `1`
- i.e: You can only select a single day within a week to have a recurring event on
- If you wish to have multiple days within a week have a recurring event, please use a `frequency` of `DAILY`
- Also, see `interval` below for "every-other" week information
###### `by_n_weekday`
- Only valid for monthly events (`frequency` of `MONTHLY`)
- `by_n_weekday` array currently can only have a length of `1`
- i.e: You can only select a single day within a month to have a recurring event on
###### `by_month` and `by_month_day`
- Only valid for annual event (`frequency` is `YEARLY`)
- both `by_month` and `by_month_day` must be provided
- both `by_month` and `by_month_day` arrays must have a length of `1`
- (i.e. you can only set a single date for annual events)
###### `interval` can only be set to a value other than `1` when `frequency` is set to `WEEKLY`
- In this situation, interval can be set to `2`
- This allowance enables "every-other week" events
- Due to the limitations placed on `by_weekday` this means that if you wish to use "every-other week" functionality
you can only do so for a single day.
**Every weekday**
```js
frequency = 3; // Frequency.DAILY
interval = 1;
by_weekday = [0, 1, 2, 3, 4]; // [Weekday.MONDAY, ..., Weekday.FRIDAY]
```
**Every Wednesday**
```js
frequency = 2; // Frequency.WEEKLY
interval = 1;
by_weekday = [2]; // [Weekday.WEDNESDAY]
```
**Every other Wednesday**
```js
frequency = 2; // Frequency.WEEKLY
interval = 2;
by_weekday = [2]; // [Weekday.WEDNESDAY]
```
**Monthly on the fourth Wednesday**
```js
frequency = 1; // Frequency.MONTHLY
interval = 1;
by_n_weekday = [
{
n: 4,
day: 2, // Weekday.WEDNESDAY
},
];
```
**Annually on July 24**
```js
frequency = 0; // Frequency.YEARLY
interval = 1;
by_month = [7]; // [Month.JULY]
by_month_day = [24];
```
###### Guild Scheduled Event Recurrence Rule - Frequency
| Value | Name |
| ----- | ------- |
| 0 | YEARLY |
| 1 | MONTHLY |
| 2 | WEEKLY |
| 3 | DAILY |
###### Guild Scheduled Event Recurrence Rule - Weekday
| Value | Name |
| ----- | --------- |
| 0 | MONDAY |
| 1 | TUESDAY |
| 2 | WEDNESDAY |
| 3 | THURSDAY |
| 4 | FRIDAY |
| 5 | SATURDAY |
| 6 | SUNDAY |
###### Guild Scheduled Event Recurrence Rule - N_Weekday Structure
| Field | Type | Description |
| ----- | ------- | ----------------------------------------------------------------------------------------- |
| n | integer | The week to reoccur on (1-5) |
| day | integer | The [day within the week](#guild-scheduled-event-recurrence-rule---weekday) to reoccur on |
###### Guild Scheduled Event Recurrence Rule - Month
| Value | Name |
| ----- | --------- |
| 1 | JANUARY |
| 2 | FEBRUARY |
| 3 | MARCH |
| 4 | APRIL |
| 5 | MAY |
| 6 | JUNE |
| 7 | JULY |
| 8 | AUGUST |
| 9 | SEPTEMBER |
| 10 | OCTOBER |
| 11 | NOVEMBER |
| 12 | DECEMBER |
### Guild Scheduled Event Exception Object
Represents an exception to the recurrence rule for a guild scheduled event.
###### Guild Scheduled Event Exception Structure
| Field | Type | Description |
| -------------------- | ------------------ | ------------------------------------------------------------------------------------------ |
| event_id | snowflake | The ID of the scheduled event the exception is for |
| event_exception_id | snowflake | A snowflake representing when the scheduled event would have started without the exception |
| is_canceled | boolean | Whether the scheduled event will be skipped on this recurrence |
| scheduled_start_time | ?ISO8601 timestamp | The scheduled event's modified start time for this recurrence |
| scheduled_end_time | ?ISO8601 timestamp | The scheduled event's modified end time for this recurrence |
###### Example Guild Scheduled Event Exception
```json
{
"event_id": "1341289071875461170",
"event_exception_id": "2117779587072000000",
"scheduled_start_time": "2030-02-18T00:01:00+00:00",
"scheduled_end_time": null,
"is_canceled": false
}
```
### Guild Scheduled Event User Object
Represents a user's subscription to a guild scheduled event or override for a specific exception.
###### Guild Scheduled Event User Structure
| Field | Type | Description |
| --------------------------------------- | ----------------------------------------------------------- | ---------------------------------------------------------------------------------- |
| guild_scheduled_event_id | snowflake | The ID of the scheduled event the user subscribed to |
| guild_scheduled_event_exception_id? ^2^ | snowflake | The ID of the specific exception this subscription is for, if any |
| response | integer | The user's [response](#guild-scheduled-event-user-response) to the scheduled event |
| user_id | snowflake | The ID of the user that subscribed to the scheduled event |
| user? ^1^ | partial [user](/resources/user#user-object) object | The user that subscribed to the scheduled event |
| member? ^1^ | [guild member](/resources/guild#guild-member-object) object | Guild member data for the user in the scheduled event's guild, if any |
^1^ Only included when fetched from the [List Guild Scheduled Event Users](#list-guild-scheduled-event-users) endpoint.
^2^ May not necessarily point to an existing exception. The only requirement of this field is that it is a snowflake representing the start time for a specific recurrence.
###### Guild Scheduled Event User Response
| Value | Name | Description |
| ----- | ------------ | --------------------------------------------- |
| 0 | UNINTERESTED | User is not interested in the occurrence |
| 1 | INTERESTED | User is interested in the event or occurrence |
## Endpoints
List User Guild Scheduled Events
Returns an array of [guild scheduled event user](#guild-scheduled-event-user-object) objects for the current user for a given guild.
###### Query String Params
| Field | Type | Description |
| --------- | --------- | ------------------------------------------------------- |
| guild_ids | snowflake | The guild ID to get the subscribed scheduled events for |
List Guild Scheduled Events
Returns a list of `SCHEDULED` and `ACTIVE` [guild scheduled event](#guild-scheduled-event-object) objects for the given guild.
###### Query String Params
| Field | Type | Description |
| ---------------- | ------- | ------------------------------------------------------------------------ |
| with_user_count? | boolean | Whether to include the of users subscribed to each event (default false) |
Get Guild Scheduled Event
Gets a guild scheduled event. Returns a [guild scheduled event](#guild-scheduled-event-object) object.
###### Query String Params
| Field | Type | Description |
| ---------------- | ------- | ------------------------------------------------------------------------ |
| with_user_count? | boolean | Whether to include the of users subscribed to each event (default false) |
Create Guild Scheduled Event
Creates a guild scheduled event in the guild. Returns a [guild scheduled event](#guild-scheduled-event-object) object on success. Fires a [Guild Scheduled Event Create](/gateway/gateway-events#guild-scheduled-event-create) Gateway event.
A guild can have a maximum of 100 events with `SCHEDULED` or `ACTIVE` status at any time.
Creating an event will automatically add you as a subscriber.
###### JSON Params
| Field | Type | Description |
| ----------------------- | ------------------------------------------------------------------------ | ---------------------------------------------------------------------------- |
| channel_id? ^1^ | snowflake | The ID of the channel in which the scheduled event will be hosted |
| entity_metadata? ^2^ | [entity metadata](#guild-scheduled-event-entity-metadata) | Additional metadata for the scheduled event |
| name | string | the name of the scheduled event |
| privacy_level | integer | The [privacy level](/resources/guild#privacy-level) of the scheduled event |
| scheduled_start_time | ISO8601 timestamp | When the scheduled event will start |
| scheduled_end_time? ^2^ | ISO8601 timestamp | When the scheduled event will end |
| description? | string | the description of the scheduled event |
| entity_type | integer | The [entity type](#guild-scheduled-event-entity-type) of the scheduled event |
| image? | [image data](/reference#cdn-data) | The cover image for the scheduled event |
| recurrence_rule? | ?[recurrence rule](#guild-scheduled-event-recurrence-rule-object) object | The definition for how often this event should recur |
^1^ Optional for events with an `entity_type` of `EXTERNAL`.
^2^ Required for events with an `entity_type` of `EXTERNAL`.
Modify Guild Scheduled Event
Modifies a guild scheduled event. Returns the modified [guild scheduled event](#guild-scheduled-event-object) object on success. Fires a [Guild Scheduled Event Update](/gateway/gateway-events#guild-scheduled-event-update) and optionally a [Stage Instance Create](/gateway/gateway-events#stage-instance-create) Gateway event.
To start or end an event, use this endpoint to modify the event's [status](#guild-scheduled-event-status) field.
Starting an event with an `entity_type` of `STAGE_INSTANCE` will automatically create a stage instance.
If an existing stage instance is associated with the channel, it will be overwritten.
Ending an event with an `entity_type` of `STAGE_INSTANCE` will automatically delete any stage instance associated with the event's channel.
Setting `status` to `CANCELED` will cancel all future recurrences of the event as well.
###### JSON Params
| Field | Type | Description |
| ----------------------- | ------------------------------------------------------------------------ | ---------------------------------------------------------------------------- |
| channel_id? ^1^ | ?snowflake | The ID of the channel in which the scheduled event will be hosted |
| entity_metadata? | ?[entity metadata](#guild-scheduled-event-entity-metadata) | Additional metadata for the scheduled event |
| name? | string | The name of the scheduled event |
| privacy_level? | integer | The [privacy level](/resources/guild#privacy-level) of the scheduled event |
| scheduled_start_time? | ISO8601 timestamp | When the scheduled event will start |
| scheduled_end_time? ^1^ | ISO8601 timestamp | When the scheduled event will end |
| description? | ?string | the description of the scheduled event |
| entity_type? ^1^ | integer | The [entity type](#guild-scheduled-event-entity-type) of the scheduled event |
| status? ^2^ | integer | The [status](#guild-scheduled-event-status) of the scheduled event |
| image? | [image data](/reference#cdn-data) | The cover image for the scheduled event |
| recurrence_rule? ^3^ | ?[recurrence rule](#guild-scheduled-event-recurrence-rule-object) object | The definition for how often this event should recur |
^1^ If updating `entity_type` to `EXTERNAL`:
- `channel_id` is required and must be set to `null`
- `entity_metadata` with a `location` field must be provided
- `scheduled_end_time` must be provided
^2^ Only the following are valid status changes:
- SCHEDULED --> ACTIVE
- ACTIVE --> COMPLETED
- SCHEDULED --> CANCELED
^3^ Modifying the `recurrence_rule` may cause all exceptions for an event to be removed.
Delete Guild Scheduled Event
Deletes a guild scheduled event. Returns a 204 empty response on success. Fires a [Guild Scheduled Event Delete](/gateway/gateway-events#guild-scheduled-event-delete) Gateway event.
Create Guild Scheduled Event Exception
Creates an exception to the recurrence rule for a guild scheduled event. Returns a [guild scheduled event exception](#guild-scheduled-event-exception-object) object on success. Fires a [Guild Scheduled Event Exception Create](/gateway/gateway-events#guild-scheduled-event-exception-create) Gateway event.
If an exception with the same `original_scheduled_start_time` already exists, this endpoint will completely overwrite the existing exception.
###### JSON Params
| Field | Type | Description |
| ----------------------------- | ------------------ | ----------------------------------------------------------------- |
| original_scheduled_start_time | ISO8601 timestamp | When the scheduled event would have started without the exception |
| is_canceled? ^1^ | ?boolean | Whether the scheduled event will be skipped on this recurrence |
| scheduled_start_time? ^1^ | ?ISO8601 timestamp | The scheduled event's modified start time for this recurrence |
| scheduled_end_time? ^1^ | ?ISO8601 timestamp | The scheduled event's modified end time for this recurrence |
^1^ At minimum, you must provide a value for one of `is_canceled`, `scheduled_start_time`, or `scheduled_end_time`. Otherwise, the request will fail with an [`180005` JSON error code](/topics/errors#json-error-codes).
Modify Guild Scheduled Event Exception
Modifies an exception to the recurrence rule for a guild scheduled event. Returns the modified [guild scheduled event exception](#guild-scheduled-event-exception-object) object on success. Fires a [Guild Scheduled Event Exception Create](/gateway/gateway-events#guild-scheduled-event-exception-create) Gateway event.
All parameters to this endpoint are optional and nullable. Omitting or setting a `null` value will set it to default.
###### JSON Params
| Field | Type | Description |
| --------------------- | ------------------ | -------------------------------------------------------------- |
| is_canceled? | ?boolean | Whether the scheduled event will be skipped on this recurrence |
| scheduled_start_time? | ?ISO8601 timestamp | The scheduled event's modified start time for this recurrence |
| scheduled_end_time? | ?ISO8601 timestamp | The scheduled event's modified end time for this recurrence |
Delete Guild Scheduled Event Exception
Deletes an exception to the recurrence rule for a guild scheduled event. Returns a 204 empty response on success. Fires a [Guild Scheduled Event Exception Delete](/gateway/gateway-events#guild-scheduled-event-exception-delete) Gateway event.
Get Guild Scheduled Event User Count
Returns the number of users subscribed to a guild scheduled event.
###### Query String Params
| Field | Type | Description |
| ------------------------------------ | ---------------- | ------------------------------------------------------- |
| guild_scheduled_event_exception_ids? | array[snowflake] | The IDs of the exceptions to return counts for (max 10) |
###### Response Body
| Field | Type | Description |
| -------------------------------------- | ----------------------- | ----------------------------------------------------------- |
| guild_scheduled_event_count | integer | The number of users subscribed to the guild scheduled event |
| guild_scheduled_event_exception_counts | map[snowflake, integer] | The number of users subscribed to each exception |
###### Example Response
```json
{
"guild_scheduled_event_count": 18,
"guild_scheduled_event_exception_counts": {
"1456059344486400000": 18
}
}
```
List Guild Scheduled Event Users
Returns a list of users subscribed to a guild scheduled event.
###### Query String Params
| Field | Type | Description |
| -------------------------- | --------- | -------------------------------------------------------------- |
| before? | snowflake | Get users before this user ID |
| after? | snowflake | Get users after this user ID |
| limit? | number | Max number of users to return (1-100, default 100) |
| with_member? | boolean | Whether to include possible guild member data (default false) |
| upgrade_response_type? ^1^ | boolean | Whether to return the new response body format (default false) |
^1^ This parameter is ignored for bots as they always receive the new response body format.
###### Response Body
When `upgrade_response_type` is set to `true`, the response is a list of [guild scheduled event user](#guild-scheduled-event-user-object) objects.
Otherwise, the response looks like this:
| Field | Type | Description |
| ----- | --------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------- |
| users | array[partial [user](/resources/user#user-object) object] | The users subscribed to the scheduled event, with an extra [`guild_member`](/resources/guild#guild-member-object) containing optional guild member data |
Create Guild Scheduled Event User
Subscribes the current user to a guild scheduled event. Returns a [guild scheduled event user](#guild-scheduled-event-user-object) object on success. Fires a [Guild Scheduled Event User Add](/gateway/gateway-events#guild-scheduled-event-user-add) Gateway event.
Delete Guild Scheduled Event User
Unsubscribes the current user from a guild scheduled event. Returns a 204 empty response on success. Fires a [Guild Scheduled Event User Remove](/gateway/gateway-events#guild-scheduled-event-user-remove) Gateway event.
List Guild Scheduled Event Exception Users
Returns a list of [guild scheduled event user](#guild-scheduled-event-user-object) objects subscribed to a specific guild scheduled event exception.
###### Query String Params
| Field | Type | Description |
| ------------ | --------- | ------------------------------------------------------------- |
| before? | snowflake | Get users before this user ID |
| after? | snowflake | Get users after this user ID |
| limit? | number | Max number of users to return (1-100, default 100) |
| with_member? | boolean | Whether to include possible guild member data (default false) |
Create Guild Scheduled Event Exception User
Overrides the user's subscription to a guild scheduled event for a specific exception. Returns a [subscribed guild scheduled event user](#guild-scheduled-event-user-object) object on success. Fires a [Guild Scheduled Event User Add](/gateway/gateway-events#guild-scheduled-event-user-add) Gateway event.
###### JSON Params
| Field | Type | Description |
| -------- | ------- | -------------------------------------------------------------------------------------------- |
| response | integer | The user's [response](#guild-scheduled-event-user-response) to the scheduled event exception |
Delete Guild Scheduled Event Exception User
Removes the user's subscription override for a specific exception. Returns a 204 empty response on success. Fires a [Guild Scheduled Event User Remove](/gateway/gateway-events#guild-scheduled-event-user-remove) Gateway event.
## Guild Scheduled Event Status Update Automation
#### An active scheduled event for a stage channel where all users have left the stage channel will automatically end a few minutes after the last user leaves the channel
When an event with a `status` of `ACTIVE` and `entity_type` of `STAGE_INSTANCE` has no users connected to the stage channel for a certain period of time (on the order of minutes), the event `status` will be automatically set to `COMPLETED`.
#### An active scheduled event for a voice channel where all users have left the voice channel will automatically end a few minutes after the last user leaves the channel
When an event with a `status` of `ACTIVE` and `entity_type` of `VOICE` has no users connected to the voice channel for a certain period of time (on the order of minutes), the event `status` will be automatically set to `COMPLETED`.
#### An external event will automatically begin at its scheduled start time
An event with an `entity_type` of `EXTERNAL` at its `scheduled_start_time` will automatically have `status` set to `ACTIVE`.
#### An external event will automatically end at its scheduled end time
An event with an `entity_type` of `EXTERNAL` at its `scheduled_end_time` will automatically have `status` set to `COMPLETED`.
#### Any scheduled event which has not begun after its scheduled start time will be automatically cancelled after a few hours
Any event with a `status` of `SCHEDULED` after a certain time interval (on the order of hours) beyond its `scheduled_start_time` will have its `status` automatically set to `CANCELED`.
## Guild Scheduled Event Permissions Requirements
A user must be a member of the guild in order to access events for that guild unless the guild is lurkable. If a guild is lurkable,
events in that guild may be visible to lurkers depending on the privacy level and the permissions of any channels associated with the event.
#### Permissions to create an event with entity_type: `STAGE_INSTANCE`
Permissions may be granted at the guild level or for the `channel_id` associated with the event, if applicable.
###### Read Permissions
- `VIEW_CHANNEL`
###### Create Permissions
- `CREATE_EVENTS`
- `MANAGE_CHANNELS`
- `MUTE_MEMBERS`
- `MOVE_MEMBERS`
###### Update Permissions
- `CREATE_EVENTS` for events the user created, otherwise `MANAGE_EVENTS`
- `MANAGE_CHANNELS`
- `MUTE_MEMBERS`
- `MOVE_MEMBERS`
#### Permissions to create an event with entity_type: `VOICE`
Permissions may be granted at the guild level or for the `channel_id` associated with the event, if applicable.
###### Read Permissions
- `VIEW_CHANNEL`
###### Create Permissions
- `CREATE_EVENTS`
- `VIEW_CHANNEL`
- `CONNECT`
###### Update Permissions
- `CREATE_EVENTS` for events the user created, otherwise `MANAGE_EVENTS`
- `VIEW_CHANNEL`
- `CONNECT`
#### Permissions to create an event with entity_type: `EXTERNAL`
###### Read Permissions
- _No other permissions required_
###### Create Permissions
- `CREATE_EVENTS`
###### Update Permissions
- `CREATE_EVENTS` for events the user created, otherwise `MANAGE_EVENTS`
---
# Presences
Link: https://docs.discord.food/resources/presence
A user's presence is their current status and activity. Presences are usually per-guild, but user accounts also receive overall user presences for [friends and implicit relationships](/resources/relationships#relationship-object) (depending on the `NO_AFFINE_USER_IDS` [Gateway capability](/gateway/using-gateway#gateway-capabilities)).
### Presence Object
###### Presence Structure
| Field | Type | Description |
| -------------------------- | -------------------------------------------------- | -------------------------------------------------------------------------------------------------- |
| user | partial [user](/resources/user#user-object) object | The user whose presence is being updated |
| guild_id? | snowflake | The ID of the guild the presence was updated in, if this is a guild presence |
| status | string | The [status](#status-type) of the user |
| activities | array[[activity](#activity-object) object] | The current activities the user is partaking in |
| hidden_activities? ^1^ ^2^ | array[[activity](#activity-object) object] | Activities that are hidden from the public |
| client_status | [client status](#client-status-object) object | The platform-dependent status of the user |
| has_played_game? ^3^ | boolean | Whether the user has authorized the same application the current user's session is associated with |
^1^ Activities are hidden when a user is invisible or has their [`show_current_game` privacy setting](/resources/user-settings-proto#status-settings-structure) disabled. Some exceptions apply, such as the Spotify activity, which is always shown.
^2^ To subscribe to hidden activities for a user, see the [Update Activity Subscriptions](#update-activity-subscriptions) endpoint.
^3^ Only available in [OAuth2 contexts](/gateway/using-gateway#oauth2-and-the-gateway).
### Session Object
Represents a specific Gateway session's presence information for the current user.
In cases of ambiguity, e.g. when the user has multiple sessions with an active presence, a special session with a `session_id` value of `all`
will exist to represent the user's overall presence. This will be the presence that is broadcasted to other users.
The overall presence will always have unknown values for `client_info`.
The number of active sessions returned over the Gateway is limited to 15 (not including the `all` session).
If a user has more than 15 active sessions, the connecting client may not have its own session information available.
###### Session Structure
| Field | Type | Description |
| --------------------- | -------------------------------------------- | ----------------------------------------------------- |
| session_id ^1^ | string | The ID of the session |
| client_info | [client info](#client-info-structure) object | Information about the client that spawned the session |
| status | string | The [status](#status-type) of the session |
| activities | array[[activity](#activity-object) object] | The current activities the session is partaking in |
| hidden_activities ^2^ | array[[activity](#activity-object) object] | Activities that are hidden from the public |
| active? | boolean | Unknown |
^1^ [Headless sessions](#create-headless-session) will have a session ID beginning with `h:`.
^2^ Activities are hidden when a user is invisible or has their [`show_current_game` privacy setting](/resources/user-settings-proto#status-settings-structure) disabled. Some exceptions apply, such as the Spotify activity, which is always shown.
###### Client Info Structure
| Field | Type | Description |
| ------- | ------- | ------------------------------------------------------------ |
| client | string | The [type of client](#client-type) |
| os | string | The [operating system](#operating-system-type) of the client |
| version | integer | The version of the client type (e.g. `5` for the PS5) |
###### Client Type
| Value | Description |
| ------- | ----------------- |
| desktop | Desktop client |
| web | Web-based client |
| mobile | Mobile client |
| vr | VR headset client |
| unknown | Unknown |
###### Operating System Type
| Value | Description |
| ----------- | ----------- |
| windows | Windows |
| osx | macOS |
| linux | Linux |
| android | Android |
| ios | iOS |
| playstation | PlayStation |
| xbox | Xbox |
| unknown | Unknown |
### Client Status Object
Active sessions are indicated with a status per platform. If a user is offline or invisible, the corresponding field is not present.
| Field | Type | Description |
| --------- | ------ | ------------------------------------------------------------------------------------------------ |
| desktop? | string | The user's [status](#status-type) on an active desktop (Windows, Linux, Mac) application session |
| mobile? | string | The user's [status](#status-type) on an active mobile (iOS, Android) application session |
| web? ^1^ | string | The user's [status](#status-type) on an active web (browser) application session |
| embedded? | string | The user's [status](#status-type) on an active embedded (Xbox, PlayStation) session |
| vr? ^2^ | string | The user's [status](#status-type) on an active VR (Meta Quest 3) session |
^1^ Used as the default when the platform is not known.
^2^ Only available through [headless sessions](#create-headless-session)
###### Status Type
| Value | Description |
| ------------- | ---------------- |
| online | Online |
| idle | Idle |
| dnd | Do Not Disturb |
| invisible ^1^ | Shown as offline |
| offline ^1^ | Offline |
| unknown ^2^ | Unknown |
^1^ `invisible` can only be sent and never received. `offline` can only be received and never sent.
^2^ This value can only be sent, and is used when the user's initial presence is unknown and should be assigned by the Gateway.
### Activity Object
###### Activity Structure
| Field | Type | Description |
| ---------------------- | ------------------------------------------------------------ | --------------------------------------------------------------------------------------------- |
| id ^5^ | string | The ID of the activity; only unique across a single user's activities |
| name ^1^ | string | The name of the activity (1-128 characters) |
| type | integer | The [activity type](#activity-type) |
| url? ^2^ | ?string | The stream URL (max 512 characters) |
| created_at ^5^ | integer | Unix timestamp (in milliseconds) of when the activity was added to the user's session |
| session_id? ^5^ | ?string | The ID of the session associated with the activity |
| platform? ^3^ | string | The [platform](#activity-platform-type) the activity is being played on |
| supported_platforms? | array[string] | The [platforms](#activity-platform-type) the activity is supported on (max 10) |
| timestamps? | [activity timestamps](#activity-timestamps-structure) object | Unix timestamps (in milliseconds) for start and/or end of the game |
| application_id? | snowflake | The ID of the application representing the game the user is playing |
| parent_application_id? | snowflake | The ID of the parent application representing the game the user is playing |
| status_display_type? | ?integer | [Which field is displayed](#status-display-type) in the user's status text in the member list |
| details? ^6^ | ?string | What the user is currently doing (max 128 characters) |
| details_url? | ?string | URL that is opened when clicking on the details text (max 256 characters) |
| state? ^7^ | ?string | The user's current party status, or text used for a custom status (max 128 characters) |
| state_url? | ?string | URL that is opened when clicking on the state text (max 256 characters) |
| sync_id? | string | The ID of the synced activity (e.g. Spotify song ID) |
| flags? | integer | The [activity's flags](#activity-flags) |
| buttons? | array[string] | Custom buttons shown in rich presence (max 2) |
| emoji? | ?[activity emoji](#activity-emoji-structure) object | The emoji used for a custom or hang status |
| party? | [activity party](#activity-party-structure) object | Information for the current party of the user |
| assets? | [activity assets](#activity-assets-structure) object | Images for the presence and their hover texts |
| secrets? ^4^ | [activity secrets](#activity-secrets-structure) object | Secrets for rich presence joining and spectating |
| metadata? ^4^ | [activity metadata](#activity-metadata-object) object | Additional metadata for the activity |
^1^ The `name` of a `CUSTOM` activity should always be "Custom Status". The `name` of a `HANG` activity should always be "Hang Status".
^2^ URLs must start with `http://` or `https://`.
^3^ This field is not commonly used for traditional presences (i.e. presences sent by regular clients over the Gateway) and is instead used to differentiate between various headless and embedded activities.
^4^ These fields are send-only. For retrieving rich presence metadata, see [Get Activity Metadata](#get-activity-metadata). For retrieving secrets, see [Get Activity Secret](#get-activity-secret).
^5^ These fields are received only and cannot be set.
^6^ When provided in a `CUSTOM` activity, it represents a [Custom Status Label](#custom-status-label-type) enumeration.
^7^ In the case of the `HANG` type, this field should be one of the [hang status types](#activity-hang-status-type). If set to `custom`, the `details` field should be used to specify the custom text, and the `emoji` field should be used to specify the custom emoji.
Bots are only able to send `name`, `type`, `state`, and optionally `url`.
###### Activity Type
Formatting can be further controlled by `status_display_type`. The formats listed here are the default values when `status_display_type` is not provided.
| Value | Name | Format | Example |
| ----- | --------- | -------------------------------------- | ------------------------------------ |
| 0 | PLAYING | Playing \{name\} | "Playing Rocket League" |
| 1 | STREAMING | Streaming \{details\} | "Streaming Rocket League" |
| 2 | LISTENING | Listening to \{name\} | "Listening to Spotify" |
| 3 | WATCHING | Watching \{name\} | "Watching YouTube Together" |
| 4 | CUSTOM | \{emoji\} \{state\} | "😃 I am cool" |
| 5 | COMPETING | Competing in \{name\} | "Competing in Arena World Champions" |
| 6 | HANG ^1^ | \{state\} or \{emoji\} \{details\} ^2^ | "Chilling" |
^1^ This type is only displayed if the user has an active voice state.
^2^ See [activity hang status type](#activity-hang-status-type) for more information.
###### Activity Platform Type
| Value | Description |
| ---------- | ------------------------- |
| desktop | Desktop (headless) |
| xbox | Xbox integration |
| samsung | Samsung integration |
| ios | iOS |
| android | Android |
| embedded | Embedded session |
| ps4 | PlayStation 4 integration |
| ps5 | PlayStation 5 integration |
| meta_quest | Meta Quest |
###### Activity Hang Status Type
When a `HANG` activity's `state` is set to any value other than `custom`, a built-in corresponding emoji will be used instead of the custom `emoji` field.
These values may be concatenated with a colon followed by an icon variant type. The valid variants are: `illocons`, `twemoji`, and `twemojimild`.
For example, `chilling:illocons` is a valid `state` value. The default variant is `twemoji`.
| Value | Example |
| -------- | -------------- |
| chilling | chilling |
| gaming | gaming |
| focusing | studying |
| brb | brb |
| watching | watching stuff |
| custom | \{details\} |
###### Activity Flags
| Value | Name | Description |
| ------------ | ----------------------------- | ----------------------------------------------------------------- |
| 1 \<\< 0 | INSTANCE | Activity is an instanced game session (a match that will end) |
| 1 \<\< 1 | JOIN | Activity can be joined by other users |
| 1 \<\< 2 | SPECTATE **(deprecated)** ^1^ | Activity can be spectated by other users |
| ~~1 \<\< 3~~ | ~~JOIN_REQUEST~~ ^2^ | ~~Activity requires a request to join~~ |
| 1 \<\< 4 | SYNC | Activity can be synced |
| 1 \<\< 5 | PLAY | Activity can be played |
| 1 \<\< 6 | PARTY_PRIVACY_FRIENDS | Activity's party can be joined by friends |
| 1 \<\< 7 | PARTY_PRIVACY_VOICE_CHANNEL | Activity's party can be joined by users in the same voice channel |
| 1 \<\< 8 | EMBEDDED | Activity is embedded within the Discord client |
| 1 \<\< 9 | CONTEXTLESS | Embedded activity is launched without a context |
^1^ Spectating has been removed from official clients and is no longer supported.
^2^ Activities no longer need to be explicitly flagged as join requestable.
###### Activity Action Type
| Value | Name | Description |
| ----- | --------------------------------- | ---------------------------------------------------- |
| 1 | JOIN ^1^ | Allows others to join a game with the user |
| 2 | SPECTATE **(deprecated)** ^1^ ^2^ | Allows others to spectate a game the user is playing |
| 3 | LISTEN | Allows others to listen to a song with the user |
| ~~4~~ | ~~WATCH~~ | ~~Allows others to join a stream with the user~~ |
| 5 | JOIN_REQUEST ^3^ | Asks others to invite the user to a game |
^1^ These [rich presence invites](/resources/message#message-activity-object) can be used with the [Get Activity Secret](#get-activity-secret) endpoint to join/spectate the activity.
^2^ Spectating has been removed from official clients and is no longer supported.
^3^ This action type is special in that instead of inviting others to a party, it asks existing party members to invite the user to join their party. Inviting users is done by [sending a message back](/resources/message#create-message) with a [rich presence invite](/resources/message#message-activity-object).
###### Activity Timestamps Structure
| Field | Type | Description |
| ------ | ------ | ------------------------------------------------------- |
| start? | string | Unix time (in milliseconds) of when the activity starts |
| end? | string | Unix time (in milliseconds) of when the activity ends |
###### Activity Emoji Structure
| Field | Type | Description |
| --------- | --------- | ------------------------------ |
| name | string | The name of the emoji |
| id? | snowflake | The ID of the emoji |
| animated? | boolean | Whether this emoji is animated |
###### Activity Party Structure
| Field | Type | Description |
| ----- | ----------------------- | ------------------------------------------------------------- |
| id? | string | The ID of the party (max 128 characters) |
| size? | array[integer, integer] | The party's current and maximum size (current_size, max_size) |
###### Activity Assets Structure
| Field | Type | Description |
| ------------------- | ------ | ----------------------------------------------------------------------------------------- |
| large_image? | string | The large [activity asset image](#activity-asset-image) (max 313 characters) |
| large_text? | string | Text displayed when hovering over the large image of the activity (max 128 characters) |
| large_url? | string | URL that is opened when clicking on the large image (max 256 characters) |
| small_image? | string | The small [activity asset image](#activity-asset-image) (max 313 characters) |
| small_text? | string | Text displayed when hovering over the small image of the activity (max 128 characters) |
| small_url? | string | URL that is opened when clicking on the small image (max 256 characters) |
| invite_cover_image? | string | The [activity asset image](#activity-asset-image) to use for invites (max 313 characters) |
###### Activity Asset Image
Activity asset images are arbitrary strings which usually contain snowflake IDs, URLs, or prefixed image IDs. Treat data within this field carefully, as it is user-specifiable and not sanitized.
Activities sent through the Social Layer SDK, [headless sessions](#create-headless-session), or RPC automatically handle proxying URLs. Otherwise, use the result of the [Proxy Application Assets](/resources/application#proxy-application-assets) endpoint prefixed with `mp:`.
| Type | Format | Image URL |
| ----------------- | ------------------------ | ------------------------------------------------------------------------------------- |
| Application Asset | `{application_asset_id}` | See [application asset image formatting](/reference#cdn-formatting) |
| Media Proxy | `mp:{image_id}` | `https://media.discordapp.net/{image_id}` |
| Twitch | `twitch:{username}` | `https://static-cdn.jtvnw.net/previews-ttv/live_user_{username}-{width}x{height}.jpg` |
| YouTube | `youtube:{video_id}` | `https://i.ytimg.com/vi/{video_id}/{thumbnail_type}.jpg` |
| Spotify | `spotify:{spotify_id}` | `https://i.scdn.co/image/{spotify_id}` |
###### Activity Secrets Structure
| Field | Type | Description |
| ------------------------------ | ---------- | ------------------------------------------------------------------ |
| join? | string | The secret for joining a party (max 128 characters) |
| spectate? **(deprecated)** ^1^ | string | The secret for spectating a game (max 128 characters) |
| ~~match?~~ | ~~string~~ | ~~The secret for a specific instanced match (max 128 characters)~~ |
^1^ Spectating has been removed from official clients and is no longer supported.
###### Operating System Type
| Value | Description |
| ------ | ----------- |
| win32 | Windows |
| darwin | macOS |
| linux | Linux |
###### Custom Status Label Type
| Value | Icon | Label |
| ---------- | -------------- | ------------------------------------- |
| ~~listen~~ | ~~Music note~~ | ~~On repeat~~ |
| ~~watch~~ | ~~TV~~ | ~~Watching lateley~~ |
| ~~play~~ | ~~Controller~~ | ~~Playing lately~~ |
| question | Calendar | Question of the day |
| think | Lightbulb | Shower thought |
| love | Heart | Current obsession (was Loving lately) |
| excited | Shooting stars | Can't wait for |
| recommend | Guide | Recommendation needed |
###### Status Display Type
| Value | Name | Description | Example |
| ----- | ------- | --------------------------- | -------------------------------------- |
| 0 | NAME | Display the `name` field | "Listening to Spotify" |
| 1 | STATE | Display the `state` field | "Listening to Rick Astley" |
| 2 | DETAILS | Display the `details` field | "Listening to Never Gonna Give You Up" |
###### Example Activity
```json
{
"id": "d11307d8c0abb136",
"created_at": "1695164784863",
"details": "24H RL Stream for Charity",
"state": "Rocket League",
"name": "Twitch",
"type": 1,
"url": "https://www.twitch.tv/discord",
"assets": {
"large_image": "twitch:discord"
}
}
```
###### Example Activity with Rich Presence
```json
{
"id": "d11307d8c0abb135",
"name": "Rocket League",
"type": 0,
"created_at": "1695164784863",
"session_id": "30f32c5d54ae86130fc4a215c7474263",
"application_id": "379286085710381999",
"state": "In a Match",
"details": "Ranked Duos: 2-1",
"platform": "xbox",
"flags": 0,
"timestamps": {
"start": "1695164482423"
},
"party": {
"id": "9dd6594e-81b3-49f6-a6b5-a679e6a060d3",
"size": [2, 2]
},
"assets": {
"large_image": "351371005538729000",
"large_text": "DFH Stadium",
"small_image": "351371005538729111",
"small_text": "Silver III"
},
"secrets": {
"join": "025ed05c71f639de8bfaa0d679d7c94b2fdce12f"
}
}
```
### Activity Metadata Object
Activity metadata can consist of arbitrary data, and is not sanitized by the API. Treat data within this object carefully.
The below structure is only a _convention_ that is used by official clients. It is not enforced by the API.
###### Activity Metadata Structure
| Field | Type | Description |
| ------------ | ------------- | --------------------------------------------------------------------------- |
| button_urls? | array[string] | The URLs corresponding to the custom buttons shown in rich presence (max 2) |
| artist_ids? | array[string] | The Spotify IDs of the artists of the song being played |
| album_id? | string | The Spotify ID of the album of the song being played |
| context_uri? | string | The Spotify URI of the current player context |
| type? | string | The type of Spotify track being played (`track` or `episode`) |
## Endpoints
List Presences
Returns the overall user presence for the user's non-offline [friends and implicit relationships](/resources/relationships#relationship-object). Only users that have an activity or are in one of the returned `guilds` will be included.
###### Response Body
| Field | Type | Description |
| ------------ | ------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------- |
| guilds | array[[voice guild](#voice-guild-structure) object] | The guilds that the user's non-offline friends and implicit relationships have active voice sessions in |
| presences | array[[presence](#presence-object) object] | The overall user presences of the user's non-offline friends and implicit relationships |
| applications | array[partial [application](/resources/application#application-object) object] | The found game applications in the presences |
###### Voice Guild Structure
| Field | Type | Description |
| -------------- | ------------------------------------------------------- | -------------------------------------------------- |
| guild_id | snowflake | The ID of the guild |
| guild_name | string | The name of the guild |
| guild_icon | ?string | The guild's [icon hash](/reference#cdn-formatting) |
| voice_channels | array[[voice channel](#voice-channel-structure) object] | The voice channels that have active sessions |
###### Voice Channel Structure
| Field | Type | Description |
| ------------ | ----------------------------------------------------- | ----------------------------------------- |
| channel_id | snowflake | The ID of the voice channel |
| channel_name | string | The name of the voice channel |
| users | array[snowflake] | The IDs of the users in the voice channel |
| streams? ^1^ | array[[voice stream](#voice-stream-structure) object] | The streams of the users in the channel |
^1^ Only included when fetched from the [List Presences for Xbox](#list-presences-for-xbox) endpoint.
###### Voice Stream Structure
| Field | Type | Description |
| ------- | --------- | ------------------------------------ |
| user_id | snowflake | The ID of the user that is streaming |
###### Example Voice Guild
```json
{
"guild_id": "839502008108580904",
"guild_icon": "4da69b53981d1adfa13590a3f2d856ee",
"guild_name": "Testing Server",
"voice_channels": [
{
"channel_id": "850360749460553769",
"channel_name": "Voice",
"users": ["150745989836308480"],
"streams": [
{
"user_id": "150745989836308480"
}
]
}
]
}
```
List Presences for Xbox
Returns the overall user presence for the user's non-offline [friends and implicit relationships](/resources/relationships#relationship-object), as well as their Xbox connection information.
Only users that have an activity or are in one of the returned `guilds` will be included.
This endpoint is meant to be used by the Xbox integration only. Because of this, it is only usable with an OAuth2 access token with the `activities.read` scope, and is locked to the Xbox application ID (`622174530214821906`).
###### Response Body
| Field | Type | Description |
| --------------------- | ------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------- |
| guilds | array[[voice guild](#voice-guild-structure) object] | The guilds that the user's non-offline friends and implicit relationships have active voice sessions in |
| presences | array[[presence](#presence-object) object] | The overall user presences of the user's non-offline friends and implicit relationships |
| applications | array[partial [application](/resources/application#application-object) object] | The found game applications in the presences |
| connected_account_ids | array[[connected account](#connected-account-structure) object] | The connected Xbox accounts for each user |
###### Connected Account Structure
| Field | Type | Description |
| ------------ | ------------- | --------------------------------------------------- |
| user_id | snowflake | The ID of the user |
| provider_ids | array[string] | The IDs of the connected Xbox accounts for the user |
Update Presence
Updates the current user's mobile game activity. Returns a 204 empty response on success. Fires a [Sessions Replace](/gateway/gateway-events#sessions-replace) Gateway event.
This endpoint is meant to be used by the Samsung Game launcher only. Because of this, all activities created through it will appear as an Android mobile session, and the [activity platform](#activity-object) will always be `samsung`.
For OAuth2 requests, this endpoint is locked to Samsung Game launcher application IDs (`567994086452363286`, `591317049637339146`).
If the application for the game you are trying to play is not yet cached, the endpoint will return a 202 accepted response. The response body will look similar to an error response:
```json
{ "message": "Application not yet available. Try again later", "code": 110001, "retry_after": 4000 }
```
You should retry the request after the timeframe specified in the `retry_after` field. Note that the timeframe is given in milliseconds. If the `retry_after` field is `0`, you should retry the request after a short delay.
See [the unavailable resources section](/topics/rate-limits#unavailable-resources) for more information.
###### JSON Params
| Field | Type | Description |
| ------------ | ------ | ---------------------------------------------------------------- |
| package_name | string | The package name of the game (e.g. `com.supercell.clashofclans`) |
| update? | string | The [type of update](#presence-update-type) (default `UPDATE`) |
###### Presence Update Type
| Value | Description |
| ------ | ------------------------------- |
| START | Start a new game session |
| UPDATE | Update the current game session |
| STOP | Stop the current game session |
List Global Activity Statistics
Returns a list of [global activity statistics](#global-activity-statistics-structure) objects representing games the user's friends and affine users have recently played.
###### Query String Params
| Field | Type | Description |
| ------------------ | ------- | ---------------------------------------------------------------------------------------------- |
| with_users? | boolean | Whether to include user information in the returned activity statistics (default false) |
| with_applications? | boolean | Whether to include application information in the returned activity statistics (default false) |
###### Global Activity Statistics Structure
| Field | Type | Description |
| ---------------- | ----------------------------------------------------------------------- | -------------------------------------------------- |
| user_id | string | The ID of the user playing the game |
| user? ^1^ | partial [user](/resources/user#user-object) object | The user playing the game |
| application_id | string | The ID of the application representing the game |
| application? ^2^ | partial [application](/resources/application#application-object) object | The application representing the game |
| updated_at | ISO8601 timestamp | When the user last played the game |
| duration | integer | How long the user played the game for (in seconds) |
^1^ Only included when `with_users` is set to `true`.
^2^ Only included when `with_applications` is set to `true`.
###### Example Global Activity Statistics
```json
{
"user_id": "1001086404203389018",
"application_id": "1334568856227942480",
"updated_at": "2025-03-01T14:58:02.284000+00:00",
"duration": 1176
}
```
List Application Activity Statistics
Returns a list of [application activity statistics](#application-activity-statistics-structure) objects representing the user's friends and affine users that have played the given game.
###### Application Activity Statistics Structure
| Field | Type | Description |
| -------------- | ----------------- | ----------------------------------------------------------- |
| user_id | string | The ID of the user playing the game |
| last_played_at | ISO8601 timestamp | When the user last played the game |
| total_duration | integer | How long the user has ever played the game for (in seconds) |
###### Example Application Activity Statistics
```json
{
"user_id": "343383572805058560",
"last_played_at": "2025-02-20T00:21:07.457000+00:00",
"total_duration": 1180625
}
```
List User Application Activity Statistics
Returns a list of [user application activity statistics](#user-application-activity-statistics-structure) objects representing games the user has played.
###### User Application Activity Statistics Structure
| Field | Type | Description |
| -------------------------- | ------------------ | ----------------------------------------------------------------------- |
| application_id | string | The ID of the application representing the game |
| last_played_at | ISO8601 timestamp | When the user last played the game |
| first_played_at | ?ISO8601 timestamp | When the user first played the game (may not be tracked) |
| total_duration | integer | How long the user has ever played the game for (in seconds) |
| total_discord_sku_duration | integer | How long the user has ever played the game through Discord (in seconds) |
###### Example User Application Activity Statistics
```json
{
"application_id": "356875221078245376",
"last_played_at": "2025-02-20T06:24:34.792000+00:00",
"first_played_at": "2024-04-29T22:23:30.307000+00:00",
"total_duration": 246531,
"total_discord_sku_duration": 0
}
```
Update Activity Session
Updates a currently running activity game session for the current user.
###### JSON Params
| Field | Type | Description |
| ----------------- | --------- | ---------------------------------------------------------------------------------- |
| token? | string | The token of the existing session to update |
| application_id | snowflake | The ID of the application representing the game |
| duration? | integer | How long the game has been played for (in seconds) sine the last update (max 1800) |
| share_activity? | boolean | Whether to share the activity in activity statistics (default true) |
| distributor? | string | The [distributor](/resources/game#distributor-type) of the game |
| exe_path? | string | The path to the game's executable file (max 128 characters) |
| voice_channel_id? | snowflake | The ID of the voice channel the user is in while playing the game |
| session_id? | string | The ID of the session associated with the activity |
| media_session_id? | string | The ID of the voice connection media session associated with the activity |
| closed? | boolean | Whether the game has been closed and the session is over (default false) |
###### Response Body
| Field | Type | Description |
| ----- | ------ | -------------------------------- |
| token | string | The updated token of the session |
###### Example Response
```json
{
"token": ".eJxNzEEKwyAUBNCrBLdtyqjx6_cc3YvELKShCYmuSu_eWArNcoY38xJ1n7aQk_CdcEY5VootkWQQsxbXTsR1nfMYS16ePyclazkQEzslodXA3GBdUyxTCrE0pKBMD92D7rAezht7I2tAdAE80Bapbt_fw-OIZSlxDqdS2uFf531cthT2Rz0TvD_X3TcU.Z8lKCQ.QvSLefzqmY6lhaBaQNG308fl3e8"
}
```
Create Headless Session
Creates a new headless session for the current user. Fires a [Sessions Replace](/gateway/gateway-events#sessions-replace) Gateway event.
This endpoint is only usable with an OAuth2 access token with the `activities.write` scope.
Headless sessions only last for 20 minutes before they are automatically deleted.
###### JSON Params
| Field | Type | Description |
| -------------- | ------------------------------------------ | ------------------------------------------------------------------------ |
| activities ^1^ | array[[activity](#activity-object) object] | An array containing exactly one activity to set for the headless session |
| token? | string | The token of the headless session to update |
^1^ In addition to `type` and `name`, this activity object must also have a valid `application_id` and `platform` set.
###### Response Body
| Field | Type | Description |
| ---------- | ------------------------------------------ | ----------------------------------------------------------- |
| activities | array[[activity](#activity-object) object] | The current activities the headless session is partaking in |
| token | string | The token of the headless session |
Delete Headless Session
Deletes a headless session for the current user. Returns a 204 empty response on success. Fires a [Sessions Replace](/gateway/gateway-events#sessions-replace) Gateway event.
This endpoint is only usable with an OAuth2 access token with the `activities.write` scope.
###### JSON Params
| Field | Type | Description |
| ----- | ------ | --------------------------------- |
| token | string | The token of the headless session |
Get Activity Metadata
Returns the [activity metadata](#activity-metadata-object) for a given activity, or a 204 empty response if no metadata is found.
A special `application_id` of `0` can be used to retrieve the metadata for [`LISTENING` type activities](#activity-type) that are not associated with a specific application, such as Spotify.
If multiple [`LISTENING` type activities](#activity-type) exist, the metadata of the last one in the `activities` array will be returned.
Get Activity Secret
Returns an activity secret that can be used to join or spectate the game. Only supports the `JOIN` and `SPECTATE` [action types](#activity-action-type).
This endpoint requires the `JOIN` or `SPECTATE` [activity flag](#activity-flags) to be set.
If a rich presence invite is not specified in the query string, the activity must have the `PARTY_PRIVACY_FRIENDS` or `PARTY_PRIVACY_VOICE_CHANNEL`
[activity flag](#activity-flags) set, and the user must meet the flag requirements.
The `SPECTATE` actity action type is deprecated and will be removed in the future.
###### Query String Params
| Field | Type | Description |
| ----------- | --------- | --------------------------------------------------------------- |
| channel_id? | snowflake | The ID of the channel the rich presence invite has been sent in |
| message_id? | snowflake | The ID of the rich presence invite message |
###### Response Body
| Field | Type | Description |
| ------ | ------ | ------------------- |
| secret | string | The activity secret |
###### Example Response
```json
{ "secret": "025ed05c71f639de8bfaa0d679d7c94b2fdce12f" }
```
Update Activity Subscriptions
Updates the current user's subscribed hidden activities. Returns a 204 empty response on success. Fires multiple [Presence Update](/gateway/gateway-events#presence-update) Gateway events.
##### JSON Params
| Field | Type | Description |
| ------------- | ----------------------------------------------------------------------- | ------------------------------------------------------- |
| subscriptions | array[[activity subscription](#activity-subscription-structure) object] | The hidden activities the user is subscribed to (1-100) |
###### Activity Subscription Structure
| Field | Type | Description |
| -------------- | --------- | ---------------------------------------------------------- |
| user_id | snowflake | The ID of the user to subscribe to |
| application_id | snowflake | The ID of the application representing the game |
| party_id | snowflake | The ID of the party the user is in |
| message_id | snowflake | The ID of the message containing the rich presence invite |
| channel_id | snowflake | The ID of the channel the rich presence invite was sent in |
---
# Using Gateway
Link: https://docs.discord.food/gateway/using-gateway
The Gateway API allows clients to open secure WebSocket connections with Discord to receive events about actions that take place in resources they have access to, like when a channel is updated or a role is created. There are a few cases where clients will _also_ use Gateway connections to update or request resources, like when updating voice state.
In _most_ cases, performing REST operations on Discord resources is done using the [HTTP API](/reference#http-api) rather than the Gateway API.
The Gateway is Discord's form of real-time communication used by clients. The API for interacting with Gateways is complex and fairly unforgiving, so be sure to read the following documentation in its entirety so you understand the sacred secrets of the Gateway.
The documentation herein is only for the latest version of the API, unless otherwise specified.
## Gateway Events
Gateway events are [payloads](/gateway/gateway-events#gateway-payload-structure) sent over a [Gateway connection](#connections)—either from a client to Discord, or from Discord to a client. A client typically [_sends_ events](#sending-events) when connecting and managing its connection to the Gateway, and [_receives_ events](#receiving-events) when listening to actions taking place in a resource.
All Gateway events are encapsulated in a [Gateway event payload](/gateway/gateway-events#gateway-payload-structure).
A full list of Gateway events and their details are in the [Gateway events documentation](/gateway/gateway-events).
Details about Gateway event payloads are in the [Gateway events documentation](/gateway/gateway-events#gateway-payload-structure).
### Sending Events
When sending a Gateway event (like when [performing an initial handshake](/gateway/gateway-events#identify) or [updating presence](/gateway/gateway-events#update-presence)), your client must send an [event payload object](/gateway/gateway-events#gateway-payload-structure) with a valid Opcode (`op`) and inner data object (`d`).
Specific rate limits are applied when sending events, which you can read about in the [Rate Limiting](#rate-limiting) section.
Event payloads sent over a Gateway connection:
1. Must be serialized in [plain-text JSON or binary ETF](#encoding-and-compression).
2. Must not exceed 15 KiB. If an event payload _does_ exceed this limit, the connection will be closed with a [`4002` close code](/gateway/opcodes-and-close-codes#gateway-close-event-codes).
All events that you can send over the Gateway are in the [Gateway events documentation](/gateway/gateway-events#send-events).
### Receiving Events
Receiving a Gateway event from Discord (like when [a reaction is added to a message](/gateway/gateway-events#message-reaction-add)) is much more common (and slightly more complex) than sending them.
While some events are sent to your client regardless of intents, the receiving of most events is configurable by specifying intents when [identifying](#identifying). Intents are bitwise values that can be ORed (`|`) to indicate which events (or groups of events) you want Discord to send your client. Intents are most commonly used (and required for) bots, as user accounts usually want to receive all event groups, and avoid unnecessary events using other functionality. A list of intents and their corresponding events are listed in the [intents section](#gateway-intents).
When receiving events, you can also configure _how_ events will be sent to your client, like the [encoding and compression](#encoding-and-compression), or whether [sharding should be enabled](#sharding).
All events that you can receive over the Gateway are in the [Gateway events documentation](/gateway/gateway-events#receive-events).
#### Dispatch Events
[Opcode 0 Dispatch](/gateway/gateway-events#gateway-payload-structure) events are the most common type of event you will receive. Gateway events which represent actions taking place in a guild will be sent to your client as Dispatch events.
When your client is parsing a Dispatch event:
- The `t` field can be used to determine which [Gateway event](/gateway/gateway-events#receive-events) the payload represents and the data you can expect in the `d` field.
- The `s` field represents the sequence number of the event, which is the relative order in which it occurred. You need to cache the most recent non-null `s` value for heartbeats, and to pass when [Resuming](#resuming) a connection.
## Connections
Gateway connections are persistent WebSockets which introduce more complexity than sending HTTP requests. When interacting with the Gateway, your client must know how to open the initial connection, as well as maintain it and handle any disconnects.
### Connection Lifecycle
There are nuances that aren't included in the overview below. More details about each step and event can be found in the individual sections below.
At a high-level, Gateway connections consist of the following cycle:

1. Client establishes a connection with the Gateway after fetching and caching a WebSocket URL using the [Get Gateway](/gateway/using-gateway#get-gateway) or [Get Gateway Bot](/gateway/using-gateway#get-gateway-bot) endpoint.
2. Discord sends the client an [Opcode 10 Hello](#hello-event) event containing a heartbeat interval in milliseconds. **Read the section on [connecting](#connecting).**
3. Client starts the heartbeat task: it sends an [Opcode 1 Heartbeat](#sending-heartbeats) event, then continue to send them every heartbeat interval until the connection is closed.
- Discord will respond to each Heartbeat event with an [Opcode 11 Heartbeat ACK](#sending-heartbeats) event to confirm it was received. If the client doesn't receive a Heartbeat ACK before the next heartbeat interval, it should close the connection and reconnect.
- Discord may send the client an [Opcode 1 Heartbeat](#sending-heartbeats) event, in which case it should respond with an [Opcode 1 Heartbeat](#sending-heartbeats) event immediately.
4. Client sends an [Opcode 2 Identify](#identifying) event to perform the initial handshake with the Gateway. The client does not have to wait for the [Opcode 10 Hello](#hello-event) event before identifying.
5. Discord sends the client a [Ready](#ready-event) event which indicates the handshake was successful and the connection is established. The Ready event contains a `resume_gateway_url` that the client should keep track of to determine the WebSocket URL it should use to resume. **Read the section on [the Ready event](#ready-event).**
6. The connection may be dropped for a variety of reasons. Whether the client can [resume](#resuming) the connection or whether it must re-identify is determined by a variety of factors like the [OPcode](/gateway/opcodes-and-close-codes#gateway-opcodes) and [close code](/gateway/opcodes-and-close-codes#gateway-close-event-codes) that it receives. **Read the section on [disconnecting](#disconnecting).**
7. If the client **can** resume/reconnect, it should open a new connection using `resume_gateway_url`, then send an [Opcode 6 Resume](#resuming) event. If it **cannot** resume/reconnect, it should open a new connection using the cached URL from step #1, then repeat the whole Gateway cycle. _Yipee!_
### Connecting
Before you can establish a connection to the Gateway, you should call the [Get Gateway](#get-gateway) or the [Get Gateway Bot](#get-gateway-bot) endpoint. Either endpoint will return a payload with a `url` field whose value is the URL you can use to open a WebSocket connection. In addition to the URL, [Get Gateway Bot](#get-gateway-bot) contains additional information about the recommended number of shards and the session start limits for your user.
When initially calling either [Get Gateway](#get-gateway) or [Get Gateway Bot](#get-gateway-bot), you should cache the value of the `url` field and only re-request it after failing to establish a connection to the Gateway.
When connecting to the URL, it's a good idea to explicitly pass the API version and [encoding](#encoding-and-compression) as query parameters. You can also optionally include whether Discord should [compress](#encoding-and-compression) data that it sends your app. For example, `wss://gateway.discord.gg/?v=9&encoding=json&compress=zlib-stream` is a URL a client may use to connect to the Gateway.
###### Query String Params
| Field | Type | Description |
| --------- | ------- | ---------------------------------------------------------------------------------------------------------------- |
| v | integer | [API Version](/reference#api-versioning) to use |
| encoding | string | The [encoding](#encoding-and-compression) of received gateway packets (`json` or `etf`) |
| compress? | string | The optional [transport compression](#transport-compression) of gateway packets (`zlib-stream` or `zstd-stream`) |
#### Hello Event
Once connected, the client will receive an [Opcode 10 Hello](/gateway/gateway-events#hello) event, with information on the connection's heartbeat interval (`heartbeat_interval`).
The heartbeat interval indicates the how often (in milliseconds) you must send a heartbeat in order to maintain the active connection. Heartbeating is detailed in the [sending heartbeats](#sending-heartbeats) section.
### Sending Heartbeats
Heartbeats are pings used to let Discord know that your client is still actively using a Gateway connection. After connecting to the Gateway, your client should send heartbeats (as described below) in a background process until the Gateway connection is closed.
To send a heartbeat, either [Opcode 1 Heartbeat](/gateway/gateway-events#heartbeat) or [Opcode 40 QoS Heartbeat](/gateway/gateway-events#qos-heartbeat) must be used. Both are functionally the same in regards to the Gateway lifecycle, but the QoS Heartbeat also tracks [Quality of Service (QoS)](https://en.wikipedia.org/wiki/Quality_of_service) statistics. The QoS Heartbeat is recommended for all clients, but is not required.
#### Heartbeat Interval
Upon receiving [Opcode 10 Hello](#hello-event), your client should immediately send its first heartbeat event (with optional jitter). From that point until the connection is closed, your client must continually send Discord a heartbeat every `heartbeat_interval` milliseconds. If your client fails to send a heartbeat event in time, your connection will be closed and you will be forced to [resume](#resuming).
When sending a heartbeat, your client will need to include the last sequence number your client received. The sequence number is sent in every Dispatch [event payload](/gateway/gateway-events#gateway-payload-structure) (in the `s` field). If you haven't received any events yet, you should pass `null`.
Additionally, every 30 minutes and on Gateway connect, an [Opcode 41 Update Time Spent Session ID](/gateway/gateway-events#update-time-spent-session-id) event should be sent. This is recommended, but not required.
The first heartbeat may be offset by a value between 0 and `heartbeat_interval` in order to prevent too many clients from reconnecting their sessions at the exact same time (which could cause an influx of traffic).
You _can_ send heartbeats before the `heartbeat_interval` elapses, but you should avoid doing so unless necessary. There is already tolerance in the `heartbeat_interval` that will cover network latency, so you don't need to account for it in your implementation.
When you send a heartbeat, the Gateway will respond with an [Opcode 11 Heartbeat ACK](/gateway/gateway-events#heartbeat-ack), which is an acknowledgement that the heartbeat was received.
If a client does not receive a heartbeat ACK between its attempts at sending heartbeats, this may be due to a failed or "zombied" connection. The client should immediately terminate the connection with any close code besides `1000` or `1001`, then reconnect and attempt to [resume](#resuming).
In the event of a service outage where you stay connected to the Gateway, you should continue to heartbeat and receive ACKs. The Gateway will eventually respond and issue a session once it's able to.
When recovering from an outage, the Gateway may respond with an [Opcode 9 Invalid Session](/gateway/gateway-events#invalid-session) when attempting to resume or identify. This is to limit the surge of clients attempting to reconnect at the same time after the outage.
If this happens, you should maintain the Gateway connection and attempt to [identify](#identifying) again. The Gateway will eventually respond with a [Ready](/gateway/gateway-events#ready) event once it's able to process your request.
#### Heartbeat Requests
In addition to the Heartbeat interval, the Gateway may request additional heartbeats from your client by sending an [Opcode 1 Heartbeat](/gateway/gateway-events#heartbeat) event. Upon receiving the event, your client should immediately heartbeat without waiting the remainder of the current interval.
Just like normal, the Gateway will respond with an [Opcode 11 Heartbeat ACK](/gateway/gateway-events#heartbeat-ack) event.
### Identifying
After the connection is open and you are heartbeating, your client should send an [Opcode 2 Identify](/gateway/gateway-events#identify). This event is the initial handshake with the Gateway that's required before your client can begin sending or receiving most Gateway events.
Users are limited by maximum concurrency (in the [session start limit object](#session-start-limit-object)) when identifying. If your client exceeds this limit, the Gateway will respond with an [Opcode 9 Invalid Session](/gateway/gateway-events#invalid-session) event.
After your client sends a valid identify payload, the Gateway will respond with a [Ready](#ready-event) event which indicates a successfully-connected state with the Gateway. The Ready event is sent as a standard [Opcode 0 Dispatch](/gateway/gateway-events#gateway-payload-structure).
Bots are limited to 1000 identify calls to the WebSocket in a 24-hour period. This limit is global and across all shards, but does not include [resume](#resuming) calls.
Upon hitting this limit, all active sessions for the bot will be terminated, the bot's token will be reset, and you will receive an email notification. It's up to you to update your bot with the new token. User accounts are not affected by this limit.
#### Ready Event
As mentioned above, the [Ready](/gateway/gateway-events#ready) event is sent to your client after a successful identification. The Ready event includes state, like the guilds you are in, that you need to start interacting with the rest of the platform.
The Ready event also includes fields that you'll need to cache in order to eventually [resume](#resuming) your connection after disconnects. Two fields in particular are important to call out:
- `resume_gateway_url` is a WebSocket URL that you should use to resume after a disconnect. The `resume_gateway_url` should be used instead of the URL [used when connecting](#connecting).
- `session_id` is the ID for the Gateway session for the connection. It's required to know which stream of events were associated with your connection.
Full details about the Ready event are in the [Gateway events documentation](/gateway/gateway-events#ready).
### Disconnecting
The Internet is a scary place. Gateway disconnects happen for a variety of reasons, whether initiated by Discord or by you.
#### Handling a Disconnect
Due to Discord's architecture, disconnects are a semi-regular event and should be expected and handled. When your client encounters a disconnect, it will typically be sent a [close code](/gateway/opcodes-and-close-codes#gateway-close-event-codes) which can be used to determine whether you can reconnect and [resume](#resuming) the session, or whether you have to start over and [re-identify](#identifying).
After you determine whether or not you can reconnect, you must do one of the following:
- If you determine that you _can_ reconnect and resume the previous session, then you should reconnect using the `resume_gateway_url` and `session_id` from the [Ready](#ready-event) event. Details about when and how to resume can be found in the [resuming](#resuming) section.
- If you _cannot_ reconnect **or the reconnect fails**, you should open a new connection using the cached URL from the initial call to [Get Gateway](#get-gateway) or [Get Gateway Bot](#get-gateway-bot). In the case of a failed reconnect, you'll have to re-identify after opening a new connection.
A full list of the close codes can be found in the [close codes](/gateway/opcodes-and-close-codes#gateway-close-event-codes) documentation.
#### Initiating a Disconnect
When you close the connection to the gateway with close code `1000` or `1001`, your session will be invalidated and your user will appear offline.
If you simply close the TCP connection or use a different close code, the session will remain active and timeout after a few minutes. This can be useful when you're [resuming](#resuming) the previous session.
### Resuming
When your client is disconnected, Discord has a process for reconnecting and resuming, which allows your client to replay any lost events starting from the last sequence number it received. After resuming, you will receive the missed events in the same way you would have had the connection had stayed active. Unlike the initial connection, your client does **not** need to re-identify when resuming.
There are a handful of scenarios when you should attempt to resume:
1. You receive an [Opcode 7 Reconnect](/gateway/gateway-events#reconnect) event
2. You're disconnected with a [close code](/gateway/opcodes-and-close-codes#gateway-close-event-codes) that indicates you can reconnect, or don't receive _any_ close code.
3. You receives an [Opcode 9 Invalid Session](/gateway/gateway-events#invalid-session) event with the `d` field set to `true`. This is an unlikely scenario, but it is possible.
#### Preparing to Resume
Before your client can send an [Opcode 6 Resume](/gateway/gateway-events#resume) event, it will need three values: the `session_id` and the `resume_gateway_url` from the [Ready](#ready-event) event, and the sequence number (`s`) from the last [Opcode 0 Dispatch](/gateway/gateway-events#gateway-payload-structure) event it received before the disconnect.
After the connection is closed, your client should open a new connection using `resume_gateway_url` rather than the URL used to initially connect. If you don't use the `resume_gateway_url` when reconnecting, you will experience disconnects at a higher rate than normal.
Once the new connection is opened, your client should send an [Opcode 6 Resume](/gateway/gateway-events#resume) event using the `session_id` and `seq` mentioned above.
When resuming, you do not need to send an identify event after opening the connection.
If successful, the Gateway will send the missed events in order, finishing with a [Resumed](/gateway/gateway-events#resumed) event to signal event replay has finished and that all subsequent events will be new.
If the client does not reconnect in time, the replay buffer will overfill and the session will be invalidated. In this case, the client will receive an [Opcode 9 Invalid Session](/gateway/gateway-events#invalid-session) and should disconnect. After disconnect, the client should create a new connection with the cached URL from the [Get Gateway](#get-gateway) or the [Get Gateway Bot](#get-gateway-bot) endpoint, then [identify](#identifying).
## OAuth2 and the Gateway
Bearer tokens with the `identify` and either the `gateway.connect` or `voice` [OAuth2 scopes](/topics/oauth2#oauth2-scopes) can be used to connect to the Gateway on behalf of a user. The token must be prefixed with `Bearer ` when [identifying](#identifying), as in HTTP requests.
The available [Gateway intents](/gateway/using-gateway#gateway-intents) and [events](/gateway/gateway-events) will differ depending on the authorized scopes.
Note that supported commands and payload structures may differ from those outlined in this documentation. Objects may be more partial than expected or may not contain required fields. As this feature is not stable, these differences are often changing and not yet documented. Proceed with caution.
## Gateway Capabilities
While capabilities are supported for bots, they are not very functional and not recommended for use.
The Discord Gateway provides a system for enabling and disabling custom feature flags on a per-connection basis. These flags, or capabilities, are passed in the `capabilities` parameter when [identifying](#identifying). Capabilities are a way for clients to opt into payload and functionality changes in a backwards-compatible way, or disable Gateway features they do not need. Capabilities are not at all related to [Gateway intents](#gateway-intents).
The effects of specific capabilities are documented in the [Gateway events](/gateway/gateway-events) section, under every event that is affected. However, the documentation generally assumes clients opt into all new feature capabilities.
### List of Capabilities
Below is a list of all capabilities and a general description of their effects. For more information, see the documentation for the specific event or feature that is affected.
| Value | Name | Description |
| --------- | ------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| 1 \<\< 0 | LAZY_USER_NOTES | Removes the `notes` field from the [Ready](/gateway/gateway-events#ready) event |
| 1 \<\< 1 | NO_AFFINE_USER_IDS | Prevents member/presence syncing and [Presence Update](/gateway/gateway-events#presence-update) events for [implicit relationships](/resources/relationships#relationship-object) |
| 1 \<\< 2 | VERSIONED_READ_STATES | Enables versioned read states, changing the `read_state` field in the [Ready](/gateway/gateway-events#ready) event to an object and allowing it to be cached when re-identifying |
| 1 \<\< 3 | VERSIONED_USER_GUILD_SETTINGS | Enables versioned user guild settings, changing the `user_guild_settings` field in the [Ready](/gateway/gateway-events#ready) event to an object and allowing it to be cached when re-identifying |
| 1 \<\< 4 | DEDUPE_USER_OBJECTS | Dehydrates the [Ready](/gateway/gateway-events#ready) payload, moving all user objects to the `users` field and replacing them in various places in the payload with `user_id` or `recipient_id`, and merging the `members` fields of all guilds into a single `merged_members` field |
| 1 \<\< 5 | PRIORITIZED_READY_PAYLOAD ^1^ | Separates the [Ready](/gateway/gateway-events#ready) payload into two parts ([Ready](/gateway/gateway-events#ready) and [Ready Supplemental](/gateway/gateway-events#ready-supplemental)) allowing the client to receive the [Ready](/gateway/gateway-events#ready) payload faster and then receive the rest of the payload later |
| 1 \<\< 6 | MULTIPLE_GUILD_EXPERIMENT_POPULATIONS | Changes the `populations` entry of [`guild_experiments`](/topics/experiments#guild-experiments) in the [Ready](/gateway/gateway-events#ready) event to be an array of populations rather than a single population |
| 1 \<\< 7 | NON_CHANNEL_READ_STATES | Includes read states tied to non-channel resources (e.g. guild scheduled events and notification center) in the `read_states` field of the [Ready](/gateway/gateway-events#ready) event |
| 1 \<\< 8 | AUTH_TOKEN_REFRESH | Enables auth token refresh, allowing the client to optionally receive a new auth token in the `auth_token` field of the [Ready](/gateway/gateway-events#ready) event |
| 1 \<\< 9 | USER_SETTINGS_PROTO | Removes the `user_settings` field from the [Ready](/gateway/gateway-events#ready) event and prevents [User Settings Update](/gateway/gateway-events#user-settings-update) events; the `user_settings_proto` field and [User Settings Proto Update](/gateway/gateway-events#user-settings-proto-update) event is used instead |
| 1 \<\< 10 | CLIENT_STATE_V2 | Enables client state caching v2 |
| 1 \<\< 11 | PASSIVE_GUILD_UPDATE | Enables passive guild updates, allowing the client to receive [Passive Update V1](/gateway/gateway-events#passive-update-v1) events instead of [Channel Unread Update](/gateway/gateway-events#channel-unread-update) and [Voice State Update](/gateway/gateway-events#voice-state-update) events for guilds it is not subscribed to |
| 1 \<\< 12 | AUTO_CALL_CONNECT | Connects the client to all pre-existing calls upon connecting to the Gateway; this means clients will receive [Call Create](/gateway/gateway-events#call-create) events for all calls created before the Gateway connection was established without needing to send a [Request Call Connect](/gateway/gateway-events#request-call-connect) first |
| 1 \<\< 13 | DEBOUNCE_MESSAGE_REACTIONS | Debounces message reaction events, preventing the client from receiving multiple [Message Reaction Add](/gateway/gateway-events#message-reaction-add) events for the same message within a short period of time; clients will receive a single [Message Reaction Add Many](/gateway/gateway-events#message-reaction-add-many) event instead |
| 1 \<\< 14 | PASSIVE_GUILD_UPDATE_V2 ^2^ | Enables passive guild updates v2, allowing the client to receive [Passive Update V2](/gateway/gateway-events#passive-update-v2) events instead of [Channel Unread Update](/gateway/gateway-events#channel-unread-update) and [Voice State Update](/gateway/gateway-events#voice-state-update) events for guilds it is not subscribed to |
| 1 \<\< 15 | CHANNEL_OBFUSCATION | Enables channel obfuscation, obfuscating any channels the user doesn't have `VIEW_CHANNEL` permission for. |
| 1 \<\< 16 | AUTO_LOBBY_CONNECT | Adds a `lobbies` field to the [Ready](/gateway/gateway-events#ready) event containing pre-existing lobbies and stops streaming [Lobby Create](/gateway/gateway-events#lobby-create) events upon connecting to the Gateway |
^1^ Requires `DEDUPE_USER_OBJECTS`. Without it, the capability will be ignored.
^2^ Supersedes `PASSIVE_GUILD_UPDATE`. If enabled, `PASSIVE_GUILD_UPDATE` will be ignored.
## Gateway Intents
For bots, intents are optionally supported on the v6 API but required as of v8. User accounts do not require intents and their usage is not recommended.
Maintaining a stateful application can be difficult when it comes to the amount of data you're expected to process over a Gateway connection, especially at scale. Gateway intents are a system to help you lower the computational burden.
Intents are bitwise values passed in the `intents` parameter when [identifying](#identifying) which correlate to a set of related events. For example, the event sent when a guild is created ([Guild Create](/gateway/gateway-events#guild-create)) and when a channel is updated ([Channel Update](/gateway/gateway-events#channel-update)) both require the same `GUILDS (1 << 0)` intent (as listed in the table below). If you do not specify an intent when identifying, you will not receive _any_ of the Gateway events associated with that intent.
For bots, two types of intents exist:
- **Standard intents** can be passed by default. You don't need any additional permissions or configurations.
- **Privileged intents** must be enabled before they can be used. More information about privileged intents can be found [in their section below](#privileged-intents).
Your Gateway connection will be closed if you pass invalid intents ([`4013` close code](/gateway/opcodes-and-close-codes#gateway-close-event-codes)), or a privileged intent that hasn't been configured or approved for your bot ([`4014` close code](/gateway/opcodes-and-close-codes#gateway-close-event-codes)). User accounts do not require approval and can use any intent, albeit with caveats of their own.
### List of Intents
Below is a list of all intents and the Gateway events associated with them. Any events _not_ listed means it's not associated with an intent and will always be sent to your client.
All events, including those that aren't associated with an intent, are in the [Gateway events](/gateway/gateway-events) documentation.
```
GUILDS (1 << 0)
- GUILD_CREATE
- GUILD_UPDATE
- GUILD_DELETE
- GUILD_ROLE_CREATE
- GUILD_ROLE_UPDATE
- GUILD_ROLE_DELETE
- CHANNEL_CREATE
- CHANNEL_UPDATE
- CHANNEL_DELETE
- VOICE_CHANNEL_START_TIME_UPDATE
- VOICE_CHANNEL_STATUS_UPDATE
- CHANNEL_PINS_UPDATE
- THREAD_CREATE
- THREAD_UPDATE
- THREAD_DELETE
- THREAD_LIST_SYNC
- THREAD_MEMBER_UPDATE
- THREAD_MEMBERS_UPDATE ¹
- STAGE_INSTANCE_CREATE
- STAGE_INSTANCE_UPDATE
- STAGE_INSTANCE_DELETE
GUILD_MEMBERS (1 << 1)
- GUILD_MEMBER_ADD
- GUILD_MEMBER_UPDATE
- GUILD_MEMBER_REMOVE
- THREAD_MEMBERS_UPDATE ¹
GUILD_MODERATION (1 << 2)
- GUILD_AUDIT_LOG_ENTRY_CREATE
- GUILD_BAN_ADD
- GUILD_BAN_REMOVE
- GUILD_JOIN_REQUEST_CREATE
- GUILD_JOIN_REQUEST_UPDATE
- GUILD_JOIN_REQUEST_DELETE
GUILD_EMOJIS_AND_STICKERS (1 << 3)
- GUILD_EMOJIS_UPDATE
- GUILD_STICKERS_UPDATE
GUILD_INTEGRATIONS (1 << 4)
- GUILD_INTEGRATIONS_UPDATE
- INTEGRATION_CREATE
- INTEGRATION_UPDATE
- INTEGRATION_DELETE
GUILD_WEBHOOKS (1 << 5)
- WEBHOOKS_UPDATE
GUILD_INVITES (1 << 6)
- INVITE_CREATE
- INVITE_DELETE
GUILD_VOICE_STATES (1 << 7)
- VOICE_STATE_UPDATE
- VOICE_CHANNEL_EFFECT_SEND
GUILD_PRESENCES (1 << 8) ²
- PRESENCE_UPDATE
GUILD_MESSAGES (1 << 9)
- MESSAGE_CREATE
- MESSAGE_UPDATE
- MESSAGE_DELETE
- MESSAGE_DELETE_BULK
GUILD_MESSAGE_REACTIONS (1 << 10)
- MESSAGE_REACTION_ADD
- MESSAGE_REACTION_ADD_MANY
- MESSAGE_REACTION_REMOVE
- MESSAGE_REACTION_REMOVE_ALL
- MESSAGE_REACTION_REMOVE_EMOJI
GUILD_MESSAGE_TYPING (1 << 11)
- TYPING_START
DIRECT_MESSAGES (1 << 12)
- MESSAGE_CREATE
- MESSAGE_UPDATE
- MESSAGE_DELETE
- CHANNEL_PINS_UPDATE
DIRECT_MESSAGE_REACTIONS (1 << 13)
- MESSAGE_REACTION_ADD
- MESSAGE_REACTION_ADD_MANY
- MESSAGE_REACTION_REMOVE
- MESSAGE_REACTION_REMOVE_ALL
- MESSAGE_REACTION_REMOVE_EMOJI
DIRECT_MESSAGE_TYPING (1 << 14)
- TYPING_START
MESSAGE_CONTENT (1 << 15) ³
GUILD_SCHEDULED_EVENTS (1 << 16)
- GUILD_SCHEDULED_EVENT_CREATE
- GUILD_SCHEDULED_EVENT_UPDATE
- GUILD_SCHEDULED_EVENT_DELETE
- GUILD_SCHEDULED_EVENT_USER_ADD
- GUILD_SCHEDULED_EVENT_USER_REMOVE
- GUILD_SCHEDULED_EVENT_EXCEPTION_CREATE
- GUILD_SCHEDULED_EVENT_EXCEPTION_UPDATE
- GUILD_SCHEDULED_EVENT_EXCEPTION_DELETE
- GUILD_SCHEDULED_EVENT_EXCEPTIONS_DELETE
GUILD_EMBEDDED_ACTIVITIES (1 << 17)
- EMBEDDED_ACTIVITY_UPDATE_V2
PRIVATE_CHANNELS (1 << 18) ⁴
- CHANNEL_CREATE
- CHANNEL_UPDATE
- CHANNEL_DELETE
- CHANNEL_RECIPIENT_ADD
- CHANNEL_RECIPIENT_REMOVE
CALLS (1 << 19) ⁴ ⁵
- AUDIO_SETTINGS_UPDATE
- CALL_CREATE
- CALL_UPDATE
- CALL_DELETE
- VOICE_STATE_UPDATE
AUTO_MODERATION_CONFIGURATION (1 << 20)
- AUTO_MODERATION_RULE_CREATE
- AUTO_MODERATION_RULE_UPDATE
- AUTO_MODERATION_RULE_DELETE
AUTO_MODERATION_EXECUTION (1 << 21)
- AUTO_MODERATION_ACTION_EXECUTION
USER_RELATIONSHIPS (1 << 22) ⁴
- RELATIONSHIP_ADD
- RELATIONSHIP_UPDATE
- RELATIONSHIP_REMOVE
- GAME_RELATIONSHIP_ADD
- GAME_RELATIONSHIP_REMOVE
USER_PRESENCE (1 << 23) ⁴
- PRESENCE_UPDATE
GUILD_MESSAGE_POLLS (1 << 24)
- MESSAGE_POLL_VOTE_ADD
- MESSAGE_POLL_VOTE_REMOVE
DIRECT_MESSAGE_POLLS (1 << 25)
- MESSAGE_POLL_VOTE_ADD
- MESSAGE_POLL_VOTE_REMOVE
DIRECT_EMBEDDED_ACTIVITIES (1 << 26)
- EMBEDDED_ACTIVITY_UPDATE_V2
LOBBIES (1 << 27) ⁵
- LOBBY_CREATE
- LOBBY_UPDATE
- LOBBY_MEMBER_ADD
- LOBBY_MEMBER_UPDATE
- LOBBY_MEMBER_REMOVE
- LOBBY_MESSAGE_CREATE
- LOBBY_MESSAGE_UPDATE
- LOBBY_MESSAGE_DELETE
- LOBBY_VOICE_SERVER_UPDATE
- LOBBY_VOICE_STATE_UPDATE
LOBBY_DELETE (1 << 28) ⁵
- LOBBY_DELETE
```
^1^ [Thread Members Update](/gateway/gateway-events#thread-members-update) contains different data depending on which intents are used.
^2^ For bots, events under the `GUILD_PRESENCES` and `GUILD_MEMBERS` intents are turned **off by default on all API versions**. Bots using API v7 and below will receive events associated with the privileged intents they have _without_ passing those intents into the `intents` parameter when identifying. Bots using **API v8** and above must specify all intents when identifying (privileged or not). User accounts default to all intents being on.
^3^ `MESSAGE_CONTENT` does not represent individual events, but rather affects what data is present for events that could contain message content fields. More information is in the [message content intent](#message-content-intent) section.
^4^ This intent cannot be used by bots.
^5^ This intent is only applicable in [OAuth2 contexts](/gateway/using-gateway#oauth2-and-the-gateway).
### Caveats
Any [events not defined in an intent](#gateway-events) are considered "passthrough" and will always be sent to you.
[Guild Member Update](/gateway/gateway-events#guild-member-update) is sent for current-user updates regardless of whether the `GUILD_MEMBERS` intent is set.
[Message Create](/gateway/gateway-events#message-create), [Message Update](/gateway/gateway-events#message-update), and [Message Delete](/gateway/gateway-events#message-delete) are sent for messages in group DMs regardless of any intents.
[Guild Create](/gateway/gateway-events#guild-create) and [Request Guild Members](/gateway/gateway-events#request-guild-members) are uniquely affected by intents. See these sections for more information.
[Thread Members Update](/gateway/gateway-events#thread-members-update) by default only includes if the current user was added to or removed from a thread. To receive these updates for other users, request the `GUILD_MEMBERS` [Gateway intent](#gateway-intents).
### Privileged Intents
Some intents are defined as privileged due to the sensitive nature of the data. Currently, those intents include:
- `GUILD_PRESENCES`
- `GUILD_MEMBERS`
- [`MESSAGE_CONTENT`](#message-content-intent)
For bots, to specify privileged intents in their `IDENTIFY` payload, they must be authorized for them. Verified applications can only use privileged intents _after_ they've been approved for them. Unverified applications may simply toggle them on. User accounts do not have the contept of privileged intents, and can simply use any intent; however, they have caveats of their own.
#### Enabling Privileged Intents
Before bots can use privileged intents, they must be enabled in their application's [flags](/resources/application#application-flags). The limited variants of these intents (usable by unverified applications) can simply be toggled on. The full variants (usable by verified applications) require approval.
Applications that qualify for [verification](https://dis.gd/bot-verification) must first be [verified](https://support-dev.discord.com/hc/en-us/articles/23926564536471-How-Do-I-Get-My-App-Verified), and you can request access to these intents during the verification process. If the app is already verified and you need to request additional privileged intents, you can [contact support](https://dis.gd/support).
#### Gateway Restrictions
Privileged intents affect which Gateway events bots are permitted to receive. For bots using **API v8** and above, all intents (privileged and not) must be specified in the `intents` parameter when identifying. Passing a privileged intent in the `intents` parameter without having it enabled will lead to the Gateway connection being closed with a ([`4014` close code](/gateway/opcodes-and-close-codes#gateway-close-event-codes)).
Events associated with the `GUILD_PRESENCES` and `GUILD_MEMBERS` intents are turned **off by default on all API versions**. Bots using API v7 and below will receive events associated with the privileged intents they have _without_ passing those intents into the `intents` parameter when identifying.
#### HTTP Restrictions
In addition to Gateway restrictions, privileged intents also affect the [HTTP API](/reference#http-api) endpoints bots are permitted to call, and the data they can receive. For example, to use the [List Guild Members](/resources/guild#list-guild-members) endpoint, a bot must have the `GUILD_MEMBERS` intent enabled. If the bot does not have the intent enabled, the endpoint will return a `403 Forbidden` error.
HTTP API restrictions are independent of Gateway restrictions, and are unaffected by intents passed in the `intents` parameter when identifying.
#### Message Content Intent
`MESSAGE_CONTENT (1 << 15)` is a unique privileged intent that isn't directly associated with any Gateway events. Instead, access to `MESSAGE_CONTENT` permits users to receive message content data across the APIs.
While user accounts can also toggle the `MESSAGE_CONTENT` intent, they are not subject to the same restrictions as bots. User accounts do not have the concept of privileged intents, and therefore do not need to be approved for the intent. Additionally, user accounts must explicitly toggle on the intent in all API versions if they are utilizing intents.
Any fields affected by the message content intent are noted in the relevant documentation. For example, the `content`, `embeds`, `attachments`, `components`, and `poll` fields in [message objects](/resources/message#message-object) all contain message content and therefore require the intent.
Users **without** the intent will receive empty values in fields that contain user-inputted content with a few exceptions:
- Content in messages that the user sends
- Content in DMs with the user
- Content in which the user is [mentioned](/reference#message-formatting)
- Content of the message a [message context menu command](/interactions/application-commands#message-commands) is used on
## Rate Limiting
This section is about Gateway rate limits, not [HTTP API rate limits](/topics/rate-limits/).
Clients can send 120 [Gateway events](/gateway/gateway-events) per [connection](#connections) every 60 seconds, meaning an average of 2 commands per second. Clients that surpass the limit are immediately disconnected from the Gateway. Similar to other rate limits, repeat offenders will have their API access revoked.
Clients also have a limit for [concurrent](#session-start-limit-object) [identify](#identifying) requests allowed per 5 seconds. If you hit this limit, the Gateway will respond with an [Opcode 9 Invalid Session](/gateway/gateway-events#invalid-session).
#### Sub Rate Limits
Some opcodes have their own specific rate limits. These are currently as follows:
| Opcode | Rate Limit |
| ------------------------------------------------------------------------------- | ---------------------------------------------- |
| [Opcode 8 Request Guild Members](/gateway/gateway-events#request-guild-members) | 1 request per guild per session per 30 seconds |
If a client exceeds an Opcode-specific rate limit, the Gateway will respond with a [Rate Limited](/gateway/gateway-events#rate-limited) event.
## Encoding and Compression
When [establishing a connection](#connecting) to the Gateway, clients can use the `encoding` parameter to choose whether to communicate with Discord using a plain-text JSON or binary [ETF](https://erlang.org/doc/apps/erts/erl_ext_dist.html) encoding. You can pick whichever encoding type you're more comfortable with, but both have their own quirks. If you aren't sure which encoding to use, JSON is generally recommended.
Clients can also optionally enable compression to receive zlib-compressed packets. [Payload compression](#payload-compression) can only be enabled when using JSON encoding, but [transport compression](#transport-compression) can be used regardless of encoding type.
#### Payload Compression
If a client is using payload compression, it cannot use [transport compression](#transport-compression).
Payload compression enables optional per-packet compression for _some_ events when Discord is sending events over the connection.
Payload compression uses the zlib format (see [RFC1950 2.2](https://tools.ietf.org/html/rfc1950#section-2.2)) when sending payloads. To enable payload compression, your client can set `compress` to `true` when [identifying](#identifying). Note that even when payload compression is enabled, not all payloads will be compressed.
When payload compression is enabled, your client _must_ detect and decompress these payloads to plain-text JSON before attempting to parse them. If you are using payload compression, the Gateway does not implement a shared compression context between events sent.
Payload compression will be disabled if you use [transport compression](#transport-compression).
### Using ETF Encoding
When using ETF (External Term Format) encoding, there are some specific behaviors you should know:
- Snowflake IDs are transmitted as 64-bit integers or strings.
- Your client can't send compressed messages to the server.
- When sending payloads, you must use string keys. Using atom keys will result in a [`4002` close code](/gateway/opcodes-and-close-codes#gateway-close-event-codes).
See [erlpack](https://github.com/discord/erlpack) for an ETF implementation example.
### Transport Compression
Transport compression enables optional compression for all packets when Discord is sending events over the connection. The only currently-available transport compression options are `zlib-stream` and `zstd-stream`.
###### Zlib-Stream Compression
When zlib transport compression is enabled, your client needs to process received data through a single Gateway connection using a shared zlib context. However, each Gateway connection should use its own unique zlib context.
When processing transport-compressed data, you should push received data to a buffer until you receive the 4-byte `Z_SYNC_FLUSH` suffix (`00 00 ff ff`). After you receive the `Z_SYNC_FLUSH` suffix, you can then decompress the buffer.
###### Zlib-Stream Compression Example
```py
# Z_SYNC_FLUSH suffix
ZLIB_SUFFIX = b'\x00\x00\xff\xff'
# initialize a buffer to store chunks
buffer = bytearray()
# create a shared zlib inflation context to run chunks through
inflator = zlib.decompressobj()
# ...
def on_websocket_message(msg):
# always push the message data to your cache
buffer.extend(msg)
# check if the last four bytes are equal to ZLIB_SUFFIX
if len(msg) < 4 or msg[-4:] != ZLIB_SUFFIX:
return
# if the message *does* end with ZLIB_SUFFIX,
# get the full message by decompressing the buffers
# NOTE: the message is utf-8 encoded.
msg = inflator.decompress(buffer)
buffer = bytearray()
# here you can treat `msg` as either JSON or ETF encoded,
# depending on your `encoding` param
```
###### Zstd-Stream Compression
When zstd transport compression is enabled, all data needs to be processed through a zstd decompression context that stays alive for the lifetime of the gateway connection.
When processing data, each WebSocket message corresponds to a single Gateway message, but does not end a zstd frame. You will need to repeatedly call `ZSTD_decompressStream`
until all data in the frame has been processed (`ZSTD_decompressStream` will not necessarily return 0, though).
###### Zstd-Stream Compression Example
Take a look at this [Erlang](https://github.com/silviucpp/ezstd/blob/f3f33b2f6b917f7e8aaa2b4d71338620537df81b/src/ezstd.erl#L151-L169) + [C++](https://github.com/silviucpp/ezstd/blob/f3f33b2f6b917f7e8aaa2b4d71338620537df81b/c_src/ezstd_nif.cc#L520-L568) implementation for inspiration.
## Tracking State
Most of a client's state is provided during the initial [Ready](/gateway/gateway-events#ready) event (and optionally the [Guild Create](/gateway/gateway-events#guild-create) events that immediately follow).
As resources continue to be created, updated, and deleted, Gateway events are sent to notify the client of these changes and to provide associated data. To avoid excessive API calls, clients should cache as many relevant resource states as possible, and update them as new events are received.
For larger bots, client state can grow to be quite large. It is recommended to only store objects in memory that are needed for a bot's operation. Many bots, for example, just respond to user input through chat commands. These bots may only need to keep guild information (like guild/channel roles and permissions) in memory, since [Message Create](/gateway/gateway-events#message-create) and [Message Update](/gateway/gateway-events#message-update) events have the full member object available.
An example of state tracking can be considered in the case of a bot that wants to track member status: when initially connecting to the Gateway, the bot will receive information about the online status of guild members (whether they're online, idle, on do-not-disturb, or offline). To keep the state updated, the bot will track and parse [Presence Update](/gateway/gateway-events#presence-update) events as they're received, then update the cached member objects accordingly.
## Guild Availability
When connecting to the Gateway as a bot user, guilds that the bot is a part of will start out as unavailable. Don't fret! The Gateway will automatically attempt to reconnect on your behalf. As guilds become available to you, you will receive [Guild Create](/gateway/gateway-events#guild-create) events. On the other hand, users start out with all possible guilds available to them.
## Sharding
As bots grow and are added to an increasing number of guilds, some developers may find it necessary to break or split portions of their bots operations into separate logical processes. As such, the Gateway implements a method of user-controlled guild sharding which allows for splitting events across a number of Gateway connections. Guild sharding is entirely user controlled, and requires no state-sharing between separate connections to operate.
Sharding is required for all bots in more than 2500 guilds. While all clients can utilize sharding, it is primarily intended for large bots. It is never necessary for user accounts, as they are limited to a maximum of 200 guilds.
User accounts always have a `max_concurrency` of 1, but do not have a session start limit.
Additionally, they are limited to a maximum of 50 active Gateway sessions at a time.
To enable sharding on a connection, the client should send the `shard` array in the [Identify](/gateway/gateway-events#identify) payload. The first item in this array should be the zero-based integer value of the current shard, while the second represents the total number of shards. DMs will only be sent to shard 0.
The [Get Gateway Bot](#get-gateway-bot) endpoint provides a recommended number of shards for your client in the `shards` field.
To calculate which events will be sent to which shard, the following formula can be used:
###### Sharding Formula
```py
shard_id = (guild_id >> 22) % num_shards
```
As an example, if you wanted to split the connection between three shards, you'd use the following values for `shard` for each connection: `[0, 3]`, `[1, 3]`, and `[2, 3]`. Note that only the first shard (`[0, 3]`) would receive DMs.
Note that `num_shards` does not relate to (or limit) the total number of potential sessions. It is only used for _routing_ traffic. As such, sessions do not have to be identified in an evenly distributed manner when sharding. You can establish multiple sessions with the same `[shard_id, num_shards]`, or sessions with different `num_shards` values. This allows you to create sessions that will handle more or less traffic than others for more fine-tuned load balancing, or to orchestrate "zero-downtime" scaling/updating by handing off traffic to a new deployment of sessions with a higher or lower `num_shards` count that are prepared in parallel.
###### Max Concurrency
If you have multiple shards, you may start them concurrently based on the [`max_concurrency`](#session-start-limit-object) value returned to you on session start. Which shards you can start concurrently are assigned based on a key for each shard. The rate limit key for a given shard can be computed with
```
rate_limit_key = shard_id % max_concurrency
```
This puts your shards into "buckets" of `max_concurrency` size. When you start your bot, you may start up to `max_concurrency` shards at a time, and you must start them by "bucket" **in order**. To explain another way, let's say you have 16 shards, and your `max_concurrency` is 16:
```
shard_id: 0, rate limit key (0 % 16): 0
shard_id: 1, rate limit key (1 % 16): 1
shard_id: 2, rate limit key (2 % 16): 2
shard_id: 3, rate limit key (3 % 16): 3
shard_id: 4, rate limit key (4 % 16): 4
shard_id: 5, rate limit key (5 % 16): 5
shard_id: 6, rate limit key (6 % 16): 6
shard_id: 7, rate limit key (7 % 16): 7
shard_id: 8, rate limit key (8 % 16): 8
shard_id: 9, rate limit key (9 % 16): 9
shard_id: 10, rate limit key (10 % 16): 10
shard_id: 11, rate limit key (11 % 16): 11
shard_id: 12, rate limit key (12 % 16): 12
shard_id: 13, rate limit key (13 % 16): 13
shard_id: 14, rate limit key (14 % 16): 14
shard_id: 15, rate limit key (15 % 16): 15
```
You may start all 16 of your shards at once, because each has a `rate_limit_key` which fills the bucket of 16 shards. However, let's say you had 32 shards:
```
shard_id: 0, rate limit key (0 % 16): 0
shard_id: 1, rate limit key (1 % 16): 1
shard_id: 2, rate limit key (2 % 16): 2
shard_id: 3, rate limit key (3 % 16): 3
shard_id: 4, rate limit key (4 % 16): 4
shard_id: 5, rate limit key (5 % 16): 5
shard_id: 6, rate limit key (6 % 16): 6
shard_id: 7, rate limit key (7 % 16): 7
shard_id: 8, rate limit key (8 % 16): 8
shard_id: 9, rate limit key (9 % 16): 9
shard_id: 10, rate limit key (10 % 16): 10
shard_id: 11, rate limit key (11 % 16): 11
shard_id: 12, rate limit key (12 % 16): 12
shard_id: 13, rate limit key (13 % 16): 13
shard_id: 14, rate limit key (14 % 16): 14
shard_id: 15, rate limit key (15 % 16): 15
shard_id: 16, rate limit key (16 % 16): 0
shard_id: 17, rate limit key (17 % 16): 1
shard_id: 18, rate limit key (18 % 16): 2
shard_id: 19, rate limit key (19 % 16): 3
shard_id: 20, rate limit key (20 % 16): 4
shard_id: 21, rate limit key (21 % 16): 5
shard_id: 22, rate limit key (22 % 16): 6
shard_id: 23, rate limit key (23 % 16): 7
shard_id: 24, rate limit key (24 % 16): 8
shard_id: 25, rate limit key (25 % 16): 9
shard_id: 26, rate limit key (26 % 16): 10
shard_id: 27, rate limit key (27 % 16): 11
shard_id: 28, rate limit key (28 % 16): 12
shard_id: 29, rate limit key (29 % 16): 13
shard_id: 30, rate limit key (30 % 16): 14
shard_id: 31, rate limit key (31 % 16): 15
```
In this case, you must start the shard buckets **in "order"**. That means that you can start shard 0 -> shard 15 concurrently, and then you can start shard 16 -> shard 31.
### Sharding for Large Bots
For bots in more than 150,000 guilds, there are some additional considerations you must take around sharding. Discord will migrate your bot to large bot sharding when it starts to get near the large bot sharding threshold. The bot owner(s) will receive a system DM and email confirming this move has completed as well as what shard number has been assigned.
The number of shards you run must be a multiple of the shard number provided when reaching out to you. If you attempt to start your bot with an invalid number of shards, your Gateway connection will close with a [`4010` close code](/gateway/opcodes-and-close-codes#gateway-close-event-codes).
The [Get Gateway Bot](/gateway/using-gateway#get-gateway-bot) endpoint will always return the correct amount of shards, so if you're already using this endpoint to determine your number of shards, you shouldn't require any changes.
The session start limit for these bots will also be increased from 1000 to `max(2000, (guild_count / 1000) * 5)` per day. You also receive an increased `max_concurrency`, the number of [shards you can concurrently start](#session-start-limit-object).
## Session Start Limit Object
###### Session Start Limit Structure
| Field | Type | Description |
| --------------- | ------- | ------------------------------------------------------ |
| total | integer | Total number of session starts the user is allowed |
| remaining | integer | Remaining number of session starts the user is allowed |
| reset_after | integer | Number of milliseconds after which the limit resets |
| max_concurrency | integer | Number of identify requests allowed per 5 seconds |
## Endpoints
Get Gateway
Returns an object with a single valid WebSocket URL, which the client can use for [Connecting](#connecting). Clients **should** cache this value and only call this endpoint to retrieve a new URL if they are unable to properly establish a connection using the cached one.
###### Response Body
| Field | Type | Description |
| ----- | ------ | ---------------------------------------------------------------- |
| url | string | The WebSocket URL that can be used for connecting to the Gateway |
###### Example Response
```json
{
"url": "wss://gateway.discord.gg"
}
```
Get Gateway Bot
Returns an object based on the information in [Get Gateway](#get-gateway), plus additional metadata that can help during the operation of large or [sharded](#sharding) bots. Unlike [Get Gateway](#get-gateway), this route should not be cached for extended periods of time as the value is not guaranteed to be the same per-call, and changes as the user joins/leaves guilds.
###### Response Body
| Field | Type | Description |
| ------------------- | --------------------------------------------------------- | -------------------------------------------------------------------- |
| url | string | The WebSocket URL that can be used for connecting to the Gateway |
| shards | integer | The recommended number of [shards](#sharding) to use when connecting |
| session_start_limit | [session start limit](#session-start-limit-object) object | Information on the current session start limit |
###### Example Response
```json
{
"url": "wss://gateway.discord.gg",
"shards": 9,
"session_start_limit": {
"total": 1000,
"remaining": 999,
"reset_after": 14400000,
"max_concurrency": 1
}
}
```
---
# Opcodes and Close Codes
Link: https://docs.discord.food/gateway/opcodes-and-close-codes
## Gateway
All Gateway events in Discord are tagged with an opcode that denotes the payload type. Your connection to the Gateway may also sometimes close. When it does, you will receive a close code that tells you what happened.
###### Gateway Opcodes
| Code | Name | Action | Description |
| ------ | --------------------------------------------- | ------------ | -------------------------------------------------------------------------------------- |
| 0 | Dispatch | Receive | An event was dispatched |
| 1 | Heartbeat | Send/Receive | Keep the WebSocket connection alive |
| 2 | Identify | Send | Start a new session during the initial handshake |
| 3 | Presence Update | Send | Update the client's presence |
| 4 | Voice State Update | Send | Join/leave or move between voice channels and calls |
| 5 | Voice Server Ping | Send | Ping the Discord voice servers |
| 6 | Resume | Send | Resume a previous session that was disconnected |
| 7 | Reconnect | Receive | You should attempt to reconnect and resume immediately |
| 8 | Request Guild Members | Send | Request information about guild members |
| 9 | Invalid Session | Receive | The session has been invalidated. You should reconnect and identify/resume accordingly |
| 10 | Hello | Receive | Sent immediately after connecting, contains the `heartbeat_interval` to use |
| 11 | Heartbeat ACK | Receive | Acknowledge a received heartbeat |
| ~~12~~ | ~~Guild Sync~~ | ~~Send~~ | ~~Request all members and presences for guilds~~ |
| 13 | Call Connect | Send | Request a private channels's pre-existing call data |
| 14 | Guild Subscriptions **(deprecated)** | Send | Update subscriptions for a guild |
| ~~15~~ | ~~Lobby Connect~~ | ~~Send~~ | ~~Join a lobby~~ |
| ~~16~~ | ~~Lobby Disconnect~~ | ~~Send~~ | ~~Leave a lobby~~ |
| 17 | Lobby Voice States | Send | Update the client's voice state in a lobby |
| 18 | Stream Create | Send | Create a stream for the client |
| 19 | Stream Delete | Send | End a client stream |
| 20 | Stream Watch | Send | Watch a user's stream |
| 21 | Stream Ping | Send | Ping a stream's voice server |
| 22 | Stream Set Paused | Send | Pause or resume a client stream |
| ~~23~~ | ~~LFG Subscriptions~~ | ~~Send~~ | ~~Update subscriptions for an LFG lobby~~ |
| ~~24~~ | ~~Request Guild Application Commands~~ | ~~Send~~ | ~~Request guild application commands~~ |
| ~~25~~ | ~~Embedded Activity Create~~ | ~~Send~~ | ~~Launch an embedded activity in a voice channel or call~~ |
| ~~26~~ | ~~Embedded Activity Delete~~ | ~~Send~~ | ~~Stop an embedded activity~~ |
| ~~27~~ | ~~Embedded Activity Update~~ | ~~Send~~ | ~~Update an embedded activity~~ |
| 28 | Request Forum Unreads | Send | Request thread-only channel unread counts |
| 29 | Remote Command | Send | Send a a message to another Gateway session |
| 30 | Request Deleted Entity IDs | Send | Request deleted entity IDs not matching a given hash for a guild |
| 31 | Request Soundboard Sounds | Send | Request soundboard sounds for guilds |
| 32 | Speed Test Create **(deprecated)** | Send | Create or update an RTC speed test |
| 33 | Speed Test Delete **(deprecated)** | Send | Delete an RTC speed test |
| 34 | Request Last Messages | Send | Request last messages for a guild's channels |
| 35 | Search Recent Members | Send | Request information about recently-joined guild members |
| 36 | Request Channel Statuses **(deprecated)** ^1^ | Send | ~~Request voice channel statuses for a guild~~ |
| 37 | Guild Subscriptions Bulk | Send | Update subscriptions for multiple guilds |
| 38 | Guild Channels Resync | Send | Resynchronize accessible guild channels |
| 39 | Request Channel Member Count | Send | Request the member and online count for a channel |
| 40 | QoS Heartbeat | Send | Keep the WebSocket connection alive (with QoS metrics) |
| 41 | Update Time Spent Session ID | Send | Track the time spent in the current session |
| 42 | Lobby Voice Server Ping | Send | Ping a lobby's voice server |
| 43 | Request Channel Info | Send | Request extra voice channel fields for a guild |
^1^ Superseded by Request Channel Info.
###### Gateway Close Event Codes
| Code | Description | Explanation |
| -------- | --------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| 4000 | Unknown error | We're not sure what went wrong. Try reconnecting? |
| 4001 | Unknown opcode | You sent an invalid [Gateway opcode](#gateway-opcodes) or an invalid payload for an opcode. Don't do that! |
| 4002 | Decode error | You sent an invalid [payload](/gateway/using-gateway#sending-events). Don't do that! |
| 4003 | Not authenticated | You sent us a payload prior to [identifying](/gateway/using-gateway#identifying), or this session has been invalidated |
| 4004 | Authentication failed | The account token sent with your [identify payload](/gateway/gateway-events#identify) is incorrect |
| 4005 | Already authenticated | You sent more than one identify payload. Don't do that! |
| ~~4006~~ | ~~Session no longer valid~~ | ~~Your session is no longer valid~~ |
| 4007 | Invalid `seq` | The sequence sent when [resuming](/gateway/gateway-events#resume) the session was invalid. Reconnect and start a new session |
| 4008 | Rate limited | Woah nelly! You're sending payloads too quickly. Slow it down! You will be disconnected on receiving this |
| 4009 | Session timed out | Your session timed out. Reconnect and start a new one |
| 4010 | Invalid shard | You sent us an invalid [shard when identifying](/gateway/using-gateway#sharding) |
| 4011 | Sharding required | The session would have handled too many guilds—you are required to [shard](/gateway/using-gateway#sharding) your connection in order to connect |
| 4012 | Invalid API version | You sent an invalid version for the Gateway |
| 4013 | Invalid intent(s) | You sent an invalid intent for a [Gateway intent](/gateway/using-gateway#gateway-intents). You may have incorrectly calculated the bitwise value |
| 4014 | Disallowed intent(s) | You sent a disallowed intent for a [Gateway intent](/gateway/using-gateway#gateway-intents). You may have tried to specify an intent that you [have not enabled or are not approved for](/gateway/using-gateway#privileged-intents) |
| 4015 | Too many sessions | You have more than the allowed amount of user account Gateway sessions open |
| 4016 | Connection request canceled | Console device connection request was canceled. The Gateway session is no longer needed |
## Voice
The Voice Gateway has its own set of opcodes and close codes.
###### Voice Opcodes
| Code | Name | Action | Description | Format |
| ------ | -------------------------------- | ---------------- | --------------------------------------------------------------------------- | ------ |
| 0 | Identify | Send | Start a new voice WebSocket connection | JSON |
| 1 | Select Protocol | Send | Select the voice protocol | JSON |
| 2 | Ready | Receive | Complete the WebSocket handshake | JSON |
| 3 | Heartbeat | Send/Receive | Keep the WebSocket connection alive | JSON |
| 4 | Session Description | Receive | Describe the session | JSON |
| 5 | Speaking | Send/Receive | Indicate which users are speaking | JSON |
| 6 | Heartbeat ACK | Receive | Acknowledge a received heartbeat | JSON |
| 7 | Resume | Send | Resume a previous session that was disconnected | JSON |
| 8 | Hello | Receive | Sent immediately after connecting, contains the `heartbeat_interval` to use | JSON |
| 9 | Resumed | Receive | Response to acknowledging a successful resume | JSON |
| ~~10~~ | ~~Signal~~ | ~~Send/Receive~~ | ~~Signal WebRTC peers for P2P connections~~ | JSON |
| ~~11~~ | ~~Reset~~ | ~~Send/Receive~~ | ~~Reset the voice connection~~ | JSON |
| 11 | Clients Connect | Receive | Indicate that clients have connected to the voice channel | JSON |
| 12 | Video | Send/Receive | Describe the video session | JSON |
| 13 | Client Disconnect | Receive | Indicate that a client has disconnected from the voice channel | JSON |
| 14 | Session Update | Send/Receive | Indicate an update in session description | JSON |
| 15 | Media Sink Wants | Send/Receive | Indicate the media streams wanted for simulcasting | JSON |
| 16 | Voice Backend Version | Send/Receive | Version information about the voice backend | JSON |
| ~~17~~ | ~~Channel Options Update~~ | ~~Receive~~ | ~~Indicate an update in voice connection properties~~ | JSON |
| 18 | Client Flags | Receive | Indicate a client's flags | JSON |
| 19 | Speed Test | Receive | Indicate speed test results | JSON |
| 20 | Client Platform | Receive | Indicate the platform a client is connected on | JSON |
| 21 | DAVE Protocol Prepare Transition | Receive | A downgrade from the DAVE protocol is upcoming | JSON |
| 22 | DAVE Protocol Execute Transition | Receive | Execute a previously announced protocol transition | JSON |
| 23 | DAVE Protocol Transition Ready | Send | Acknowledge readiness previously announced transition | JSON |
| 24 | DAVE Protocol Prepare Epoch | Receive | A DAVE protocol version or group change is upcoming | JSON |
| 25 | MLS External Sender Package | Receive | Credential and public key for MLS external sender | Binary |
| 26 | MLS Key Package | Send | MLS Key Package for pending group member | Binary |
| 27 | MLS Proposals | Receive | MLS Proposals to be appended or revoked | Binary |
| 28 | MLS Commit Welcome | Send | MLS Commit with optional MLS Welcome messages | Binary |
| 29 | MLS Announce Commit Transition | Receive | MLS Commit to be processed for upcoming transition | JSON |
| 30 | MLS Welcome | Receive | MLS Welcome to group for upcoming transition | Binary |
| 31 | MLS Invalid Commit Welcome | Send | Flag invalid commit or welcome, request re-add | JSON |
| 32 | No Route | Send | Indicate that no RTC route was available | JSON |
###### Voice Close Event Codes
| Code | Description | Explanation |
| ---- | ------------------------ | ------------------------------------------------------------------------------------------------------------------------------------ |
| 4001 | Unknown opcode | You sent an invalid [opcode](#voice-opcodes) |
| 4002 | Failed to decode payload | You sent a invalid payload in your [identifying](/topics/voice-connections#establishing-a-voice-websocket-connection) to the Gateway |
| 4003 | Not authenticated | You sent a payload before [identifying](/topics/voice-connections#establishing-a-voice-websocket-connection) with the Gateway |
| 4004 | Authentication failed | The token you sent in your [identify](/topics/voice-connections#establishing-a-voice-websocket-connection) payload is incorrect |
| 4005 | Already authenticated | You sent more than one [identify](/topics/voice-connections#establishing-a-voice-websocket-connection) payload. Stahp |
| 4006 | Session no longer valid | Your session is no longer valid |
| 4009 | Session timeout | Your session has timed out |
| 4011 | Server not found | We can't find the server you're trying to connect to |
| 4012 | Unknown protocol | We didn't recognize the [protocol](/topics/voice-connections#select-protocol-structure) you sent |
| 4013 | WebRTC crashed | The WebRTC connection crashed. Our bad! Try [resuming](/topics/voice-connections#resuming-voice-connection) |
| 4014 | Disconnected | Disconnect individual client (you were kicked, the main Gateway session was dropped, etc.). Should not reconnect |
| 4015 | Voice server crashed | The server crashed. Our bad! Try [resuming](/topics/voice-connections#resuming-voice-connection) |
| 4016 | Unknown encryption mode | We didn't recognize your [encryption](/topics/voice-connections#sending-and-receiving-media) |
| 4017 | E2EE required | This channel requires a client supporting [E2EE via the DAVE Protocol](https://daveprotocol.com) |
| 4020 | Bad request | You sent a malformed request |
| 4021 | Rate limited | Rate limit exceeded. Should not reconnect |
| 4022 | Disconnected | Disconnect all clients (channel deleted, voice server changed, call ended, etc.). Should not reconnect |
---
# Gateway Events
Link: https://docs.discord.food/gateway/gateway-events
Gateway connections are WebSockets, meaning they're bidirectional and either side of the WebSocket can send events to the other. The following events are split up into two types:
- **Send events** are Gateway events sent by a client to Discord (like when identifying with the Gateway)
- **Receive events** are Gateway events that are sent by Discord to a client. These events typically represent something happening inside of a guild where the user is a member of, like a channel being updated.
All Gateway events are encapsulated in a [Gateway payload](#gateway-payload-structure).
For more information about interacting with the Gateway, you can reference the [Gateway documentation](/gateway/using-gateway).
### Event Names
In practice, event names are UPPER-CASED with under_scores joining each word in the name. For instance, [Channel Create](#channel-create) would be `CHANNEL_CREATE` and [Voice State Update](#voice-state-update) would be `VOICE_STATE_UPDATE`.
For readability, event names in the following documentation are typically left in Title Case.
### Gateway Payload Structure
Gateway event payloads have a common structure, but the contents of the associated data (`d`) varies between the different events.
| Field | Type | Description |
| ------ | ----------- | ---------------------------------------------------------------------------------------------------------------------------------------------------- |
| op | integer | [Gateway Opcode](/gateway/opcodes-and-close-codes#gateway-opcodes), which indicates the payload type |
| d | ?JSON value | Event data |
| s? ^1^ | ?integer | Sequence number of event used for [resuming sessions](/gateway/using-gateway#resuming) and [heartbeating](/gateway/using-gateway#sending-heartbeats) |
| t? ^1^ | ?string | Event name for this payload (`DISPATCH` Opcode only) |
^1^ These fields are received only, and `null` when the `op` is not `DISPATCH`.
###### Example Gateway Payload (Send)
```json
{
"op": 2,
"d": {}
}
```
###### Example Gateway Payload (Receive)
```json
{
"op": 0,
"d": {},
"s": 42,
"t": "GATEWAY_EVENT_NAME"
}
```
## Send Events
Send events are Gateway events encapsulated in an [event payload](#gateway-payload-structure), and are sent by a client to Discord through a Gateway connection.
| Name | Description |
| ------------------------------------------------------------------------------------- | ----------------------------------------------------------------- |
| [Identify](#identify) | Trigger the initial handshake with the Gateway |
| [Resume](#resume) | Resume a dropped Gateway connection |
| [Heartbeat](#heartbeat) | Maintain an active Gateway connection |
| [QoS Heartbeat](#qos-heartbeat) | Maintain an active Gateway connection with QoS metrics |
| [Update Time Spent Session ID](#update-time-spent-session-id) | Track the time spent in the current session |
| [Update Presence](#update-presence) | Update the client's presence |
| [Update Voice State](#update-voice-state) | Join, move, or disconnect the client from a voice channel or call |
| [Ping Voice Server](#ping-voice-server) | Ping the Discord voice servers |
| [Create Stream](#create-stream) | Create a stream for the client (Go Live) |
| [Watch Stream](#watch-stream) | Watch a user's stream |
| [Set Stream Paused](#set-stream-paused) | Pause/resume a client stream |
| [Delete Stream](#delete-stream) | End a client stream |
| [Ping Stream Server](#ping-stream-server) | Ping a user's stream voice server |
| [Update Lobby Voice States](#update-lobby-voice-states) | Update voice states for multiple lobbies |
| [Ping Lobby Voice Server](#ping-lobby-voice-server) | Ping a lobby's voice server |
| [Request Guild Members](#request-guild-members) | Request members for one or more guilds |
| [Request Call Connect](#request-call-connect) | Request a private channels's pre-existing call information |
| Update Guild Subscriptions | Update subscriptions for a guild |
| Request Forum Unreads | Request thread-only channel unread counts |
| [Remote Command](<#remote-command-(send)>) | Send a message to another Gateway session |
| [Get Deleted Entity IDs Not Matching Hash](#get-deleted-entity-ids-not-matching-hash) | Request deleted entity IDs not matching a given hash for a guild |
| [Request Soundboard Sounds](#request-soundboard-sounds) | Request soundboard sounds for one or more guilds |
| [Create Speed Test](#create-speed-test) | Create or update an RTC speed test for the client. |
| [Delete Speed Test](#delete-speed-test) | Delete the client's RTC speed test. |
| [Request Last Messages](#request-last-messages) | Request last messages for a guild's channels |
| [Search Recent Members](#search-recent-members) | Request recently-joined members for a guild |
| [Resync Guild Channels](#resync-guild-channels) | Requests channel(s) for a guild |
| [Request Channel Statuses](#request-channel-statuses) | Request voice channel statuses for a guild |
| [Request Channel Member Count](#request-channel-member-count) | Request the number of members that can view a channel |
| [Request Channel Info](#request-channel-info) | Request extra voice channel fields for a guild |
#### Identify
Used to trigger the initial handshake with the Gateway.
Details about identifying is in the [Gateway documentation](/gateway/using-gateway#identifying).
###### Identify Structure
| Field | Type | Description |
| ----------------- | -------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| token | string | Authentication token |
| properties | [client properties](/reference#client-properties) object | Client and system information |
| compress? | boolean | Whether this connection uses legacy payload compression (default false) |
| large_threshold? | integer | Total number of members where, for bots, the Gateway will stop sending offline members in the guild member list, or, for users, stop sending non-stateful events for guilds without a subscription (25-250, default 25 for bots and 250 for users) |
| shard? | array[integer, integer] | The connection's shard (shard_id, num_shards), used for [connection sharding](/gateway/using-gateway#sharding) |
| presence? ^1^ ^3^ | [update presence](#update-presence-structure) object | Initial presence information |
| intents? ^2^ | integer | The [Gateway intents](/gateway/using-gateway#gateway-intents) you wish to receive |
| capabilities? | integer | The [Gateway capabilities](/gateway/using-gateway#gateway-capabilities) you wish to enable |
| client_state? ^3^ | [client state](#client-state-structure) object | The client's current cache state, used for reducing unneeded information transmission on re-identify |
^1^ For user accounts, the `status` and `activities` specified may not always be respected. The field should only be used when re-identifying to communicate the last known presence of the user. Otherwise, the status should be `unknown` and activities an empty array.
^2^ Required for bots on API v8 and above.
^3^ Not supported in [OAuth2 contexts](/gateway/using-gateway#oauth2-and-the-gateway).
###### Client State Structure
| Field | Type | Description |
| ---------------------------- | ----------------------- | --------------------------------------------------------------------------- |
| guild_versions | map[snowflake, integer] | A mapping of guild IDs to their last known version |
| highest_last_message_id? | snowflake | The highest last message ID across all guild channels |
| read_state_version? | integer | The version of all read states together |
| user_guild_settings_version? | integer | The version of user guild settings |
| user_settings_version? | integer | The data version of the user settings proto |
| private_channels_version? | snowflake | The highest last message ID across all private channels |
| api_code_version? | integer | The API code version |
| initial_guild_id? | snowflake | The ID of the guild to receive an [Initial Guild](#initial-guild) event for |
###### Example Identify
```json
{
"op": 2,
"d": {
"token": "my_token",
"properties": {
"os": "linux",
"browser": "disco",
"device": "disco"
},
"compress": false,
"presence": {
"activities": [],
"status": "unknown",
"since": 0,
"afk": false
},
"capabilities": 1734653,
"client_state": {
"guild_versions": {},
"api_code_version": 0
}
}
}
```
#### Resume
Used to replay missed events when a disconnected client resumes.
Details about resuming are in the [Gateway documentation](/gateway/using-gateway#resuming).
###### Resume Structure
| Field | Type | Description |
| ---------- | ------- | ----------------------------- |
| token | string | Authentication token |
| session_id | string | Existing session ID |
| seq | integer | Last sequence number received |
###### Example Resume
```json
{
"op": 6,
"d": {
"token": "randomstring",
"session_id": "30f32c5d54ae86130fc4a215c7474263",
"seq": 1337
}
}
```
#### Heartbeat
Used to maintain an active Gateway connection. Must be sent every `heartbeat_interval` milliseconds after the [Opcode 10 Hello](#hello) payload is received. The inner `d` key is the last sequence number—`s`—received by the client.
If you have not yet received one, send `null`. Fires a [Heartbeat ACK](#heartbeat-ack) Gateway event.
Details about heartbeats are in the [Gateway documentation](/gateway/using-gateway#sending-heartbeats).
###### Example Heartbeat
```json
{
"op": 1,
"d": 251
}
```
#### QoS Heartbeat
Same as a normal [heartbeat](#heartbeat), but also tracks [Quality of Service](https://en.wikipedia.org/wiki/Quality_of_service) statistics.
Must be sent every `heartbeat_interval` milliseconds after the [Opcode 10 Hello](#hello) payload is received. Fires a [Heartbeat ACK](#heartbeat-ack) Gateway event.
Details about heartbeats are in the [Gateway documentation](/gateway/using-gateway#sending-heartbeats).
###### QoS Heartbeat Structure
| Field | Type | Description |
| ----- | ------------------------------------- | ---------------------------------- |
| seq | ?integer | Last sequence number received |
| qos | [QoS payload](#qos-payload-structure) | The QoS payload for this heartbeat |
###### QoS Payload Structure
| Field | Type | Description |
| ------- | ------------- | ---------------------------------------------------------------- |
| ver | integer | The client heartbeat version (currently `29`) |
| active | boolean | Whether the session is currently active (has reasons of service) |
| reasons | array[string] | [Reasons of service](#reasons-of-service) |
###### Reasons of Service
| Name | Description |
| ------------- | ----------------------------------- |
| foregrounded | Window is focused |
| rtc_connected | User is connected to the voice call |
###### Example QoS Heartbeat
```json
{
"op": 40,
"d": {
"seq": 1337,
"qos": {
"ver": 29,
"active": true,
"reasons": ["foregrounded", "rtc_connected"]
}
}
}
```
#### Update Time Spent Session ID
Sent every 30 minutes (if the client is focused or is in a voice call) and on connect to track the time the user has spent in the current session.
Whenever this is sent, an accompanying [QoS Heartbeat](#qos-heartbeat) should be sent.
###### QoS Heartbeat Structure
| Field | Type | Description |
| ------------------------ | ------- | ------------------------------------------------------------------------------------------------------------------- |
| initialization_timestamp | integer | Unix timestamp (in milliseconds) of when the session ID was generated |
| session_id | string | A client-generated UUID, same as `client_heartbeat_session_id` in [client properties](/reference#client-properties) |
| client_launch_id | string | A client-generated UUID, same as `client_launch_id` in [client properties](/reference#client-properties) |
###### Example Update Time Spent Session ID
```json
{
"op": 41,
"d": {
"initialization_timestamp": 1753221861697,
"session_id": "fe223885-211d-4826-ba7b-395373da4213",
"client_launch_id": "2bf1c669-4710-4b76-8c99-76f918fd36fc"
}
}
```
#### Update Presence
Sent by the client to indicate a presence update.
Requires `activities.write` or `presences.write` scope when operating in an OAuth2 context.
Clients may only update their presence 5 times per 20 seconds.
All incoming Gateway events will be paused until the updated presence is propagated.
###### Update Presence Structure
| Field | Type | Description |
| ---------- | ------------------------------------------------------------- | ------------------------------------------------------------------------------------------------- |
| activities | array[[activity](/resources/presence#activity-object) object] | The user's activities |
| status | string | the user's new [status](/resources/presence#status-type) |
| since | integer | Unix timestamp (in milliseconds) of when the client went idle, or 0 if it is not |
| afk | boolean | Whether or not the client is AFK, used to determine whether to dispatch mobile push notifications |
###### Example Update Presence
```json
{
"op": 3,
"d": {
"since": 0,
"activities": [
{
"application_id": "383226320970055681",
"assets": {
"large_image": "565945350846939145",
"large_text": "Editing a TEXT file",
"small_image": "565945770067623946",
"small_text": "Visual Studio Code"
},
"buttons": ["View Repository"],
"created_at": "1695164784863",
"details": "Editing index.astro",
"flags": 0,
"id": "d11307d8c0abb135",
"name": "Visual Studio Code",
"session_id": "30f32c5d54ae86130fc4a215c7474263",
"state": "Workspace: vendicated.dev",
"timestamps": {
"start": "1695164482423"
},
"type": 0
}
],
"status": "online",
"afk": false
}
}
```
#### Update Voice State
Sent when a client wants to join, move, or disconnect from a voice channel. Fires a [Voice State Update](#voice-state-update) and optionally a [Voice Server Update](#voice-server-update) Gateway event.
Requires `voice` scope when operating in an OAuth2 context.
###### Update Voice State Structure
| Field | Type | Description |
| ------------------ | ------------- | ------------------------------------------------------------------------------------------- |
| guild_id | ?snowflake | The ID of the guild the voice channel is in, if any |
| channel_id | ?snowflake | The ID of the voice or private channel the client wants to join (`null` if disconnecting) |
| self_mute | boolean | Whether the client is muted |
| self_deaf | boolean | Whether the client is deafened |
| self_video? | boolean | Whether the client is streaming video to the channel |
| preferred_region? | ?string | The preferred [voice region](/resources/voice#voice-region-object) ID for the voice channel |
| preferred_regions? | array[string] | The ranked [voice region](/resources/voice#voice-region-object) IDs for the voice channel |
| flags? | integer | The client's [voice flags](/topics/voice-connections#voice-flags) |
###### Example Update Voice State
```json
{
"op": 4,
"d": {
"guild_id": "41771983423143937",
"channel_id": "127121515262115840",
"self_mute": false,
"self_deaf": false,
"self_video": false,
"preferred_region": "newark",
"preferred_regions": ["newark", "us-central", "us-east", "atlanta", "us-south"],
"flags": 3
}
}
```
#### Ping Voice Server
Sent when a client wants to request that the Gateway pings a misbehaving voice server. This will force a check server-side and potentially reallocate the voice server. The inner `d` key should be set to `null`. May fire a [Voice Server Update](#voice-server-update) Gateway event.
Requires `voice` scope when operating in an OAuth2 context.
###### Example Ping Voice Server
```json
{
"op": 5,
"d": null
}
```
#### Create Stream
Sent by the client to create a stream in a given voice channel. Requires the `STREAM` permission in the given channel. Fires a [Stream Create](#stream-create) and [Stream Server Update](#stream-server-update) Gateway event.
Requires `voice` scope when operating in an OAuth2 context.
###### Create Stream Structure
| Field | Type | Description |
| ----------------- | ---------- | ------------------------------------------------------------------------------------ |
| type | string | The [type of stream](#stream-type) to create |
| guild_id? | ?snowflake | The ID of the guild to stream in, if any |
| channel_id | snowflake | The ID of the voice channel to stream in |
| preferred_region? | ?string | The preferred [voice region](/resources/voice#voice-region-object) ID for the stream |
###### Example Create Stream
```json
{
"op": 18,
"d": {
"type": "call",
"guild_id": null,
"channel_id": "1142105002492575794",
"preferred_region": "us-east"
}
}
```
### Watch Stream
Sent by the client to start watching a user's stream. User must be connected to the associated voice channel. Fires either a [Stream Create](#stream-create) and [Stream Server Update](#stream-server-update) or a [Stream Delete](#stream-delete) Gateway event.
Requires `voice` scope when operating in an OAuth2 context.
###### Watch Stream Structure
| Field | Type | Description |
| ---------- | ------ | -------------------------------------- |
| stream_key | string | The [stream key](#stream-key) to watch |
###### Example Watch Stream
```json
{
"op": 20,
"d": {
"stream_key": "call:1110739331624210483:852892297661906993"
}
}
```
#### Set Stream Paused
Sent by the client to pause or resume their stream. User must be the owner of the stream. Fires a [Stream Server Update](#stream-server-update) Gateway event.
Requires `voice` scope when operating in an OAuth2 context.
###### Set Stream Paused Structure
| Field | Type | Description |
| ---------- | ------- | ------------------------------------------------ |
| stream_key | string | The [stream key](#stream-key) to pause or resume |
| paused | boolean | Whether the stream should be paused or resumed |
###### Example Set Stream Paused
```json
{
"op": 22,
"d": {
"stream_key": "call:1110739331624210483:852892297661906993",
"paused": true
}
}
```
#### Delete Stream
Sent by the client to disconnect from a stream. If the client is the owner of the stream, the stream will be deleted. Fires a [Stream Delete](#stream-delete) Gateway event.
Requires `voice` scope when operating in an OAuth2 context.
###### Delete Stream Structure
| Field | Type | Description |
| ---------- | ------ | --------------------------------------- |
| stream_key | string | The [stream key](#stream-key) to delete |
###### Example Delete Stream
```json
{
"op": 19,
"d": {
"stream_key": "call:1110739331624210483:852892297661906993"
}
}
```
#### Ping Stream Server
Sent when a client wants to request that the Gateway pings a misbehaving stream server. This will force a check server-side and potentially reallocate the stream server. May fire a [Stream Server Update](#stream-server-update) Gateway event.
Requires `voice` scope when operating in an OAuth2 context.
###### Ping Stream Server Structure
| Field | Type | Description |
| ---------- | ------ | ------------------------------------- |
| stream_key | string | The [stream key](#stream-key) to ping |
###### Example Ping Stream Server
```json
{
"op": 21,
"d": {
"stream_key": "call:1110739331624210483:852892297661906993"
}
}
```
#### Update Lobby Voice States
Sent by the client to update the user's voice state in multiple lobbies. Fires a [Lobby Voice State Update](#lobby-voice-state-update) and optionally [Lobby Voice Server Update](#lobby-voice-server-update) Gateway event.
Requires `lobbies.write` scope when operating in an OAuth2 context.
The inner `d` key is an array of the following objects:
###### Update Lobby Voice State Structure
| Field | Type | Description |
| ------------------ | ------------- | ----------------------------------------------------------------------------------- |
| lobby_id | snowflake | The ID of the lobby |
| self_mute | boolean | Whether the client is muted |
| self_deaf | boolean | Whether the client is deafened |
| self_video? | boolean | Whether the client is streaming video to the channel |
| preferred_region? | ?string | The preferred [voice region](/resources/voice#voice-region-object) ID for the lobby |
| preferred_regions? | array[string] | The ranked [voice region](/resources/voice#voice-region-object) IDs for the lobby |
#### Ping Lobby Voice Server
Sent when a client wants to request that the Gateway pings a misbehaving lobby voice server. This will force a check server-side and potentially reallocate the lobby voice server. May fire a [Lobby Voice Server Update](#lobby-voice-server-update) Gateway event.
###### Ping Lobby Voice Server Structure
| Field | Type | Description |
| -------- | --------- | --------------------------- |
| lobby_id | snowflake | The ID of the lobby to ping |
#### Request Guild Members
Used to request all members for a guild or a list of guilds. When initially connecting, only a subset of members are provided. If a client wishes to receive additional members, they need to explicitly request them via this operation.
Fires multiple [Guild Members Chunk](#guild-members-chunk) events with up to 1000 members per chunk until all members that match the request have been sent.
Due to privacy and infrastructural concerns with this feature, there are some limitations that apply:
- For bots, the `GUILD_PRESENCES` privileged intent is required to request presences
- For bots, the `GUILD_MEMBERS` privileged intent is required to request the entire member list (query of "" and limit of 0)
- For users, the `MANAGE_ROLES`, `KICK_MEMBERS`, or `BAN_MEMBERS` permissions are required to request the entire member list (query of "" and limit of 0)
- For bots, only one guild ID may be requested at a time
- Requesting a prefix (`query` parameter) will return a maximum of 100 members
- `user_ids` is limited to 100 members
###### Request Guild Members Structure
| Field | Type | Description |
| ------------- | ----------------------------- | ----------------------------------------------------------------------------------------------- |
| guild_id | snowflake \| array[snowflake] | ID(s) of the guild(s) to get members for |
| query? ^1^ | string | String that the username/nickname starts with, or an empty string to return all members |
| limit? ^2^ | integer | Maximum number of members to send matching the `query` (0-100, must be 0 with an empty `query`) |
| presences? | boolean | Whether the presence of matched members will be returned |
| user_ids? ^1^ | snowflake \| array[snowflake] | The user IDs to request (max 100) |
| nonce? ^3^ | string | Nonce to identify the [Guild Members Chunk](#guild-members-chunk) response (max 32 bytes) |
^1^ One of `query` or `user_ids` is required.
^2^ Required when specifying `query`.
^3^ If you send an invalid nonce, it will be ignored, and the reply member chunk(s) will not have a nonce set.
###### Example Request Guild Members
```json
{
"op": 8,
"d": {
"guild_id": ["41771983444115456"],
"query": "",
"limit": 0
}
}
```
#### Request Call Connect
Used to request a private channel's pre-existing call data, created before the Gateway connection was established. Fires a [Call Create](#call-create) Gateway event if a call is found.
Requires `dm_channels.read` and `voice` scopes if operating in OAuth2 context.
When using the `AUTO_CALL_CONNECT` [Gateway capability](/gateway/using-gateway#gateway-capabilities), it is no longer necessary to explicitly request a call connect. Instead, the client will automatically receive [Call Create](#call-create) events for pre-existing calls upon connecting to the Gateway.
###### Request Call Connect Structure
| Field | Type | Description |
| ---------- | --------- | -------------------------------- |
| channel_id | snowflake | ID of the DM or group DM channel |
###### Example Request Call Connect
```json
{
"op": 13,
"d": {
"channel_id": "957057010334048288"
}
}
```
#### Remote Command (Send)
Used to send a message to another Gateway session. Typically, this is used to control embedded sessions, such as an Xbox or PlayStation session. Fires a [Remote Command](<#remote-command-(receive)>) Gateway event on the target session.
###### Remote Command Structure
| Field | Type | Description |
| ----------------- | ------ | ---------------------------- |
| target_session_id | string | ID of the session to send to |
| payload ^1^ | any | The payload to send |
^1^ The sent payload is not standardized or validated by the server.
###### Example Remote Command
```json
{
"op": 29,
"d": {
"target_session_id": "30f32c5d54ae86130fc4a215c7474263",
"payload": {
"type": "VOICE_STATE_UPDATE",
"self_mute": false,
"self_deaf": false
}
}
}
```
#### Get Deleted Entity IDs Not Matching Hash
Used to request currently existing entity IDs from a guild. User must be a member of the guild. Fires a [Deleted Entity IDs](#deleted-entity-ids) Gateway event.
###### Get Deleted Entity IDs Not Matching Hash Structure
| Field | Type | Description |
| -------------------- | --------- | --------------------------- |
| guild_id | snowflake | The ID of the guild |
| channel_ids_hash ^1^ | string | The hash of all channel IDs |
| role_ids_hash ^1^ | string | The hash of all role IDs |
| emoji_ids_hash ^1^ | string | The hash of all emoji IDs |
| sticker_ids_hash ^1^ | string | The hash of all sticker IDs |
^1^ The values are 32-bit unsigned Murmur3 hashed representations of snowflake arrays, sorted in ascending order and joined by `,`.
#### Request Soundboard Sounds
Used to request soundboard sounds for a list of guilds. Fires a [Soundboard Sounds](#soundboard-sounds) Gateway event for every guild in response.
###### Request Soundboard Sounds Structure
| Field | Type | Description |
| --------- | ---------------- | -------------------------------------------------- |
| guild_ids | array[snowflake] | The IDs of the guilds to get soundboard sounds for |
###### Example Request Soundboard Sounds
```json
{
"op": 31,
"d": {
"guild_ids": ["41771983444115456", "1015060230222131221", "811255666990907402"]
}
}
```
#### Create Speed Test
Used to create an RTC speed test for the client. If the client already has an active speed test, this will update it. Fires a [Speed Test Create](#speed-test-create) and [Speed Test Server Update](#speed-test-server-update) or [Speed Test Update](#speed-test-update) Gateway event.
###### Create Speed Test Structure
| Field | Type | Description |
| ----------------- | ------- | ---------------------------------------------------------------------------------------- |
| preferred_region? | ?string | The preferred [voice region](/resources/voice#voice-region-object) ID for the speed test |
###### Example Create Speed Test
```json
{
"op": 32,
"d": {
"preferred_region": "us-east"
}
}
```
#### Delete Speed Test
Used to delete the client's RTC speed test. Fires a [Speed Test Delete](#speed-test-delete) Gateway event.
###### Example Delete Speed Test
```json
{
"op": 33,
"d": null
}
```
#### Request Last Messages
Used to request the last messages (indicated by the [`last_message_id` field](/resources/channel#channel-object)) from channels. User must be a member of the guild. Fires a [Last Messages](#last-messages) Gateway event with up to 100 messages that match the request.
###### Request Last Messages Structure
| Field | Type | Description |
| ----------- | ---------------- | -------------------------------------------------------------- |
| guild_id | snowflake | The ID of the guild |
| channel_ids | array[snowflake] | The IDs of the channels to request last messages for (max 100) |
###### Example Request Last Messages
```json
{
"op": 34,
"d": {
"guild_id": "957057010334048288",
"channel_ids": ["1145501524013895733", "1145501524013895734"]
}
}
```
#### Search Recent Members
Used to search the 10,000 most recently joined members in a guild. User must be a member of the guild. Fires a [Guild Members Chunk](#guild-members-chunk) Gateway event with up to 1000 members that match the request.
###### Search Recent Members Structure
| Field | Type | Description |
| ---------------------- | ---------- | --------------------------------------------------------------------------------------- |
| guild_id | snowflake | The ID of the guild to search members for |
| query ^1^ | string | String that the username/nickname starts with, or an empty string to return all members |
| continuation_token ^2^ | ?snowflake | The member ID to continue pagination from |
| nonce? ^3^ | string | Nonce to identify the [Guild Members Chunk](#guild-members-chunk) response |
^1^ When a query is provided, results are limited to one member.
^2^ Pagination is based on the [`joined_at`](/resources/guild#guild-member-object) field descending. To paginate, you provide the member ID of the member that joined the earliest in the previously received [Guild Members Chunk](#guild-members-chunk). You can only paginate up to 10,000 members back from the most recently joined member.
^3^ The nonce can only be up to 32 bytes. If you send an invalid nonce, it will be ignored, and the reply member chunk will not have a nonce set.
###### Example Search Recent Members
```json
{
"op": 35,
"d": {
"guild_id": "957057010334048288",
"query": "",
"continuation_token": null
}
}
```
#### Resync Guild Channels
Used to request channels for a guild. Fires a [Channel Sync](#channel-sync) Gateway event with the requested channels.
###### Resync Guild Channels Structure
| Field | Type | Description |
| ---------------------- | ---------------- | -------------------------- |
| guild_id | snowflake | The ID of the guild |
| obfuscated_channel_ids | array[snowflake] | The channel IDs to request |
```json
{
"op": 38,
"d": {
"guild_id": "957057010334048288",
"obfuscated_channel_ids": ["1142105002492575794"]
}
}
```
#### Request Channel Statuses
Used to request the voice channel statuses for a guild. Fires a [Channel Statuses](#channel-statuses) Gateway event with the requested statuses.
###### Request Channel Statuses Structure
| Field | Type | Description |
| -------- | --------- | ------------------- |
| guild_id | snowflake | The ID of the guild |
###### Example Request Channel Statuses
```json
{
"op": 36,
"d": {
"guild_id": "957057010334048288"
}
}
```
#### Request Channel Member Count
Used to request the number of members that can view a guild channel, as well as how many are online at the given time. Requires the `VIEW_CHANNEL` permission in the given channel. Fires a [Channel Member Count Update](#channel-member-count-update) Gateway event with the requested count.
###### Request Channel Member Count Structure
| Field | Type | Description |
| ---------- | --------- | --------------------- |
| guild_id | snowflake | The ID of the guild |
| channel_id | snowflake | The ID of the channel |
###### Example Request Channel Member Count
```json
{
"op": 39,
"d": {
"guild_id": "957057010334048288",
"channel_id": "1145501524013895733"
}
}
```
#### Request Channel Info
Used to request a number of extra fields for a guilds' channels. Fires a [Channel Info](#channel-info) Gateway event with the requested information.
###### Request Channel Info Structure
| Field | Type | Description |
| -------- | ------------- | --------------------------------------------- |
| guild_id | snowflake | The ID of the guild |
| fields | array[string] | The [fields](#channel-info-fields) to request |
###### Channel Info Fields
| Name | Description |
| ---------------- | ---------------------------------------------------- |
| status | The status of the voice channel |
| voice_start_time | The start time of the voice channel's active session |
## Receive Events
Received events are Gateway events encapsulated in an [event payload](#gateway-payload-structure), and are sent by Discord to a client through a Gateway connection. Most received events correspond to dispatch events that happen relevant to the current user and the guilds it is a member of.
| Name | Description |
| ----------------------------------- | -------------------------------------------------------------------------------------------------------------------- |
| [Hello](#hello) | Defines the heartbeat interval |
| [Heartbeat ACK](#heartbeat-ack) | Acknowledges a received client heartbeat |
| [Reconnect](#reconnect) | Indicates the server is going away, client should reconnect to Gateway and [resume](/gateway/using-gateway#resuming) |
| [Invalid Session](#invalid-session) | Failure response to [Identify](#identify) or [Resume](#resume), or indicates an invalid active session |
| [Dispatch](#dispatch-events) | Dispatches an event to the client |
#### Hello
Sent on connection to the WebSocket. Defines the heartbeat interval that the client should heartbeat to.
###### Hello Structure
| Field | Type | Description |
| ------------------ | ------------- | ----------------------------------------------------------------------------------------- |
| \_trace | array[string] | An array of stringified JSON values representing the connection trace, used for debugging |
| heartbeat_interval | integer | The interval (in milliseconds) the client should heartbeat at |
###### Example Hello
```json
{
"op": 10,
"d": {
"heartbeat_interval": 41250,
"_trace": ["[\"gateway-prd-us-east1-c-6w69\",{\"micros\":0.0}]"]
},
"s": null,
"t": null
}
```
#### Heartbeat ACK
Sent in response to receiving a heartbeat to acknowledge that it has been received.
Details about heartbeats are in the [Gateway documentation](/gateway/using-gateway#sending-heartbeats).
###### Example Heartbeat ACK
```json
{
"op": 11,
"d": null,
"s": null,
"t": null
}
```
#### Reconnect
The reconnect event is dispatched when a client should reconnect to the Gateway (and resume their existing session, if they have one). This event usually occurs during deploys to migrate sessions gracefully off old hosts.
###### Example Reconnect
```json
{
"op": 7,
"d": null,
"s": null,
"t": null
}
```
#### Invalid Session
Sent to indicate one of at least three different situations:
- The Gateway could not initialize a session after receiving an [Opcode 2 Identify](#identify)
- The Gateway could not resume a previous session after receiving an [Opcode 6 Resume](#resume)
- The Gateway has invalidated an active session and is requesting client action
The inner `d` key is a boolean that indicates whether the session may be resumable. See [Connecting](/gateway/using-gateway#connecting) and [Resuming](/gateway/using-gateway#resuming) for more information.
Note that unless the Gateway closes the connection, this event does not signify that the client needs to start a new WebSocket conneciton.
The client can continue using the existing connection when following the [Connecting](/gateway/using-gateway#connecting) or [Resuming](/gateway/using-gateway#resuming) flow.
###### Example Invalid Session
```json
{
"op": 9,
"d": false,
"s": null,
"t": null
}
```
## Dispatch Events
These events directly correspond with a specific action or state change that has occurred in the platform.
| Name | Description |
| ------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------- |
| [Ready](#ready) | Initial state information |
| [Ready Supplemental](#ready-supplemental) | Supplemental information for the initial state, not critical to beginning use of the platform |
| [Resumed](#resumed) | Acknowledges a successful [Resume](#resume) |
| [Rate Limited](#rate-limited) | Client has hit a rate limit for a specific operation |
| [Remote Command](<#remote-command-(receive)>) | Received a message from another Gateway session |
| [Activity Invite Create](#activity-invite-create) | Activity invite was created |
| [Auth Session Change](#auth-session-change) | Current session's associated auth session ID changed |
| [Authenticator Create](#authenticator-create) | WebAuthn authenticator was created |
| [Authenticator Update](#authenticator-update) | WebAuthn authenticator was updated |
| [Authenticator Delete](#authenticator-delete) | WebAuthn authenticator was deleted |
| [Application Command Permissions Update](#application-command-permissions-update) | Application command permissions were updated |
| [Auto Moderation Rule Create](#auto-moderation-rule-create) | AutoMod rule was created |
| [Auto Moderation Rule Update](#auto-moderation-rule-update) | AutoMod rule was updated |
| [Auto Moderation Rule Delete](#auto-moderation-rule-delete) | AutoMod rule was deleted |
| [Auto Moderation Action Execution](#auto-moderation-action-execution) | AutoMod rule was triggered and an action was executed (e.g. a message was blocked) |
| [Auto Moderation Mention Raid Detection](#auto-moderation-mention-raid-detection) | AutoMod mention raid incident was detected |
| [Billing Popup Bridge Callback](#billing-popup-bridge-callback) | Billing popup bridge callback was received |
| [Call Create](#call-create) | Private channel call was created |
| [Call Update](#call-update) | Private channel call was updated |
| [Call Delete](#call-delete) | Private channel call was deleted |
| [Channel Create](#channel-create) | Channel was created |
| [Channel Update](#channel-update) | Channel was updated |
| [Channel Delete](#channel-delete) | Channel was deleted |
| [Channel Sync](#channel-sync) | Response to [Resync Guild Channels](#resync-guild-channels) |
| [Channel Update Partial](#channel-update-partial) | Channel was partially updated |
| [Channel Statuses](#channel-statuses) | Response to [Request Channel Statuses](#request-channel-statuses) |
| [Channel Info](#channel-info) | Response to [Request Channel Info](#request-channel-info) |
| [Channel Member Count Update](#channel-member-count-update) | Response to [Request Channel Member Count](#request-channel-member-count) |
| [Channel Unread Update](#channel-unread-update) | Guild channel unread state was updated |
| [Channel Pins Update](#channel-pins-update) | Message was pinned or unpinned |
| [Channel Pins Ack](#channel-pins-ack) | Channel pins read state was updated |
| [Channel Recipient Add](#channel-recipient-add) | User joined a group DM channel |
| [Channel Recipient Remove](#channel-recipient-remove) | User was removed from a group DM channel |
| [Console Command Update](#console-command-update) | Console command was updated |
| [Conversation Summary Update](#conversation-summary-update) | Conversation summaries were updated for a text channel |
| [Creator Monetization Restrictions Update](#creator-monetization-restrictions-update) | Guild creator monetization restrictions were updated |
| [Deleted Entity IDs](#deleted-entity-ids) | Response to [Get Deleted Entity IDs Not Matching Hash](#get-deleted-entity-ids-not-matching-hash) |
| [DM Settings Upsell Show](#dm-settings-upsell-show) | DM privacy settings upsell modal was triggered |
| [Thread Create](#thread-create) | Thread was created, also sent when being added to a private thread |
| [Thread Update](#thread-update) | Thread was updated |
| [Thread Delete](#thread-delete) | Thread was deleted |
| [Thread List Sync](#thread-list-sync) | Sent when gaining access to a channel, contains all active threads in that channel |
| [Thread Member Update](#thread-member-update) | [Thread member](/resources/channel#thread-member-object) for the current user was updated |
| [Thread Members Update](#thread-members-update) | User(s) were added to or removed from a thread |
| [Embedded Activity Update V2](#embedded-activity-update-v2) | Embedded activity was created, updated, or deleted |
| [Entitlement Create](#entitlement-create) | Entitlement was created |
| [Entitlement Update](#entitlement-update) | Entitlement was updated |
| [Entitlement Delete](#entitlement-delete) | Entitlement was deleted |
| [Experiment Session Override Create](#experiment-session-override-create) | Apex experiment override was created |
| [Experiment Session Override Delete](#experiment-session-override-delete) | Apex experiment override was deleted |
| [Friend Suggestion Create](#friend-suggestion-create) | Friend suggestion was created |
| [Friend Suggestion Delete](#friend-suggestion-delete) | Friend suggestion was deleted |
| [Game Server Create](#game-server-create) | Guild game server was created |
| [Game Server Update](#game-server-update) | Guild game server was updated |
| [Game Server Delete](#game-server-delete) | Guild game server was deleted |
| [Gift Code Create](#gift-code-create) | Gift code was created |
| [Gift Code Update](#gift-code-update) | Gift code was updated |
| [Guild Create](#guild-create) | Guild became available or user joined a new guild |
| [Guild Update](#guild-update) | Guild was updated |
| [Guild Delete](#guild-delete) | Guild became unavailable, or user left/was removed from a guild |
| [Guild Application Command Index Update](#guild-application-command-index-update) | Application command index was updated for a guild |
| [Guild Applied Boosts Update](#guild-applied-boosts-update) | Premium guild subscription was created or updated |
| [Guild Audit Log Entry Create](#guild-audit-log-entry-create) | Guild audit log entry was created |
| [Guild Ban Add](#guild-ban-add) | User was banned from a guild |
| [Guild Ban Remove](#guild-ban-remove) | User was unbanned from a guild |
| [Guild Bulk Ban Update](#guild-bulk-ban-update) | Guild finished processing a bulk-ban operation performed by the user |
| [Guild Directory Entry Create](#guild-directory-entry-create) | Guild directory entry was created |
| [Guild Directory Entry Update](#guild-directory-entry-update) | Guild directory entry was updated |
| [Guild Directory Entry Delete](#guild-directory-entry-delete) | Guild directory entry was deleted |
| [Guild Emojis Update](#guild-emojis-update) | Guild emoji were updated |
| [Guild Stickers Update](#guild-stickers-update) | Guild stickers were updated |
| [Guild Feature Ack](#guild-feature-ack) | Guild feature read state was updated |
| [Guild Join Request Create](#guild-join-request-create) | Guild join request was created |
| [Guild Join Request Update](#guild-join-request-update) | Guild join request was updated |
| [Guild Join Request Delete](#guild-join-request-delete) | Guild join request was deleted |
| [Guild Member Add](#guild-member-add) | User joined a guild |
| [Guild Member Update](#guild-member-update) | Guild member was updated |
| [Guild Member Remove](#guild-member-remove) | User was removed from a guild |
| [Guild Members Chunk](#guild-members-chunk) | Response to [Request Guild Members](#request-guild-members) |
| [Guild Official Game Applications Update](#guild-official-game-applications-update) | Guild game applications were updated |
| [Guild Powerup Entitlements Create](#guild-powerup-entitlements-create) | Guild powerups were added |
| [Guild Powerup Entitlements Delete](#guild-powerup-entitlements-delete) | Guild powerups were removed |
| [Guild Role Create](#guild-role-create) | Guild role was created |
| [Guild Role Update](#guild-role-update) | Guild role was updated |
| [Guild Role Delete](#guild-role-delete) | Guild role was deleted |
| [Guild Scheduled Event Create](#guild-scheduled-event-create) | Guild scheduled event was created |
| [Guild Scheduled Event Update](#guild-scheduled-event-update) | Guild scheduled event was updated |
| [Guild Scheduled Event Delete](#guild-scheduled-event-delete) | Guild scheduled event was deleted |
| [Guild Scheduled Event Exception Create](#guild-scheduled-event-exception-create) | Guild scheduled event exception was created |
| [Guild Scheduled Event Exception Update](#guild-scheduled-event-exception-update) | Guild scheduled event exception was updated |
| [Guild Scheduled Event Exception Delete](#guild-scheduled-event-exception-delete) | Guild scheduled event exception was deleted |
| [Guild Scheduled Event Exceptions Delete](#guild-scheduled-event-exceptions-delete) | All guild scheduled event exceptions were deleted |
| [Guild Scheduled Event User Add](#guild-scheduled-event-user-add) | User subscribed to a guild scheduled event or exception |
| [Guild Scheduled Event User Remove](#guild-scheduled-event-user-remove) | User unsubscribed from a guild scheduled event or exception |
| [Guild Soundboard Sound Create](#guild-soundboard-sound-create) | Guild soundboard sound was created |
| [Guild Soundboard Sound Update](#guild-soundboard-sound-update) | Guild soundboard sound was updated |
| [Guild Soundboard Sound Delete](#guild-soundboard-sound-delete) | Guild soundboard sound was deleted |
| [Guild Soundboard Sounds Update](#guild-soundboard-sound-update) | Guild soundboard sounds were updated |
| [Soundboard Sounds](#soundboard-sounds) | Response to [Request Soundboard Sounds](#request-soundboard-sounds) |
| [Guild Integrations Update](#guild-integrations-update) | Guild integration was updated |
| [Integration Create](#integration-create) | Guild integration was created |
| [Integration Update](#integration-update) | Guild integration was updated |
| [Integration Delete](#integration-delete) | Guild integration was deleted |
| [Interaction Create](#interaction-create) | User used an interaction, such as an [Application Command](/interactions/application-commands) |
| [Interaction Failure](#interaction-failure) | Interaction failed |
| [Interaction Success](#interaction-success) | Interaction succeeded |
| [Application Command Autocomplete Response](#application-command-autocomplete-response) | Application responded to autocomplete interaction |
| [Interaction Modal Create](#interaction-modal-create) | Application responded with a modal |
| [Interaction IFrame Modal Create](#interaction-iframe-modal-create) | Application responded with an iframe modal |
| [Social Layer SKU Purchase Eligibility Response](#social-layer-sku-purchase-eligibility-response) | Application responded to social layer SKU purchase eligibility interaction |
| [Invite Create](#invite-create) | Guild invite to a channel was created |
| [Invite Delete](#invite-delete) | Guild invite to a channel was deleted |
| [Message Create](#message-create) | Message was created |
| [Message Update](#message-update) | Message was edited |
| [Message Delete](#message-delete) | Message was deleted |
| [Message Delete Bulk](#message-delete-bulk) | Multiple messages were deleted at once |
| [Message Ack](#message-ack) | Channel read state was updated |
| [Message Poll Vote Add](#message-poll-vote-add) | User voted on a poll |
| [Message Poll Vote Remove](#message-poll-vote-remove) | User removed a vote on a poll |
| [Message Reaction Add](#message-reaction-add) | User reacted to a message |
| [Message Reaction Add Many](#message-reaction-add-many) | Many users reacted to a message |
| [Message Reaction Remove](#message-reaction-remove) | User removed a reaction from a message |
| [Message Reaction Remove All](#message-reaction-remove-all) | All reactions were explicitly removed from a message |
| [Message Reaction Remove Emoji](#message-reaction-remove-emoji) | All reactions for a given emoji were explicitly removed from a message |
| [Reaction Notification Sent](#reaction-notification-sent) | User reacted to a message authored by the current user |
| [Recent Mention Delete](#recent-mention-delete) | Recent message that mentioned the current user was acknowledged |
| [Last Messages](#last-messages) | Response to [Request Last Messages](#request-last-messages) |
| [Notification Center Item Create](#notification-center-item-create) | Notification center item was created |
| [Notification Center Item Delete](#notification-center-item-delete) | Notification center item was deleted |
| [Notification Center Items Ack](#notification-center-items-ack) | Notification center item was acknowledged |
| [Notification Center Item Completed](#notification-center-item-completed) | Notification center item of a certain action type was completed |
| [Notification Settings Update](#notification-settings-update) | User notification settings were updated |
| [OAuth2 Token Create](#oauth2-token-create) | OAuth2 authorization was created |
| [OAuth2 Token Delete](#oauth2-token-delete) | OAuth2 authorization was deleted |
| [OAuth2 Token Revoke](#oauth2-token-revoke) | OAuth2 token was revoked |
| [Payment Update](#payment-update) | User had a payment updated |
| [Presence Update](#presence-update) | User presence was updated |
| [Quests User Status Update](#quests-user-status-update) | User status in a quest was updated |
| [Quests User Completion Update](#quests-user-completion-update) | User quest completion eligibility was updated |
| [Relationship Add](#relationship-add) | User had a relationship added |
| [Relationship Update](#relationship-update) | User had a relationship updated |
| [Relationship Remove](#relationship-remove) | User had a relationship removed |
| [Game Invite Create](#game-invite-create) | User had a game invite received |
| [Game Invite Delete](#game-invite-delete) | User had a game invite deleted |
| [Game Invite Delete Many](#game-invite-delete-many) | User had some game invites deleted |
| [Game Relationship Add](#game-relationship-add) | User had a game relationship added |
| [Game Relationship Remove](#game-relationship-remove) | User had a game relationship removed |
| [Lobby Create](#lobby-create) | Lobby was created |
| [Lobby Update](#lobby-update) | Lobby was updated |
| [Lobby Delete](#lobby-delete) | Lobby was deleted |
| [Lobby Member Add](#lobby-member-add) | User was added to a lobby |
| [Lobby Member Update](#lobby-member-update) | Lobby member was updated |
| [Lobby Member Remove](#lobby-member-remove) | User was removed from a lobby |
| [Lobby Message Create](#lobby-message-create) | Message was created in a lobby |
| [Lobby Message Update](#lobby-message-update) | Message was updated in a lobby |
| [Lobby Message Delete](#lobby-message-delete) | Message was deleted in a lobby |
| [Lobby Voice State Update](#lobby-voice-state-update) | User joined, left, or moved lobbies |
| [Lobby Voice Server Update](#lobby-voice-server-update) | Lobby voice connection server was updated |
| [Passive Update V1](#passive-update-v1) | Guild channel unreads and voice state were updated |
| [Passive Update V2](#passive-update-v2) | Guild channel unreads and voice state were updated |
| [Saved Message Create](#saved-message-create) | Message was bookmarked |
| [Saved Message Delete](#saved-message-delete) | Bookmarked message was deleted |
| [Sessions Replace](#sessions-replace) | User session list was updated |
| [Stage Instance Create](#stage-instance-create) | Stage instance was created |
| [Stage Instance Update](#stage-instance-update) | Stage instance was updated |
| [Stage Instance Delete](#stage-instance-delete) | Stage instance was deleted or closed |
| [Stream Create](#stream-create) | Stream was created |
| [Stream Server Update](#stream-server-update) | Stream server was updated |
| [Stream Update](#stream-update) | Stream was updated |
| [Stream Delete](#stream-delete) | Stream was deleted |
| [Speed Test Create](#speed-test-create) | RTC speed test was created |
| [Speed Test Server Update](#speed-test-server-update) | RTC speed test server was updated |
| [Speed Test Update](#speed-test-update) | RTC speed test was updated |
| [Speed Test Delete](#speed-test-delete) | RTC speed test was deleted |
| [Typing Start](#typing-start) | User started typing in a channel |
| [User Update](#user-update) | Current user changed |
| [User Application Update](#user-application-update) | User installed an application or an application was updated |
| [User Application Remove](#user-application-remove) | User uninstalled an application |
| [User Application Identity Update](#user-application-identity-update) | Application identity is updated for the current user |
| [User Application Identity Remove](#user-application-identity-remove) | Application identity is removed for the current user |
| [User Connections Update](#user-connections-update) | User connection was created, updated, or deleted |
| [User Guild Settings Update](#user-guild-settings-update) | User guild settings were updated |
| [User Merge Operation Completed](#user-merge-operation-completed) | User has been merged with a provisional account |
| [User Non Channel Ack](#user-non-channel-ack) | User feature read state was updated |
| [User Note Update](#user-note-update) | User note was updated |
| [User Payment Browser Checkout Done](#user-payment-browser-checkout-done) | User finished checking out a purchase in-browser |
| [User Payment Client Add](#user-payment-client-add) | User had a payment client authorized |
| [User Payment Sources Update](#user-payment-sources-update) | User payment sources were updated |
| [User Subscriptions Update](#user-subscriptions-update) | User subscriptions were updated |
| [User Premium Guild Subscription Slot Create](#user-premium-guild-subscription-slot-create) | User premium guild subscription slot was created |
| [User Premium Guild Subscription Slot Update](#user-premium-guild-subscription-slot-update) | User premium guild subscription slot was updated |
| [User Premium Guild Subscription Slot Delete](#user-premium-guild-subscription-slot-delete) | User premium guild subscription slot was deleted |
| [User Required Action Update](#user-required-action-update) | User's required action was updated |
| [User Settings Update](#user-settings-update) | User settings were updated |
| [Audio Settings Update](#audio-settings-update) | Audio settings were updated |
| [Voice State Update](#voice-state-update) | User joined, left, or moved a voice channel |
| [Voice Server Update](#voice-server-update) | Voice connection server was updated |
| [Voice Channel Effect Send](#voice-channel-effect-send) | User sent an effect in a voice channel the current user is connected to |
| [Voice Channel Start Time Update](#voice-channel-start-time-update) | Voice channel start time was updated |
| [Voice Channel Status Update](#voice-channel-status-update) | Voice channel status was updated |
| [Virtual Currency Balance Update](#virtual-currency-balance-update) | User's Orbs balance was updated |
| [Webhooks Update](#webhooks-update) | Channel webhook was created, update, or deleted |
#### Initial Guild
Sent before [Ready](#ready). The inner payload is a [gateway guild](#gateway-guild-object) object.
This event requires the `initial_guild_id` field to be specified in [client state](#client-state-structure) object while identifying.
#### Ready
Sent when a client has completed the initial handshake with the Gateway (for new sessions). The Ready event is the largest and most complex event the Gateway will send, as it contains all the state required for a client to begin interacting with the rest of the platform.
###### Ready Structure
| Field | Type | Description |
| ----------------------------------------- | -------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| \_trace | array[string] | An array of stringified JSON values representing the connection trace, used for debugging |
| v | integer | [API version](/reference#api-versions) |
| user | [user](/resources/user#user-object) object | The connected user |
| user_settings ^1^ ^4^ **(deprecated)** | [user settings](/resources/user-settings#user-settings-object) object | The client settings for the user |
| user_settings_proto ^1^ | string | The base64-encoded serialized [preloaded user settings](/resources/user-settings-proto#preloaded-user-settings-object) protobuf for the user, (if missing, defaults should be used) |
| notification_settings ^1^ | [notification settings](/resources/user-settings#notification-settings-object) object | The notification settings for the user |
| user_guild_settings ^1^ ^9^ | [versioned array](#versioned-structure)[[user guild settings](/resources/user-settings#user-guild-settings-object) object] | The user settings for each guild |
| read_state ^1^ ^10^ | [versioned array](#versioned-structure)[[read state](/topics/read-state#read-state-object) object] | The user read states |
| guilds ^2^ ^6^ | array[[gateway guild](#gateway-guild-object) object] | The guilds the user is in |
| guild_join_requests ^1^ | array[partial [guild join request](/resources/guild#guild-join-request-object)] | Active guild join requests the user has |
| relationships ^1^ | array[[relationship](/resources/relationships#relationship-object)] | The relationships the user has with other users |
| game_relationships ^1^ | array[[game relationship](/resources/relationships#game-relationship-object)] | The game relationships the user has with other users |
| friend_suggestion_count? ^1^ | integer | The number of friend suggestions the user has |
| private_channels ^1^ ^13^ | array[[channel](/resources/channel#channel-object) object] | The DMs and group DMs the user is participating in |
| connected_accounts | array[[connection](/resources/connected-accounts#connection-object)] | The third-party accounts the user has linked |
| notes ^1^ ^5^ | map[snowflake, string] | A mapping of user IDs to notes the user has made for them |
| presences ^6^ | array[[presence](/resources/presence#presence-object) object] | The presences of the user's non-offline [friends and implicit relationships](/resources/relationships#relationship-object) (depending on the `NO_AFFINE_USER_IDS` [Gateway capability](/gateway/using-gateway#gateway-capabilities)) |
| merged_presences ^6^ ^7^ | [merged presences](#merged-presences-structure) object | The presences of the user's non-offline [friends and implicit relationships](/resources/relationships#relationship-object) (depending on the `NO_AFFINE_USER_IDS` [Gateway capability](/gateway/using-gateway#gateway-capabilities)), and any guild presences sent at startup |
| merged_members ^6^ ^7^ | array[array[[guild member](/resources/guild#guild-member-object) object]] | Initial members for each of the user's guilds, in the same order as the `guilds` array |
| users ^6^ | array[partial [user](/resources/user#user-object) object] | The deduped users across all objects in the event |
| linked_users ^1^ | array[[linked user](/resources/family-center#linked-user-object) object] | The linked users connected to the account via [Family Center](/resources/family-center) |
| application? | [gateway application](#gateway-application-structure) object | The application of the connected bot or OAuth2 application |
| scopes? ^11^ | array[string] | The [OAuth2 scopes](/topics/oauth2#oauth2-scopes) the user has authorized for the application |
| session_id | string | Unique session ID, used for resuming connections |
| session_type | string | The [type of session](#session-type) that was started |
| sessions ^1^ | array[[session](/resources/presence#session-object) object] | The sessions that are currently active for the user |
| static_client_session_id | string | A unique identifier for the client session, used for persistent DAVE public keys |
| auth_session_id_hash ^1^ | string | The hash of the auth session ID corresponding to the auth token used to connect |
| auth_token? ^1^ ^3^ | string | The refreshed auth token for this user; if present, the client should discard the current auth token and use this in subsequent requests to the API |
| analytics_token ^1^ | string | The token used for analytical tracking requests |
| auth ^1^ | [gateway auth](#gateway-auth-structure) object | Authentication information for the session |
| required_action? ^1^ | string | The [action a user is required to take](/resources/user#required-action-type) before continuing to use Discord |
| country_code ^1^ | string | The detected [ISO 3166-1 alpha-2](https://en.wikipedia.org/wiki/ISO_3166-1_alpha-2) country code of the user's current IP address |
| geo_ordered_rtc_regions | array[string] | A geo-ordered list of [RTC regions](/resources/voice#voice-region-object) that can be used when when setting a voice channel's [`rtc_region`](/resources/channel#channel-object) or [updating the client's voice state](#update-voice-state) |
| consents ^1^ | [consents](/resources/user-settings#consents-object) | The tracking features the user has consented to |
| tutorial ^1^ ^8^ | ?[tutorial](#tutorial-structure) object | The tutorial state of the user, if any |
| shard? | array[integer, integer] | The [shard information](/gateway/using-gateway#sharding) (shard_id, num_shards) associated with this session, if sharded |
| resume_gateway_url | string | WebSocket URL for resuming connections |
| api_code_version ^1^ | integer | The API code version, used when re-identifying with client state v2 |
| experiments ^1^ | array[[user experiment](/topics/experiments#user-experiments) object] | User experiment rollouts for the user |
| guild_experiments ^1^ | array[[guild experiment](/topics/experiments#guild-experiments) object] | Guild experiment rollouts for the user |
| apex_experiments? ^1^ | [apex experiments](/topics/experiments#apex-experiments) object | Apex experiment assignments for the `APP` surface |
| explicit_content_scan_version | integer | The latest version of the explicit content scan filter feature |
| pending_payments? | ?array[[payment](/resources/payment#payment-object) object] | The pending payments |
| av_sf_protocol_floor? ^11^ | integer | The minimum supported version of the DAVE protocol in eligible voice connection |
| feature_flags? ^11^ | [gateway feature flags](#gateway-feature-flags-structure) object | Social layer SDK feature flags |
| lobbies? ^11^ ^12^ | array[[lobby](/resources/lobby#lobby-object) object] | The lobbies the connected user is in |
| user_application_profiles? ^11^ | map[snowflake, array[[user application profile](#user-application-profile-structure) object]] | A mapping of user IDs to provisional user accounts application profiles encountered across all objects in the event |
| connection_request_data? ^11^ | [console connection request data](#console-connection-request-data-structure) object | Pending connection request data |
| ad_personalization_toggles_disabled ^1^ | boolean | Whether personalization toggles for quests are disabled |
| broadcaster_user_ids **(deprecated)** ^1^ | array[snowflake] | IDs of users currently broadcasting |
| regional_feature_config ^1^ | [regional feature config](#regional-feature-config-object) object | Defines which features are enabled or restricted based on the geographic region of the connecting client |
^1^ Feature is not available to or not tracked for bots. This field may be empty, omitted, or `null`.
^2^ For bots, guilds start out as unavailable when they connect to the Gateway. As they become available, the bot will be notified via [Guild Create](#guild-create) events. Note that for users, guilds that are experiencing an outage or are geo-restricted will still be sent as unavailable.
^3^ Requires the `AUTH_TOKEN_REFRESH` [Gateway capability](/gateway/using-gateway#gateway-capabilities).
^4^ Omitted when using the `USER_SETTINGS_PROTO` [Gateway capability](/gateway/using-gateway#gateway-capabilities).
^5^ Omitted when using the `LAZY_USER_NOTES` [Gateway capability](/gateway/using-gateway#gateway-capabilities).
^6^ When using the `DEDUPE_USER_OBJECTS` [Gateway capability](/gateway/using-gateway#gateway-capabilities), `presences`, as well as each guild's `presences` array, is replaced by `merged_presences`. In addition, each guild's `members` array will be collapsed into `merged_members`. Finally, the `users` array will contain the user objects for every user in the event. Any user object in the event will be omitted, with an ID left in its place (e.g. `user_id` in [member](/resources/guild#guild-member-object) objects, `recipient_ids` in [private channel](/resources/channel#channel-object) objects, etc.).
^7^ When using the `PRIORITIZED_READY_PAYLOAD` [Gateway capability](/gateway/using-gateway#gateway-capabilities), `merged_members` will only include the client's [member](/resources/guild#guild-member-object) object for each guild. The rest will be sent in the [Ready Supplemental](#ready-supplemental) event, along with `merged_presences`. See the [gateway guild](#gateway-guild-object) object documentation for more information about included data.
^8^ The tutorial state is cleared after a period of inactivity. A `null` tutorial means no indicators will be shown.
^9^ The field will be a [versioned array](#versioned-structure) if the `VERSIONED_USER_GUILD_SETTINGS` [Gateway capability](/gateway/using-gateway#gateway-capabilities) is enabled. Otherwise, it will be a regular array.
^10^ The field will be a [versioned array](#versioned-structure) if the `VERSIONED_READ_STATES` [Gateway capability](/gateway/using-gateway#gateway-capabilities) is enabled. Otherwise, it will be a regular array.
^11^ Only available in [OAuth2 contexts](/gateway/using-gateway#oauth2-and-the-gateway).
^12^ Requires the `AUTO_LOBBY_CONNECT` [Gateway capability](/gateway/using-gateway#gateway-capabilities).
^13^ If `private_channels_version` is specified and the `PRIORITIZED_READY_PAYLOAD` [Gateway capability](/gateway/using-gateway#gateway-capabilities) is enabled, the field will have only created/updated private channels. The rest will be sent in the [Ready Supplemental](#ready-supplemental) event within the `lazy_private_channels` array.
###### Versioned Structure
A generic object used to represent versioned data. Depends on specific capabilities to enable versioning for certain fields in the [Ready](#ready) event.
| Field | Type | Description |
| ------- | ------------- | -------------------------------------- |
| entries | array[object] | The entries |
| partial | boolean | Whether the `entries` field is partial |
| version | integer | The version of the object |
###### Merged Presences Structure
| Field | Type | Description |
| ---------- | -------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| friends | array[[presence](/resources/presence#presence-object) object] | Presences of the user's [friends and implicit relationships](/resources/relationships#relationship-object) (depending on the [`NO_AFFINE_USER_IDS` Gateway capability](/gateway/using-gateway#gateway-capabilities)) |
| guilds ^1^ | array[array[[presence](/resources/presence#presence-object) object]] | Presences of the user's guilds, in the same order as [the `guilds` array in Ready](#ready) |
^1^ See the [gateway guild](#gateway-guild-object) object documentation for more information about included data.
###### Tutorial Structure
| Field | Type | Description |
| --------------------- | ------------- | ---------------------------------------------------------- |
| indicators_suppressed | boolean | Whether the user has suppressed all tutorial indicators |
| indicators_confirmed | array[string] | An array of the tutorial indicators the user has confirmed |
###### Gateway Application Structure
| Field | Type | Description |
| -------------- | --------- | ------------------------------------------------------------------------------------------------------- |
| id | snowflake | The ID of the application |
| flags ^2^ | integer | The [application's flags](/resources/application#application-flags) |
| flags_new ^2^ | string | The [application's flags](/resources/application#application-flags) serialized as a stringified integer |
| name? ^1^ | string | The name of the application |
| parent_id? ^1^ | snowflake | The ID of the parent application |
^1^ Only available in [OAuth2 contexts](/gateway/using-gateway#oauth2-and-the-gateway).
^2^ The `flags` field is serialized as a number; however, this number will not grow beyond 31 bits. New flag bits beyond bit 30 will only appear in `flags_new`, a string-serialized integer
containing the full set of flag bits.
###### Gateway Auth Structure
| Field | Type | Description |
| -------------------- | -------------- | --------------------------------------------------------------------------------------------------- |
| authenticator_types? | array[integer] | The [types of multi-factor authenticators](/resources/user#authenticator-type) the user has enabled |
###### Gateway Feature Flags Structure
| Field | Type | Description |
| ----------------------- | ------------- | ------------------------------------------------------------------------ |
| disabled_functions | array[string] | Functions that are currently disabled in the SDK due to instability |
| disabled_gateway_events | array[string] | Gateway events that are currently disabled in the SDK due to instability |
###### User Application Profile Structure
| Field | Type | Description |
| ------------- | --------------------------------------------------------------------------------------------------- | ---------------------------------------------------- |
| username | ?string | The external username of the provisional account |
| metadata | ?string | Custom metadata |
| data? | ?[user application profile data](/resources/widgets#user-application-profile-data-structure) object | The user application data |
| data_trusted? | ?boolean | Whether the data is trusted (set by application bot) |
| external_id | [user application profile external ID](#user-application-profile-external-id-structure) object | The external ID of the provisional account |
| avatar_hash | ?string | The user's [avatar hash](/reference#cdn-formatting) |
###### User Application Profile External ID Structure
| Field | Type | Description |
| ----------------------- | ------- | ---------------------------------------------------------------------------------------------------------- |
| provider_type | string | The [type of the application identity provider](/resources/application#application-identity-provider-type) |
| provider_issued_user_id | string | The ID of the user on the external identity provider |
| provider_id ^1^ | ?string | The ID of the application external identity provider client |
| preferred_global_name | ?string | The preferred global name for the user |
^1^ Not applicable for the [`DISCORD_BOT`](/resources/application#application-identity-provider-type) provider type.
###### Example User Application Profile External ID
```json
{
"username": null,
"metadata": "",
"external_id": {
"provider_type": "UNITY",
"provider_issued_user_id": "x8Ps1ETIGYma4gJ1c6lyeKBaiJ42",
"provider_id": "d360455e-2b56-4922-bf73-b64b157d5934",
"preferred_global_name": null
},
"avatar_hash": null
}
```
###### Console Connection Request Data Structure
| Field | Type | Description |
| --------------------- | ------------------------------------------------------------------------------------------------------- | --------------------------------- |
| analytics_properties? | [connect request properties](/resources/connected-accounts#connect-request-properties-structure) object | The properties used for analytics |
###### Session Type
| Value | Description |
| ------ | ------------------------- |
| normal | A normal Gateway session |
| oauth | An OAuth2 Gateway session |
###### Regional Feature Config Object
| Field | Type | Description |
| ------------------------ | ------ | --------------------------------------------------------------------------------------- |
| age_gated_features | number | Bitfield representing [age-gated actions and content](#age-gated-features) |
| teen_by_default_settings | number | Bitfield representing [safety settings restricted for teens](#teen-by-default-settings) |
###### Age Gated Features
| Value | Name | Description |
| -------- | ----------------------------------- | ---------------------------------------------------------------------------------------------------------------------------- |
| 1 \<\< 0 | AGE_GATED_SPACES | Restricted from joining or viewing guilds and channels marked as NSFW |
| 1 \<\< 1 | SENSITIVE_CONTENT_SHOW_SETTING | Restricted from changing sensitive content settings |
| 1 \<\< 2 | DM_PRIVACY_SETTINGS | Restricted from changing DM privacy and scanning settings |
| 1 \<\< 3 | MESSAGE_REQUEST_RESTRICTIONS_TOGGLE | Restricted from changing message request filtering settings |
| 1 \<\< 4 | LARGE_SERVER_ACCESS | Restricted from joining or viewing guilds with the [`AGE_VERIFICATION_LARGE_GUILD` feature](/resources/guild#guild-features) |
| 1 \<\< 5 | COMMANDS_TOGGLE | Restricted from using commands marked as NSFW |
| 1 \<\< 6 | REACTIVE_CHECK | Requires the client to perform a silent age verification check before accessing gated features |
| 1 \<\< 7 | STAGE_SPEAKING | Restricted from starting stages or raising a hand to speak in stage channels |
###### Teen By Default Settings
| Value | Name | Description |
| -------- | ------------------------------------ | ------------------------------------------------------------- |
| 1 \<\< 0 | SENSITIVE_CONTENT | Forces sensitive content filters to be enabled |
| 1 \<\< 1 | FRIEND_REQUEST_STRANGER_CONFIRMATION | Disables the everyone option in friend request settings |
| 1 \<\< 2 | MESSAGE_REQUEST_RESTRICTIONS | Restricts toggling message requests |
| 1 \<\< 3 | GUILD_ACTIVITY_STATUS | Forces activity status sharing to be disabled in large guilds |
| 1 \<\< 4 | SPAM_FILTERS | Forces spam filters to their highest restriction level in DMs |
#### Ready Supplemental
Sent soon after [Ready](#ready), with additional data that is not critical to begin interacting with the platform.
If this event is enabled, any fields received in it that are also present in [Ready](#ready) will not be received in [Ready](#ready). See footnotes for more information.
This event requires the `PRIORITIZED_READY_PAYLOAD` [Gateway capability](/gateway/using-gateway#gateway-capabilities).
###### Ready Supplemental Structure
| Field | Type | Description |
| --------------------- | ---------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| guilds | array[[supplemental guild](#supplemental-guild-structure) object] | The guilds the user is in |
| merged_members ^1^ | array[array[[member](/resources/guild#guild-member-object) object]] | Initial members for each of the user's guilds, in the same order as the `guilds` array |
| merged_presences ^1^ | [merged presences](#merged-presences-structure) object | The presences of the user's non-offline [friends and implicit relationships](/resources/relationships#relationship-object) (depending on the [`NO_AFFINE_USER_IDS` Gateway capability](/gateway/using-gateway#gateway-capabilities)), and any guild presences sent at startup |
| lazy_private_channels | array[[channel](/resources/channel#channel-object) object] | Additional DMs and group DMs the user is participating in, omitted from [Ready](#ready) because they were already in client state cache |
| disclose | array[string] | Upcoming changes that the client should disclose to the user |
| game_invites | array[[game invite](/resources/game-invite#game-invite-object) object] | The game invites the current user has received (max 100) |
^1^ See the [gateway guild](#gateway-guild-object) object documentation for more information about included data.
###### Supplemental Guild Structure
Unavailable guilds will only include the `id` field.
| Field | Type | Description |
| ------------------ | ---------------------------------------------------------------------------------------------------- | --------------------------------------------- |
| id | snowflake | The ID of the guild |
| voice_states | array[[voice state](/resources/voice#voice-state-object) object] | States of members currently in voice channels |
| activity_instances | array[[embedded activity instance](/resources/application#embedded-activity-instance-object) object] | Embedded activity instances in the guild |
#### Resumed
Sent when a client has sent a [resume payload](#resume) to the Gateway (for resuming existing sessions). Signifies the end of event replaying.
###### Resumed Structure
| Field | Type | Description |
| ------- | ------------- | ----------------------------------------------------------------------------------------- |
| \_trace | array[string] | An array of stringified JSON values representing the connection trace, used for debugging |
###### Example Resumed
```json
{
"_trace": [
"[\"gateway-prd-us-east1-c-6w69\",{\"micros\":4493,\"calls\":[\"id_created\",{\"micros\":0,\"calls\":[]},\"session_lookup_time\",{\"micros\":4163,\"calls\":[]},\"session_lookup_finished\",{\"micros\":17,\"calls\":[]},\"discord-sessions-prd-2-31\",{\"micros\":66}]}]"
]
}
```
#### Rate Limited
Sent when a client encounters a Gateway rate limit for an operation. See the [rate limiting documentation](/gateway/using-gateway#rate-limiting) for more information on rate limits.
###### Rate Limited Structure
| Field | Type | Description |
| ----------- | ------------------------------------------------------------ | ------------------------------------------------------------------------------------------------- |
| opcode | integer | [Opcode](/gateway/opcodes-and-close-codes#gateway-opcodes) of the operation that was rate limited |
| retry_after | float | The number of seconds to wait before submitting another request |
| meta | [rate limit metadata](#rate-limit-metadata-structure) object | Metadata for the operation that was rate limited |
###### Rate Limit Metadata Structure
| Field | Type | Description |
| -------- | --------- | ----------------------------------------------------------------------- |
| guild_id | snowflake | The ID of the guild associated with the operation that was rate limited |
| nonce? | string | The nonce sent in the request that was rate limited |
#### Remote Command (Receive)
Sent when a message is received from another Gateway session. The inner payload is the [sent message](<#remote-command-(send)>).
#### Activity Invite Create
Sent when the current user receives an activity invite but the session doesn't have the `dm_channels.messages.read` scope.
This event is only received in OAuth2 contexts.
###### Activity Invite Create Structure
| Field | Type | Description |
| ------------ | --------------------------------------------------------------------------------------- | -------------------------------------------------------------------- |
| message_id? | snowflake | The ID of the message |
| channel_id? | snowflake | The ID of the channel |
| author? | partial [user](/resources/user#user-object) object | The user that is inviting the current user to rich presence activity |
| application? | [integration application](/resources/integration#integration-application-object) object | The application of the message's rich presence activity |
| activity? | [message activity](/resources/message#message-activity-object) object | The rich presence activity the author is inviting current user to |
### Authentication
#### Auth Session Change
Sent when the current session's associated auth session ID changes.
###### Auth Session Change Structure
| Field | Type | Description |
| -------------------- | ------ | ------------------------------------------------------------------------------- |
| auth_session_id_hash | string | The hash of the auth session ID corresponding to the auth token used to connect |
#### Authenticator Create
Sent when a WebAuthn authenticator is created. The inner payload is an [authenticator](/resources/user#authenticator-object) object.
#### Authenticator Update
Sent when a WebAuthn authenticator is updated. The inner payload is an [authenticator](/resources/user#authenticator-object) object.
#### Authenticator Delete
Sent when a WebAuthn authenticator is deleted.
###### Authenticator Delete Structure
| Field | Type | Description |
| ----- | ------ | --------------------------------------------------------------- |
| id | string | The ID of the authenticator |
| type | string | The [type of authenticator](/resources/user#authenticator-type) |
### Application Commands
#### Application Command Permissions Update
Sent when an application command's permissions are updated. The inner payload is a [guild application command permissions](/interactions/application-commands#guild-application-command-permissions-structure) object.
### Auto Moderation
#### Auto Moderation Rule Create
Sent when a rule is created. The inner payload is an [automod rule](/resources/auto-moderation#automod-rule-object) object. Requires the `MANAGE_GUILD` permission.
This event is not received by user accounts.
#### Auto Moderation Rule Update
Sent when a rule is updated. The inner payload is an [automod rule](/resources/auto-moderation#automod-rule-object) object. Requires the `MANAGE_GUILD` permission.
This event is not received by user accounts.
#### Auto Moderation Rule Delete
Sent when a rule is deleted. The inner payload is an [automod rule](/resources/auto-moderation#automod-rule-object) object. Requires the `MANAGE_GUILD` permission.
This event is not received by user accounts.
#### Auto Moderation Action Execution
Sent when a rule is triggered and an action is executed (e.g. message is blocked). Requires the `MANAGE_GUILD` permission.
This event is not received by user accounts.
###### Auto Moderation Action Execution Structure
| Field | Type | Description |
| ------------------------ | ------------------------------------------------------------------------- | ---------------------------------------------------------------------- |
| guild_id | snowflake | The ID of the guild where the action was executed |
| action | [automod action](/resources/auto-moderation#automod-action-object) object | The action that was executed |
| rule_id | snowflake | The ID of the rule that was triggered |
| rule_trigger_type | integer | The trigger type of the rule that was triggered |
| user_id | snowflake | The ID of the user which generated the content that triggered the rule |
| channel_id? | snowflake | The ID of the channel in which the user content was posted |
| message_id? | snowflake | The ID of the message that triggered the rule |
| alert_system_message_id? | snowflake | The ID of the AutoMod system message posted as a result of this action |
| content | string | The user message content |
| matched_keyword | ?string | The word or phrase configured that triggered the rule |
| matched_content | ?string | The substring in content that triggered the rule |
#### Auto Moderation Mention Raid Detection
Sent when a mention raid is detected. Requires the `MANAGE_GUILD` permission.
###### Auto Moderation Mention Raid Detection Structure
| Field | Type | Description |
| --------------------------------- | ----------------- | ------------------------------------------------------- |
| guild_id | snowflake | The ID of the guild where the mention raid was detected |
| decision_id | string | The ID of the decision that was executed |
| suspicious_mention_activity_until | ISO8601 timestamp | When the mention activity restrictions will end |
### Billing
#### Billing Popup Bridge Callback
Sent when billing popup bridge callback is received.
###### Billing Popup Bridge Callback Structure
| Field | Type | Description |
| -------------------- | ------------------- | -------------------------------------------------------------------- |
| payment_source_type? | integer | The [type](/resources/billing#payment-source-type) of payment source |
| state? | string | The hash used to verify the callback |
| path? | string | The URL path of the callback |
| query? | map[string, string] | The URL query parameters of the callback |
### Calls
#### Call Create
Sent when a user creates a call in a private channel, or to inform the client of an existing call after a [Request Call Connect](#request-call-connect).
###### Call Create Structure
| Field | Type | Description |
| ------------ | ---------------------------------------------------------------- | ----------------------------------------------------------------------------------- |
| channel_id | snowflake | The ID of the private channel this call is occuring in |
| message_id | snowflake | The ID of the message associated with the call |
| region | string | The [voice region](/resources/voice#voice-region-object) ID the call is hosted from |
| ringing | array[snowflake] | The IDs of the users that are being rung to join the call |
| voice_states | array[[voice state](/resources/voice#voice-state-object) object] | The voice states of the users already in the call |
#### Call Update
Sent when metadata about a call changes.
###### Call Update Structure
| Field | Type | Description |
| ---------- | --------- | ----------------------------------------------------------------------------------- |
| channel_id | snowflake | The ID of the private channel this call is occuring in |
| message_id | snowflake | The ID of the message associated with the call |
| region | string | The [voice region](/resources/voice#voice-region-object) ID the call is hosted from |
| ringing | array | The IDs of the users that are being rung to join the call |
#### Call Delete
Sent when a call is deleted, or becomes unavailable due to an outage.
###### Call Delete Structure
| Field | Type | Description |
| ------------ | --------- | ------------------------------------------------------ |
| channel_id | snowflake | The ID of the private channel this call is occuring in |
| unavailable? | boolean | Whether the call is unavailable due to an outage |
### Channels
#### Channel Create
Sent when a channel was created, relevant to the current user. The inner payload is a [channel](/resources/channel#channel-object) object.
###### Channel Create Structure Extra Fields
| Field | Type | Description |
| ------------------ | --------- | ---------------------------------------------------- |
| origin_channel_id? | snowflake | The ID of the DM that this group DM was created from |
#### Channel Update
Sent when a channel is updated. The inner payload is a [channel](/resources/channel#channel-object) object. This is not sent when the field `last_message_id` or `status` is altered.
To keep track of the `last_message_id` changes, you must listen for [Message Create](#message-create) events (or [Thread Create](#thread-create) events for thread-only channels, [Guild Directory Entry Create](#guild-directory-entry-create) events for directory channels, etc.).
To keep track of the `status` changes, you must listen for [Voice Channel Status Update](#voice-channel-status-update) events.
This event may reference roles or guild members that no longer exist in a guild.
#### Channel Delete
Sent when a channel relevant to the current user is deleted. The inner payload is a [channel](/resources/channel#channel-object) object.
For private channels, the received channel object will be partial.
#### Channel Sync
Sent in response to [Resync Guild Channels](#resync-guild-channels).
The channel list will only include channels the account has the `VIEW_CHANNEL` permission for.
###### Channel Sync Structure
| Field | Type | Description |
| --------------- | ---------------------------------------------------------- | ---------------------------------------------------------------- |
| guild_id | snowflake | The ID of the guild |
| channels ^1^ | array[[channel](/resources/channel#channel-object) object] | The requested channels |
| integrity_check | boolean | Whether an integrity check needs to be performed on client cache |
^1^ If the current user does not have `VIEW_CHANNEL` permission in a requested channel or it does not exist, it will be omitted.
#### Channel Update Partial
Sent instead of [Channel Unread Update](#channel-unread-update) in OAuth2 contexts. Inner payload is a [channel unread](#channel-unread-structure) object.
This event is only received in OAuth2 contexts.
#### Channel Info
Sent in response to [Request Channel Info](#request-channel-info). Contains extra fields for the guild's channels.
Only requested fields are included, and they are only included on applicable channel types.
###### Channel Info Structure
| Field | Type | Description |
| -------- | ------------------------------------------------------------- | -------------------------------------- |
| guild_id | snowflake | The ID of the guild |
| channels | array[[channel metadata](#channel-metadata-structure) object] | The guild's channels with extra fields |
###### Channel Metadata Structure
| Field | Type | Description |
| ----------------- | ------------------ | ------------------------------------------------------------------------- |
| id | snowflake | The ID of the channel |
| status? | ?string | The status of the voice channel (max 500 characters) |
| voice_start_time? | ?ISO8601 timestamp | The unix timestamp (in seconds) of when the current voice session started |
#### Channel Statuses
Sent in response to [Request Channel Statuses](#request-channel-statuses). Contains the statuses for all voice channels that have one set.
###### Channel Statuses Structure
| Field | Type | Description |
| -------- | --------------------------------------------------------- | -------------------------------- |
| guild_id | snowflake | The ID of the guild |
| channels | array[[channel status](#channel-status-structure) object] | The voice channels with statuses |
###### Channel Status Structure
| Field | Type | Description |
| ------ | --------- | ---------------------------------------------------- |
| id | snowflake | The ID of the channel |
| status | string | The status of the voice channel (max 500 characters) |
#### Channel Member Count Update
Sent in response to [Request Channel Member Count](#request-channel-member-count). Contains the number of members that can currently see the channel.
##### Channel Member Count Update Structure
| Field | Type | Description |
| -------------- | --------- | ---------------------------------------------------------------------------- |
| guild_id | snowflake | The ID of the guild |
| channel_id | snowflake | The ID of the channel |
| member_count | integer | The number of members that can currently see the channel |
| presence_count | integer | The number of members that can currently see the channel and are not offline |
#### Channel Unread Update
Sent periodically to inform the client of the current unread state in guilds it's not subscribed to.
This event is not sent when using the `PASSIVE_GUILD_UPDATE` or `PASSIVE_GUILD_UPDATE_V2` [Gateway capabilities](/gateway/using-gateway#gateway-capabilities).
An exception is made for directory channels, which will still dispatch this event even when using those capabilities.
###### Channel Unread Update Structure
| Field | Type | Description |
| ---------------------- | --------------------------------------------------------- | ------------------------------------------- |
| guild_id | snowflake | The ID of the guild |
| channel_unread_updates | array[[channel unread](#channel-unread-structure) object] | The unread states for channels in the guild |
###### Channel Unread Structure
| Field | Type | Description |
| ------------------- | ------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| id | snowflake | The ID of the channel |
| last_message_id | ?snowflake | The ID of the last message sent (or thread created for thread-only channels, directory entry created for directory channels) in this channel (may not point to an existing resource) |
| last_pin_timestamp? | ?ISO8601 timestamp | When the last pinned message was pinned, if any |
#### Channel Pins Update
Sent when a message is pinned or unpinned in a text channel. This is not sent when a pinned message is deleted.
###### Channel Pins Update Structure
| Field | Type | Description |
| ------------------- | ------------------ | ---------------------------------------------- |
| guild_id? | snowflake | The ID of the guild |
| channel_id | snowflake | The ID of the channel |
| last_pin_timestamp? | ?ISO8601 timestamp | When the most recent pinned message was pinned |
#### Channel Pins Ack
Sent when the user acknowledges the current pinned messages in a channel.
###### Channel Pins Ack Structure
| Field | Type | Description |
| ---------- | ----------------- | ---------------------------------------------- |
| channel_id | snowflake | The ID of the channel |
| timestamp | ISO8601 timestamp | When the most recent pinned message was pinned |
| version | integer | The user read state version |
#### Channel Recipient Add
Sent when a user is added to a group direct message channel.
###### Channel Recipient Add Structure
| Field | Type | Description |
| ---------- | -------------------------------------------------- | --------------------------------------- |
| channel_id | snowflake | The ID of the channel |
| user | partial [user](/resources/user#user-object) object | The user who was added |
| nick? | string | The nickname of the user in the channel |
#### Channel Recipient Remove
Sent when a user is removed from a group direct message channel.
###### Channel Recipient Remove Structure
| Field | Type | Description |
| ---------- | -------------------------------------------------- | ------------------------ |
| channel_id | snowflake | The ID of the channel |
| user | partial [user](/resources/user#user-object) object | The user who was removed |
### Consoles
#### Console Command Update
Sent when a console command is updated.
###### Console Command Update Structure
| Field | Type | Description |
| ---------- | --------------------------------------------------------------------------------- | ------------------------- |
| id | snowflake | The ID of the command |
| result ^1^ | string | The result of the command |
| error ^2^ | ?partial [JSON error response](/topics/errors#example-json-error-response) object | The error |
^1^ If command failed, `result` will be set to either `failed`, or `n/a`.
^2^ The object will contain only a `code` key.
#### Conversation Summary Update
Sent when conversation summaries are updated for a text channel. Only new or updated summaries are sent.
###### Conversation Summary Update Structure
| Field | Type | Description |
| ---------- | ------------------------------------------------------------------------------------ | -------------------------------------------------- |
| guild_id | snowflake | The ID of the guild |
| channel_id | snowflake | The ID of the text channel |
| summaries | array[[conversation summary](/resources/message#conversation-summary-object) object] | The updated conversation summaries for the channel |
#### Creator Monetization Restrictions Update
Sent when guild creator monetization restrictions are updated.
###### Creator Monetization Restrictions Update
| Field | Type | Description |
| ------------ | --------------- | -------------------------------------------------------------------------------------------------- |
| guild_id | snowflake | The ID of the guild |
| restrictions | ?array[integer] | The [restrictions to creator monetization](/resources/guild#creator-monetization-restriction-type) |
#### Deleted Entity IDs
Sent in response to [Get Deleted Entity IDs Not Matching Hash](#get-deleted-entity-ids-not-matching-hash). Contains the IDs of the existing entities inside the guild.
If a field is omitted, it means that the hash matched and does not require updates.
###### Deleted Entity IDs Structure
| Field | Type | Description |
| --------- | ---------------- | ----------------------------- |
| guild_id | snowflake | The ID of the guild |
| stickers? | array[snowflake] | The IDs of the guild stickers |
| roles? | array[snowflake] | The IDs of the guild roles |
| emojis? | array[snowflake] | The IDs of the guild emoji |
| channels? | array[snowflake] | The IDs of the guild channels |
#### DM Settings Upsell Show
May be sent when a user rejects a message request.
###### DM Settings Upsell Show Structure
| Field | Type | Description |
| -------- | --------- | ------------------- |
| guild_id | snowflake | The ID of the guild |
#### Thread Create
Sent when a thread is created, relevant to the current user, or when the current user is added to a thread. The inner payload is a [channel](/resources/channel#channel-object) object.
- When a thread is created, includes an additional `newly_created` boolean field.
- When being added to an existing private thread, includes the optional [`member` field](/resources/channel#thread-member-object).
###### Thread Create Structure Extra Fields
| Field | Type | Description |
| -------------- | ------- | ----------------------------------- |
| newly_created? | boolean | Whether the thread was just created |
#### Thread Update
Sent when a thread is updated. The inner payload is a [channel](/resources/channel#channel-object) object. This is not sent when the field `last_message_id` is altered. To keep track of the `last_message_id` changes, you must listen for [Message Create](#message-create) events.
#### Thread Delete
Sent when a thread relevant to the current user is deleted. The inner payload is a subset of the [channel](/resources/channel#channel-object) object, containing just the `id`, `guild_id`, `parent_id`, and `type` fields.
#### Thread List Sync
Sent to sync a guild's active thread list, or to sync specific channel lists when the current user _gains_ access to a channel within a guild.
For bots, all active threads are synced at startup. For user accounts, only joined threads are synced, and the full list is sent through this event on subscription.
###### Thread List Sync Structure
| Field | Type | Description |
| ------------ | ---------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| guild_id | snowflake | The ID of the guild |
| channel_ids? | array[snowflake] | The parent channel IDs whose threads are being synced (may contain channel IDs that have no active threads so you know to clear that data); if omitted, then threads were synced for the entire guild |
| threads | array[[channel](/resources/channel#channel-object) object] | All active threads in the given channels that the current user can access |
| members | array[[thread member](/resources/channel#thread-member-object) object] | All thread member objects from the synced threads for the current user, indicating which threads the current user has been added to |
#### Thread Member Update
Sent when the [thread member](/resources/channel#thread-member-object) object for the current user is updated. The inner payload is a [thread member](/resources/channel#thread-member-object) object with an extra `guild_id` field. For bots, this event largely is just a signal that you are a member of the thread. See the [threads docs](/topics/threads) for more details.
###### Thread Member Update Structure Extra Fields
| Field | Type | Description |
| -------- | --------- | ------------------- |
| guild_id | snowflake | the id of the guild |
#### Thread Members Update
Sent when anyone is added to or removed from a thread. If the current user does not have the `GUILD_MEMBERS` [Gateway intent](/gateway/using-gateway#gateway-intents), then this event will only be sent if the current user was added to or removed from the thread.
###### Thread Members Update Structure
| Field | Type | Description |
| ------------------- | ---------------------------------------------------------------------- | ------------------------------------------------------------- |
| id | snowflake | The ID of the thread |
| guild_id | snowflake | The ID of the guild |
| member_count | integer | The approximate number of members in the thread, capped at 50 |
| added_members? ^1^ | array[[thread member](/resources/channel#thread-member-object) object] | The users who were added to the thread |
| removed_member_ids? | array of snowflakes | The IDs of the users who were removed from the thread |
^1^ Also include [`member`](/resources/guild#guild-member-object) and nullable [`presence`](/resources/presence#presence-object) fields.
### Embedded Activities
#### Embedded Activity Update V2
Sent when an embedded activity instance is created, updated, or deleted. The inner payload is an [embedded activity instance](/resources/application#embedded-activity-instance-object) object.
### Entitlements
#### Entitlement Create
Sent when an entitlement is created. The inner payload is an [entitlement](/resources/entitlement#entitlement-object) object.
#### Entitlement Update
Sent when an entitlement is updated. The inner payload is an [entitlement](/resources/entitlement#entitlement-object) object.
For subscription entitlements, this event is triggered only when a user's subscription ends, providing an `ends_at` timestamp that indicates the end of the entitlement.
#### Entitlement Delete
Sent when an entitlement is deleted. The inner payload is an [entitlement](/resources/entitlement#entitlement-object) object.
Entitlement deletions are infrequent, and occur when:
- Discord issues a refund for a subscription
- Discord removes an entitlement from a user via internal tooling
- Discord deletes an app-managed entitlement they created
- A test entitlement is deleted
Entitlements are _not_ deleted when they expire.
### Experiments
#### Experiment Session Override Create
Sent when an apex experiment override is created.
###### Experiment Session Override Create Structure
| Field | Type | Description |
| --------------- | ------- | ------------------------------- |
| experiment_name | string | The name of the experiment |
| variant_id | integer | The ID of the overriden variant |
#### Experiment Session Override Delete
Sent when an apex experiment override is deleted.
###### Experiment Session Override Delete Structure
| Field | Type | Description |
| --------------- | ------ | -------------------------- |
| experiment_name | string | The name of the experiment |
### Friend Suggestions
#### Friend Suggestion Create
Sent when a friend suggestion is created. The inner payload is a [friend suggestion](/resources/relationships#friend-suggestion-object) object.
#### Friend Suggestion Delete
Sent when a friend suggestion is deleted.
###### Friend Suggestion Delete Structure
| Field | Type | Description |
| ----------------- | --------- | ---------------------------- |
| suggested_user_id | snowflake | The ID of the suggested user |
### Game Servers
#### Game Server Create
Sent when a game server is created.
###### Game Server Create Structure
| Field | Type | Description |
| ----------- | --------------------------------------------------------- | ------------------- |
| guild_id | snowflake | The ID of the guild |
| game_server | [game server](/resources/guild#game-server-object) object | The game server |
#### Game Server Update
Sent when a game server is updated.
###### Game Server Update Structure
| Field | Type | Description |
| ----------- | --------------------------------------------------------- | ------------------- |
| guild_id | snowflake | The ID of the guild |
| game_server | [game server](/resources/guild#game-server-object) object | The game server |
#### Game Server Delete
Sent when a game server is deleted.
###### Game Server Delete Structure
| Field | Type | Description |
| -------------- | --------- | --------------------------------- |
| guild_id | snowflake | The ID of the guild |
| game_server_id | snowflake | The ID of the deleted game server |
### Gift Codes
#### Gateway Gift Code Object
A gift code object received over the Gateway has different attributes than the REST API.
###### Gateway Gift Code Structure
| Field | Type | Description |
| ----------- | --------- | ----------------------------------------------- |
| code | string | The gift code |
| sku_id | snowflake | The ID of the SKU that the gift code grants |
| uses | integer | The number of times the gift code has been used |
| channel_id? | snowflake | The ID of the channel the gift code was sent in |
| guild_id? | snowflake | The ID of the guild the gift code was sent in |
#### Gift Code Create
Sent when the user creates a gift code. The inner payload is a [gateway gift code](#gateway-gift-code-object) object.
#### Gift Code Update
Sent when a gift code is updated, either by the user or in a channel the user can see. The inner payload is a [gateway gift code](#gateway-gift-code-object) object.
### Guilds
#### Gateway Guild Object
[Guild](/resources/guild#guild-object) objects received over the Gateway have extended attributes that are not provided in the REST API.
###### Gateway Guild Structure
| Field | Type | Description |
| --------------------------- | ---------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------- |
| joined_at | ISO8601 timestamp | When this guild was joined |
| large | boolean | Whether the guild is considered large (more than `large_threshold` members) |
| unavailable? | boolean | Whether the guild is unavailable due to an outage |
| geo_restricted? ^7^ | boolean | Whether the guild is not available in your current region |
| member_count | integer | Total number of members in this guild |
| members ^1^ ^8^ | array[[guild member](/resources/guild#guild-member-object) object] | Initial members provided for the guild |
| channels ^8^ | array[[channel](/resources/channel#channel-object) object] | Channels in the guild |
| threads ^3^ | array[[channel](/resources/channel#channel-object) object] | All active threads in the guild that current user has permission to view |
| presences ^2^ ^8^ | array[[presence](/resources/presence#presence-object) object] | Initial presences provided for the guild |
| voice_states ^4^ ^8^ | array[[voice state](/resources/voice#voice-state-object) object] | States of members currently in voice channels |
| activity_instances ^4^ ^8^ | array[[embedded activity instance](/resources/application#embedded-activity-instance-object) object] | Embedded activity instances in the guild |
| stage_instances ^8^ | array[[stage instance](/resources/stage-instance#stage-instance-object) object] | Stage instances in the guild |
| guild_scheduled_events ^8^ | array[[guild scheduled event](/resources/guild-scheduled-event#guild-scheduled-event-object) object] | Scheduled events in the guild |
| data_mode ^5^ | string | The [data mode](#data-mode) for this object |
| partial_updates? | partial [guild updates](#partial-guild-updates-structure) object | The partial updates of the guild |
| channel_updates? | array[[channel unread](#channel-unread-structure) object] | The modified unread states for channels in the guild |
| unable_to_sync_deletes? ^9^ | boolean | Whether the Gateway could not sync deletes |
| properties ^5^ | partial [guild](/resources/guild#guild-object) object | The properties of the guild; an otherwise-normal guild object that is missing the below fields |
| stickers | array[[sticker](/resources/sticker#sticker-object) object] | Custom guild stickers |
| roles | array[[role](/resources/guild#role-object) object] | Roles in the guild |
| emojis | array[[emoji](/resources/emoji#emoji-object) object] | Custom guild emojis |
| soundboard_sounds ^6^ | array[[soundboard sound](/resources/soundboard#soundboard-sound-object) object] | Custom guild soundboard sounds |
| premium_subscription_count | integer | The number of premium subscriptions (boosts) the guild currently has |
^1^ For user accounts, guilds with over 75k members, or bots without the `GUILD_PRESENCES` [Gateway intent](/gateway/using-gateway#gateway-intents) this will only include the client's member and users in voice channels. User accounts additionally receive [friends and implicit relationships](/resources/relationships#relationship-object) (depending on the [`NO_AFFINE_USER_IDS` Gateway capability](/gateway/using-gateway#gateway-capabilities)), as well as users they have an open DM with. Otherwise, if a guild has between `large_threshold` and 75k members, bots will receive members who are online, have a role, have a nickname, or are in a voice channel, and if under `large_threshold` members, will receive all members.
^2^ User accounts only receive presences for non-offline [friends and implicit relationships](/resources/relationships#relationship-object) (depending on the [`NO_AFFINE_USER_IDS` Gateway capability](/gateway/using-gateway#gateway-capabilities)), as well as non-offline users they have an open DM with. Bots with the `GUILD_PRESENCES` [Gateway intent](/gateway/using-gateway#gateway-intents) receive all presences if the guild has less than `large_threshold` members, otherwise receiving only non-offline presences.
^3^ User accounts are only synced threads they have been added to. Bots are synced all threads they have permission to view.
^4^ Omitted when using the `PRIORITIZED_READY_PAYLOAD` [Gateway capability](/gateway/using-gateway#gateway-capabilities).
^5^ Requires the `CLIENT_STATE_V2` [Gateway capability](/gateway/using-gateway#gateway-capabilities). Without the capability, the `properties` field will be merged into the main object, along with the rest of the extended attributes.
^6^ Omitted when using the `CLIENT_STATE_V2` [Gateway capability](/gateway/using-gateway#gateway-capabilities).
^7^ Geo-restricted guilds will also be marked as unavailable and will not be joinable or accessable.
^8^ Omitted when using the `CLIENT_STATE_V2` [Gateway capability](/gateway/using-gateway#gateway-capabilities) and version is higher than specified when identifying.
^9^ Generally if the field is true, you should wait `math.ceil(random.random() * 2000.0)` milliseconds and send [Get Deleted Entity IDs Not Matching Hash](#get-deleted-entity-ids-not-matching-hash).
###### Partial Guild Updates Structure
| Field | Type | Description |
| -------------------- | ---------------------------------------------------------- | ------------------------------------- |
| channels? | array[[channel](/resources/channel#channel-object) object] | The updated channels |
| deleted_channel_ids? | array[snowflake] | The IDs of the deleted channels |
| emojis? | array[[emoji](/resources/emoji#emoji-object) object] | The updated guild emojis |
| deleted_emoji_ids? | array[snowflake] | The IDs of the deleted guild emojis |
| roles? | array[[role](/resources/guild#role-object) object] | The updated guild roles |
| deleted_role_ids? | array[snowflake] | The IDs of the deleted guild roles |
| stickers? | array[[sticker](/resources/sticker#sticker-object) object] | The updated guild stickers |
| deleted_sticker_ids? | array[snowflake] | The IDs of the deleted guild stickers |
#### Unavailable Guild Object
A partial guild object. Represents an offline guild, or a guild the client is not connected to yet.
###### Unavailable Guild Structure
| Field | Type | Description |
| --------------- | --------- | --------------------------------------------------------- |
| id | snowflake | The ID of the guild |
| unavailable? | boolean | Whether the guild is unavailable due to an outage |
| geo_restricted? | boolean | Whether the guild is not available in your current region |
| name? ^1^ | string | The name of the guild (2-100 characters) |
| icon? ^1^ | ?string | The guild's [icon hash](/reference#cdn-formatting) |
^1^ Only included when `geo_restricted` is `true`.
###### Example Unavailable Guild
```json
{
"id": "41771983423143937",
"unavailable": true
}
```
###### Data Mode
| Value | Description |
| ----------- | ------------------------------------------------------- |
| full | The full guild object is sent |
| partial | Guild data already in the client state cache is omitted |
| unavailable | The guild is unavailable due to an outage |
#### Guild Create
This event can be sent in three different scenarios:
1. When a bot is initially connecting, to lazily load and backfill information for all unavailable guilds sent in the [Ready](#ready) event. Guilds that are unavailable due to an outage or geo-restricted will instead send a [Guild Delete](#guild-delete) event.
2. When a guild becomes available again to the client.
3. When the current user joins a new guild.
During an outage, the guild object in scenarios 1 and 3 may be marked as unavailable.
The inner payload can be:
- An available guild: a [Gateway guild](#gateway-guild-object) object.
- An unavailable guild: an [unavailable guild](#unavailable-guild-object) object.
#### Guild Update
Sent when a guild is updated. The inner payload is a [guild](/resources/guild#guild-object) object.
#### Guild Delete
Sent when a guild becomes or was already unavailable due to an outage, or when the user leaves or is removed from a guild. The inner payload is an [unavailable guild](#unavailable-guild-object) object. If the `unavailable` field is not set, the user was removed from the guild.
#### Guild Application Command Index Update
Sent when the application command index is updated for a guild.
###### Guild Application Command Index Update Structure
| Field | Type | Description |
| -------- | --------- | ------------------- |
| guild_id | snowflake | The ID of the guild |
#### Guild Applied Boosts Update
Sent when a premium guild subscription is updated, meaning a user applied a boost or an existing boost was updated. The inner payload is a [premium guild subscription](/resources/guild#premium-guild-subscription-object) object.
#### Guild Audit Log Entry Create
Sent when a guild audit log entry is created. The inner payload is an [Audit Log Entry](/resources/audit-log#audit-log-entry-object) object. Requires the `VIEW_AUDIT_LOG` permission.
#### Guild Ban Add
Sent when a user is banned from a guild. Requires the `BAN_MEMBERS` or `VIEW_AUDIT_LOG` permission.
###### Guild Ban Add Structure
| Field | Type | Description |
| ------------------- | -------------------------------------------------- | ------------------------------------------- |
| guild_id | snowflake | The ID of the guild |
| user | partial [user](/resources/user#user-object) object | The banned user |
| delete_message_secs | integer | Number of seconds messages were deleted for |
#### Guild Ban Remove
Sent when a user is unbanned from a guild. Requires the `BAN_MEMBERS` or `VIEW_AUDIT_LOG` permission.
###### Guild Ban Remove Structure
| Field | Type | Description |
| -------- | -------------------------------------------------- | ------------------- |
| guild_id | snowflake | The ID of the guild |
| user | partial [user](/resources/user#user-object) object | The unbanned user |
#### Guild Bulk Ban Update
Sent when a guild finishes processing a [bulk-ban operation](/resources/guild#bulk-guild-ban-v2) for the current user.
###### Guild Bulk Ban Update Structure
| Field | Type | Description |
| -------- | ------------------------------------------------------------------------- | --------------------------------------- |
| guild_id | snowflake | The ID of the guild |
| bulk_ban | [guild bulk ban](/gateway/gateway-events#guild-bulk-ban-structure) object | The information about the ban operation |
###### Guild Bulk Ban Structure
| Field | Type | Description |
| ---------------- | ---------------- | ------------------------------------------ |
| banned_users | array[snowflake] | The user IDs that were successfully banned |
| failed_users ^1^ | array[snowflake] | The user IDs that were not banned |
^1^ A ban will fail if the user is already banned, the user has a higher role than the current user, the user is the owner of the guild, or the user is the current user.
#### Guild Directory Entry Create
Sent when a guild directory entry is created. The inner payload is a [directory entry](/resources/directory-entry#directory-entry-object) object.
#### Guild Directory Entry Update
Sent when a guild directory entry is updated. The inner payload is a [directory entry](/resources/directory-entry#directory-entry-object) object.
#### Guild Directory Entry Delete
Sent when a guild directory entry is deleted.
###### Guild Directory Entry Delete Structure
| Field | Type | Description |
| -------------------- | --------- | ---------------------------------------------------------------------------------- |
| type | integer | The [type of directory entry](/resources/directory-entry#directory-entry-type) |
| directory_channel_id | snowflake | The ID of the directory channel that the entry is in |
| guild_id | snowflake | The ID of the guild that the entry is in |
| entity_id | snowflake | The ID of the guild or scheduled event |
| created_at | string | When the entry was created |
| primary_category_id? | integer | The [primary category](/resources/directory-entry#directory-category) of the entry |
| description | ?string | The description of the entry |
| author_id | snowflake | The ID of the user that created the entry |
#### Guild Emojis Update
Sent when a guild's emoji have been updated.
###### Guild Emojis Update Structure
| Field | Type | Description |
| -------- | ---------------------------------------------------- | ---------------------- |
| guild_id | snowflake | The ID of the guild |
| emojis | array[[emoji](/resources/emoji#emoji-object) object] | The emoji in the guild |
#### Guild Stickers Update
Sent when a guild's stickers have been updated.
###### Guild Stickers Update Structure
| Field | Type | Description |
| -------- | ---------------------------------------------------------- | ------------------------- |
| guild_id | snowflake | The ID of the guild |
| stickers | array[[sticker](/resources/sticker#sticker-object) object] | The stickers in the guild |
#### Guild Feature Ack
Sent when the user updates the read state for a guild feature, such as scheduled events or onboarding.
###### Guild Feature Ack Structure
| Field | Type | Description |
| ----------- | --------- | -------------------------------------------------------------------- |
| ack_type | integer | The [type of read state](/topics/read-state#read-state-type) updated |
| resource_id | snowflake | The ID of the guild |
| entity_id | snowflake | The ID of the last acknowledged entity |
| version | integer | The user read state version |
#### Guild Join Request Create
Sent when a user creates a guild join request. Requires the `KICK_MEMBERS` permission for users other than the current user.
Events for guild join requests created with a status of [`STARTED`](/resources/guild#guild-join-request-status) are only dispatched to the current user. With respect to other users, this event is only sent for submitted join requests. If a join request is created and then submitted, only a [Guild Join Request Update](#guild-join-request-update) event will be received by moderators.
If a join request is created for a user with the `KICK_MEMBERS` permission, this event will be sent to the user twice: once for creating the join request, and once for receiving it as a moderator.
###### Guild Join Request Create Structure
| Field | Type | Description |
| -------- | ----------------------------------------------------------------------- | ---------------------------------------------------------------------------- |
| guild_id | snowflake | The ID of the guild |
| request | [guild join request](/resources/guild#guild-join-request-object) object | The created join request |
| status | string | The [status of the join request](/resources/guild#guild-join-request-status) |
#### Guild Join Request Update
Sent when a guild join request is updated. Requires the `KICK_MEMBERS` permission for users other than the current user.
If a join request is updated for a user with the `KICK_MEMBERS` permission, this event will be sent to the user twice: once for being the user who created the join request, and once for receiving it as a moderator.
###### Guild Join Request Update Structure
| Field | Type | Description |
| -------- | ----------------------------------------------------------------------- | ---------------------------------------------------------------------------- |
| guild_id | snowflake | The ID of the guild |
| request | [guild join request](/resources/guild#guild-join-request-object) object | The updated join request |
| status | string | The [status of the join request](/resources/guild#guild-join-request-status) |
#### Guild Join Request Delete
Sent when a guild join request is deleted. Requires the `KICK_MEMBERS` permission for users other than the current user.
###### Guild Join Request Delete Structure
| Field | Type | Description |
| -------- | --------- | ----------------------------------------------- |
| guild_id | snowflake | The ID of the guild |
| id | snowflake | The ID of the join request |
| user_id | snowflake | The ID of the user who created the join request |
#### Guild Member Add
If using [Gateway intents](/gateway/using-gateway#gateway-intents), the `GUILD_MEMBERS` intent will be required to receive this event.
Sent when a new user joins a guild. The inner payload is a [guild member](/resources/guild#guild-member-object) object with an extra `guild_id` key:
For user accounts, this event is only sent for themselves. Users are not automatically subscribed to [friends and implicit relationships](/resources/relationships#relationship-object) or users they have an open DM with upon them joining.
###### Guild Member Add Structure Extra Fields
| Field | Type | Description |
| -------- | --------- | ------------------- |
| guild_id | snowflake | The ID of the guild |
#### Guild Member Update
If using [Gateway intents](/gateway/using-gateway#gateway-intents), the `GUILD_MEMBERS` intent will be required to receive this event.
Sent when a guild member is updated. This will also fire when the user object of a guild member changes. Optional fields will only be included if changed.
For user accounts, this event is only sent for members they are subscribed to, and in response to actions committed by the user. Users are automatically subscribed to [friends and implicit relationships](/resources/relationships#relationship-object) (depending on the `NO_AFFINE_USER_IDS` [Gateway capability](/gateway/using-gateway#gateway-capabilities)), as well as users they have an open DM with.
###### Guild Member Update Structure
| Field | Type | Description |
| -------------------------------- | ------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| guild_id | snowflake | The ID of the guild |
| user | partial [user](/resources/user#user-object) object | The user this guild member represents |
| nick? | ?string | The guild-specific nickname of the member (1-32 characters) |
| avatar | ?string | The member's [guild avatar hash](/reference#cdn-formatting) |
| avatar_decoration_data? | ?[avatar decoration data](/resources/user#avatar-decoration-data-object) object | The member's [guild avatar decoration](https://support.discord.com/hc/en-us/articles/13410113109911-Avatar-Decorations) |
| roles | array[snowflake] | The role IDs assigned to this member |
| joined_at | ISO8601 timestamp | When the user joined the guild |
| premium_since | ?ISO8601 timestamp | When the member subscribed to (started [boosting](https://support.discord.com/hc/en-us/articles/360028038352-Server-Boosting-)) the guild |
| deaf? | boolean | Whether the member is deafened in voice channels |
| mute? | boolean | Whether the member is muted in voice channels |
| pending? ^1^ | boolean | Whether the member has not yet passed the guild's [member verification](/resources/guild#member-verification-object) requirements |
| communication_disabled_until ^2^ | ?ISO8601 timestamp | when the user's [timeout](https://support.discord.com/hc/en-us/articles/4413305239191-Time-Out-FAQ) will expire and the user will be able to communicate in the guild again, null or a time in the past if the user is not timed out |
| flags | integer | The [member's flags](/resources/guild#guild-member-flags) |
^1^ Won't be included in contexts that are impossible for a pending member to exist in.
^2^ If the value is a time in the past, the member's timeout has expired and they can communicate again. An event will not be sent when this happens.
#### Guild Member Remove
If using [Gateway intents](/gateway/using-gateway#gateway-intents), the `GUILD_MEMBERS` intent will be required to receive this event.
Sent when a user is removed from a guild (leave/kick/ban).
For user accounts, this event is only sent for themselves, members they are subscribed to, and in response to actions committed by the user. Users are automatically subscribed to [friends and implicit relationships](/resources/relationships#relationship-object) (depending on the `NO_AFFINE_USER_IDS` [Gateway capability](/gateway/using-gateway#gateway-capabilities)), as well as users they have an open DM with.
###### Guild Member Remove Structure
| Field | Type | Description |
| -------- | ------------------------------------------ | ------------------- |
| guild_id | snowflake | The ID of the guild |
| user | [user](/resources/user#user-object) object | The removed user |
#### Guild Members Chunk
Sent in response to [Request Guild Members](#request-guild-members).
You can use the `chunk_index` and `chunk_count` to calculate how many chunks are left for your request.
###### Guild Members Chunk Structure
| Field | Type | Description |
| ----------- | ------------------------------------------------------------------ | ---------------------------------------------------------------------------------------------------------------------------- |
| guild_id | snowflake | The ID of the guild |
| members | array[[guild member](/resources/guild#guild-member-object) object] | Chunked guild members |
| chunk_index | integer | The chunk index in the expected chunks for this response `(0 <= chunk_index < chunk_count)` |
| chunk_count | integer | The total number of expected chunks for this response |
| not_found? | array | The passed IDs that were not found |
| presences? | array[[presence](/resources/presence#presence-object) object] | The presences of the returned members, if requested |
| nonce? | string | The nonce used in [Request Guild Members](#request-guild-members) or [Search Recent Members](#search-recent-members), if any |
#### Guild Official Game Applications Update
Sent when official game applications are updated for a guild.
###### Guild Official Game Applications Update Structure
| Field | Type | Description |
| -------------------- | ---------------- | ------------------------------------- |
| guild_id | snowflake | The ID of the guild |
| game_application_ids | array[snowflake] | The IDs of official game applications |
#### Guild Powerup Entitlements Create
Sent when guild powerup entitlements are created.
###### Guild Powerup Entitlements Create Structure
| Field | Type | Description |
| ------------ | ---------------------------------------------------------------------- | -------------------------------- |
| guild_id | snowflake | The ID of the guild |
| entitlements | array[[entitlement](/resources/entitlement#entitlement-object) object] | The created powerup entitlements |
#### Guild Powerup Entitlements Delete
Sent when guild powerup entitlements are deleted.
###### Guild Powerup Entitlements Delete Structure
| Field | Type | Description |
| ------------ | ---------------------------------------------------------------------- | -------------------------------- |
| guild_id | snowflake | The ID of the guild |
| entitlements | array[[entitlement](/resources/entitlement#entitlement-object) object] | The deleted powerup entitlements |
#### Guild Role Create
Sent when a guild role is created.
###### Guild Role Create Structure
| Field | Type | Description |
| -------- | ------------------------------------------- | ------------------- |
| guild_id | snowflake | The ID of the guild |
| role | [role](/resources/guild#role-object) object | The role created |
#### Guild Role Update
Sent when a guild role is updated.
###### Guild Role Update Structure
| Field | Type | Description |
| -------- | ------------------------------------------- | ------------------- |
| guild_id | snowflake | The ID of the guild |
| role | [role](/resources/guild#role-object) object | The role updated |
#### Guild Role Delete
Sent when a guild role is deleted.
###### Guild Role Delete Structure
| Field | Type | Description |
| -------- | --------- | ------------------- |
| guild_id | snowflake | The ID of the guild |
| role_id | snowflake | The ID of the role |
### Guild Scheduled Events
#### Guild Scheduled Event Create
Sent when a guild scheduled event is created. The inner payload is a [guild scheduled event](/resources/guild-scheduled-event#guild-scheduled-event-object) object.
#### Guild Scheduled Event Update
Sent when a guild scheduled event is updated. The inner payload is a [guild scheduled event](/resources/guild-scheduled-event#guild-scheduled-event-object) object.
#### Guild Scheduled Event Delete
Sent when a guild scheduled event is deleted. The inner payload is a [guild scheduled event](/resources/guild-scheduled-event#guild-scheduled-event-object) object.
#### Guild Scheduled Event Exception Create
Sent when a guild scheduled event exception is created. The inner payload is a [guild scheduled event exception](/resources/guild-scheduled-event#guild-scheduled-event-exception-object) object.
#### Guild Scheduled Event Exception Update
Sent when a guild scheduled event exception is updated. The inner payload is a [guild scheduled event exception](/resources/guild-scheduled-event#guild-scheduled-event-exception-object) object.
This event is not currently used. See [Guild Scheduled Event Exception Create](#guild-scheduled-event-exception-create) instead.
#### Guild Scheduled Event Exception Delete
Sent when a guild scheduled event exception is deleted. The inner payload is a [guild scheduled event exception](/resources/guild-scheduled-event#guild-scheduled-event-exception-object) object.
#### Guild Scheduled Event Exceptions Delete
Sent when all guild scheduled event exceptions are deleted.
###### Guild Scheduled Event Exceptions Delete Structure
| Field | Type | Description |
| -------- | --------- | ----------------------------------- |
| guild_id | snowflake | The ID of the guild |
| event_id | snowflake | The ID of the guild scheduled event |
#### Guild Scheduled Event User Add
Sent when a user has subscribed to a guild scheduled event or exception. The inner payload is a [guild scheduled event user](/resources/guild-scheduled-event#guild-scheduled-event-user-object) object.
#### Guild Scheduled Event User Remove
Sent when a user has unsubscribed from a guild scheduled event or exception. The inner payload is a [guild scheduled event user](/resources/guild-scheduled-event#guild-scheduled-event-user-object) object.
### Guild Soundboard
#### Guild Soundboard Sound Create
Sent when a guild soundboard sound is created. The inner payload is a [soundboard sound](/resources/soundboard#soundboard-sound-object) object.
#### Guild Soundboard Sound Update
Sent when a guild soundboard sound is updated. The inner payload is a [soundboard sound](/resources/soundboard#soundboard-sound-object) object.
#### Guild Soundboard Sound Delete
Sent when a guild soundboard sound is deleted.
###### Guild Soundboard Sound Delete Structure
| Field | Type | Description |
| -------- | --------- | ------------------------------ |
| guild_id | snowflake | The ID of the guild |
| sound_id | snowflake | The ID of the soundboard sound |
#### Guild Soundboard Sounds Update
Sent when multiple guild soundboard sounds are updated.
###### Guild Soundboard Sounds Update Structure
| Field | Type | Description |
| ----------------- | ------------------------------------------------------------------------------- | ----------------------------- |
| guild_id | snowflake | The ID of the guild |
| soundboard_sounds | array[[soundboard sound](/resources/soundboard#soundboard-sound-object) object] | The guild's soundboard sounds |
#### Soundboard Sounds
Sent in response to [Request Soundboard Sounds](#request-soundboard-sounds).
###### Soundboard Sounds Event Structure
| Field | Type | Description |
| ----------------- | ------------------------------------------------------------------------------- | ------------------------------ |
| guild_id | snowflake | The ID of the source guild |
| soundboard_sounds | array[[soundboard sound](/resources/soundboard#soundboard-sound-object) object] | Custom guild soundboard sounds |
### Integrations
#### Guild Integrations Update
Sent when a guild integration is updated. This is sent in addition to one of the below events.
###### Guild Integrations Update Structure
| Field | Type | Description |
| -------- | --------- | --------------------------------------------------- |
| guild_id | snowflake | The ID of the guild whose integrations were updated |
#### Integration Create
Sent when an integration is created. The inner payload is an [integration](/resources/integration#integration-object) object with an additional `guild_id` key:
###### Integration Create Structure Extra Fields
| Field | Type | Description |
| -------- | --------- | ------------------- |
| guild_id | snowflake | The ID of the guild |
#### Integration Update
Sent when an integration is updated. The inner payload is an [integration](/resources/integration#integration-object) object with an additional `guild_id` key:
###### Integration Update Structure Extra Fields
| Field | Type | Description |
| -------- | --------- | ------------------- |
| guild_id | snowflake | The ID of the guild |
#### Integration Delete
Sent when an integration is deleted.
###### Integration Delete Structure
| Field | Type | Description |
| --------------- | --------- | --------------------------------------------------- |
| id | snowflake | The ID of the integration |
| guild_id | snowflake | The ID of the guild |
| application_id? | snowflake | The ID of the integrated OAuth2 application, if any |
### Interactions
#### Interaction Create
Sent when an user uses an [application command](/interactions/application-commands), triggers a [message component](/resources/components), filling in an autocompleteable option, or submits a modal.
For bots, the inner payload is an [interaction](/interactions/receiving-and-responding#interaction-object) object.
###### Interaction Create Structure
| Field | Type | Description |
| ------ | --------- | ----------------------------------------------------------- |
| id | snowflake | The ID of the interaction |
| nonce? | string | The interaction's nonce, used for interaction deduplication |
#### Interaction Failure
Sent when an interaction fails.
###### Interaction Failure Structure
| Field | Type | Description |
| ----------- | --------- | ---------------------------------------------------------------- |
| id | snowflake | The ID of the interaction |
| nonce? | string | The interaction's nonce, used for interaction deduplication |
| reason_code | integer | The [reason why interaction failed](#interaction-failure-reason) |
###### Interaction Failure Reason
| Value | Name | Description |
| ----- | ------------------------------------------------------------ | -------------------------------------------------------------- |
| 1 | UNKNOWN | Unknown |
| 2 | TIMEOUT | The interaction timed out |
| 3 | ACTIVITY_LAUNCH_UNKNOWN_APPLICATION | Unknown application |
| 4 | ACTIVITY_LAUNCH_UNKNOWN_CHANNEL | Unknown channel |
| 5 | ACTIVITY_LAUNCH_UNKNOWN_GUILD | Unknown guild |
| 6 | ACTIVITY_LAUNCH_INVALID_PLATFORM | Invalid platform |
| 7 | ACTIVITY_LAUNCH_NOT_IN_EXPERIMENT | The guild/user is not eligible for a required experiment |
| 8 | ACTIVITY_LAUNCH_INVALID_CHANNEL_TYPE | Invalid channel type |
| 9 | ACTIVITY_LAUNCH_INVALID_CHANNEL_NO_AFK | Cannot launch activity in an AFK channel |
| 10 | ACTIVITY_LAUNCH_INVALID_DEV_PREVIEW_GUILD_SIZE | Guild is too large for the beta test of this feature |
| 11 | ACTIVITY_LAUNCH_INVALID_USER_AGE_GATE | Cannot use NSFW interaction |
| 12 | ACTIVITY_LAUNCH_INVALID_USER_VERIFICATION_LEVEL | User does not meet the guild's verification level |
| 13 | ACTIVITY_LAUNCH_INVALID_USER_PERMISSIONS | User has insufficient permissions for this interaction |
| 14 | ACTIVITY_LAUNCH_INVALID_CONFIGURATION_NOT_EMBEDDED | The application is not an embedded activity |
| 15 | ACTIVITY_LAUNCH_INVALID_CONFIGURATION_PLATFORM_NOT_SUPPORTED | The embedded activity does not support the current platform |
| 16 | ACTIVITY_LAUNCH_INVALID_CONFIGURATION_PLATFORM_NOT_RELEASED | The embedded activity is not released for the current platform |
| 17 | ACTIVITY_LAUNCH_FAILED_TO_LAUNCH | Failed to launch the activity |
| 18 | ACTIVITY_LAUNCH_INVALID_USER_NO_ACCESS_TO_ACTIVITY | The user does not have permissions to launch the activity |
| 19 | ACTIVITY_LAUNCH_INVALID_LOCATION_TYPE | Failed to launch the activity |
| 20 | ACTIVITY_LAUNCH_INVALID_USER_REGION_FOR_APPLICATION | The embedded activity is not supported in the current region |
#### Interaction Success
Sent when an interaction succeeds.
###### Interaction Success Structure
| Field | Type | Description |
| ----- | --------- | ----------------------------------------------------------- |
| id | snowflake | The ID of the interaction |
| nonce | ?string | The interaction's nonce, used for interaction deduplication |
#### Application Command Autocomplete Response
Sent when application responds to an autocomplete interaction.
###### Application Command Autocomplete Response Structure
| Field | Type | Description |
| ------- | --------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------- |
| choices | array[[application command option choice](/interactions/application-commands#application-command-option-choice-structure) object] | The choices the application is offering for autocomplete |
| nonce | ?string | The interaction's nonce, used for interaction deduplication |
#### Interaction Modal Create
Sent when an application responds to interaction with a modal.
###### Interaction Modal Create Structure
| Field | Type | Description |
| ----------- | --------------------------------------------------------------------------------------- | ----------------------------------------------------------- |
| id | snowflake | The ID of the interaction |
| channel_id | snowflake | The ID of the channel the interaction was created in |
| custom_id | string | The developer-defined identifier for the modal |
| application | [integration application](/resources/integration#integration-application-object) object | The application associated with the interaction |
| title | string | The title of the modal |
| components | array[[component](/resources/components#component-object) object] | The modal components |
| nonce | ?string | The interaction's nonce, used for interaction deduplication |
| resolved? | [resolved data](/interactions/receiving-and-responding#resolved-data-object) | The resolved entities |
#### Interaction IFrame Modal Create
Sent when an application responds to interaction with an iFrame modal.
###### Interaction IFrame Modal Create Structure
| Field | Type | Description |
| --------------- | --------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------- |
| id | snowflake | The ID of the interaction |
| channel_id | snowflake | The ID of the channel the interaction was created in |
| custom_id | string | The developer-defined identifier for the iFrame modal |
| application | [integration application](/resources/integration#integration-application-object) object | The application associated with the interaction |
| title | string | The title of the modal |
| iframe_path ^1^ | string | The relative URL to the iFrame modal |
| modal_size | integer | The [iFrame modal size](/interactions/receiving-and-responding#iframe-modal-size) |
| nonce | ?string | The interaction's nonce, used for interaction deduplication |
^1^ The complete iFrame URL will be `https://{application_id}.discordsays.com/{iframe_path}?instance_id={channel_id}:{application_id}:{custom_id}&custom_id={custom_id}&channel_id={channel_id}&guild_id={guild_id}&frame_id={frame_id}&platform={platform}` where `guild_id` is optional, `frame_id` is a unique UUID for the frame, and `platform` is either `desktop` or `mobile`.
#### Social Layer SKU Purchase Eligibility Response
Sent when an application responds to a social layer SKU purchase eligibility interaction.
###### Social Layer SKU Purchase Eligibility Response Structure
| Field | Type | Description |
| -------------- | --------- | ------------------------------------------------------------------- |
| interaction_id | snowflake | The ID of the interaction |
| application_id | snowflake | The ID of the application |
| sku_id | snowflake | The ID of the SKU |
| recipient_id | snowflake | The ID of the recipient |
| eligible | snowflake | Whether the recipient is eligible for the social layer SKU purchase |
### Invites
#### Invite Create
Sent when a new invite to a guild channel is created. Requires the `MANAGE_CHANNELS` permission.
This event is not received by user accounts.
###### Invite Create Structure
| Field | Type | Description |
| ------------------- | ----------------------------------------------------------------------- | ----------------------------------------------------------------------------------- |
| code | string | The invite code (unique ID) |
| type | integer | The [type of invite](/resources/invite#invite-type) |
| channel_id | snowflake | The ID of the channel the invite is for |
| guild_id | snowflake | The ID of the guild this invite is for |
| inviter? | partial [user](/resources/user#user-object) object | The user who created the invite |
| target_type? | integer | The [type of target](/resources/invite#invite-target-type) for this guild invite |
| target_user? | partial [user](/resources/user#user-object) object | The user whose stream to display for this voice channel stream invite |
| target_application? | partial [application](/resources/application#application-object) object | The embedded application to open for this voice channel embedded application invite |
| role_ids? | array[snowflake] | The IDs of the roles to grant to the invitee upon acceptance |
| expires_at | ?ISO8601 timestamp | The expiry date of the invite, if it expires |
| created_at | ISO8601 timestamp | When this invite was created |
| uses | integer | Number of times this invite has been used |
| max_uses | integer | Max number of times this invite can be used |
| max_age | integer | Duration (in seconds) after which the invite expires |
| temporary | boolean | Whether this invite only grants temporary membership |
#### Invite Delete
Sent when a guild invite is deleted. Requires the `MANAGE_CHANNELS` permission.
This event is not received by user accounts.
###### Invite Delete Structure
| Field | Type | Description |
| ---------- | --------- | --------------------------------------- |
| code | string | The invite code (unique ID) |
| channel_id | snowflake | The ID of the channel the invite is for |
| guild_id | snowflake | The ID of the guild this invite is for |
### Messages
Unlike persistent messages, ephemeral messages are sent directly to the user and the bot who sent the message rather than through the guild channel. Because of this, ephemeral messages are tied to the [`DIRECT_MESSAGES` intent](/gateway/using-gateway#list-of-intents), and the message object won't include `guild_id` or `member`.
###### Message Object Extra Fields
| Field | Type | Description |
| -------------------- | ------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------- |
| channel_type | integer | The [type of channel](/resources/channel#channel-type) this message was sent in |
| guild_id? ^1^ | snowflake | The ID of the guild the message was sent in |
| member? ^1^ ^2^ | partial [guild member](/resources/guild#guild-member-object) object | Guild member data for this message's author, without the [`user`](/resources/user#user-object) key |
| mentions ^1^ | array[partial [user](/resources/user#user-object) object] | Users specifically mentioned in the message, with an extra optional [`member`](/resources/guild#guild-member-object) key representing guild member data |
| metadata? | map[string, string] | Custom metadata for the message (max 25 keys, 1024 characters per key and value) |
| moderation_metadata? | map[string, string] | Custom moderation metadata for the message (max 5 keys, 2000 characters per key and value) |
^1^ Ephemeral messages will not include these fields.
^2^ Messages sent by webhooks will not include this field, as webhooks are not guild members.
#### Message Create
Sent when a message is created. The inner payload is a [message](/resources/message#message-object) object with the [extra structure](#message-object-extra-fields) above.
#### Message Update
Sent when a message is updated. The inner payload is a [message](/resources/message#message-object) object with the [extra structure](#message-object-extra-fields) above.
The value for `tts` will always be `false` in message updates.
#### Message Delete
Sent when a message is deleted.
###### Message Delete Structure
| Field | Type | Description |
| ---------- | --------- | --------------------- |
| id | snowflake | The ID of the message |
| channel_id | snowflake | The ID of the channel |
| guild_id? | snowflake | The ID of the guild |
#### Message Delete Bulk
Sent when multiple messages are deleted at once.
###### Message Delete Bulk Structure
| Field | Type | Description |
| ---------- | ---------------- | ------------------------------- |
| ids | array[snowflake] | The IDs of the removed messages |
| channel_id | snowflake | The ID of the channel |
| guild_id? | snowflake | The ID of the guild |
#### Message Ack
Sent when the channel read state is updated for the current user. This indicates that the user has read up to a specific message in a channel.
###### Message Ack Structure
| Field | Type | Description |
| ------------------ | --------- | ---------------------------------------------------------------------------- |
| ack_type? | integer | The [read state type](/topics/read-state#read-state-type) being acknowledged |
| channel_id | snowflake | The ID of the channel |
| message_id | snowflake | The ID of the last acknowledged message |
| manual? | boolean | Whether the acknowleged message ID is manually set |
| mention_count? ^1^ | integer | The number of mentions the user has in the channel |
| flags? ^1^ | ?integer | The [read state flags](/topics/read-state#read-state-flags) for the channel |
| last_viewed? ^1^ | ?integer | When the channel was last viewed (in days since the Discord epoch) |
| version | integer | The user read state version |
^1^ If omitted or `null`, the current value is retained.
#### Message Poll Vote Add
Sent when a user votes on a poll. If the poll allows multiple selection, one event will be sent per answer.
###### Message Poll Vote Add Structure
| Field | Type | Description |
| ---------- | --------- | ----------------- |
| user_id | snowflake | ID of the user |
| channel_id | snowflake | ID of the channel |
| message_id | snowflake | ID of the message |
| guild_id? | snowflake | ID of the guild |
| answer_id | integer | ID of the answer |
#### Message Poll Vote Remove
Sent when a user removes their vote on a poll. If the poll allows for multiple selections, one event will be sent per answer.
###### Message Poll Vote Remove Structure
| Field | Type | Description |
| ---------- | --------- | ----------------- |
| user_id | snowflake | ID of the user |
| channel_id | snowflake | ID of the channel |
| message_id | snowflake | ID of the message |
| guild_id? | snowflake | ID of the guild |
| answer_id | integer | ID of the answer |
#### Message Reaction Add
Sent when a user adds a reaction to a message.
###### Message Reaction Add Structure
| Field | Type | Description |
| ----------------- | ----------------------------------------------------- | -------------------------------------------------------- |
| user_id | snowflake | The ID of the user |
| channel_id | snowflake | The ID of the channel |
| message_id | snowflake | The ID of the message |
| message_author_id | snowflake | The ID of the message author |
| guild_id? | snowflake | The ID of the guild |
| member? | [member](/resources/guild#guild-member-object) object | The member who reacted |
| emoji | partial [emoji](/resources/emoji#emoji-object) object | The emoji used to react |
| type | integer | The [type of reaction](/resources/message#reaction-type) |
| burst_colors? | array[string] | The hex-encoded colors to render the burst reaction with |
#### Message Reaction Add Many
Sent when multiple users add reactions to a message in a short period of time.
This event requires the `DEBOUNCE_MESSAGE_REACTIONS` [Gateway capability](/gateway/using-gateway#gateway-capabilities).
###### Message Reaction Add Many Structure
| Field | Type | Description |
| ---------- | ----------------------------------------------------------------- | ---------------------------------- |
| channel_id | snowflake | The ID of the channel |
| message_id | snowflake | The ID of the message |
| guild_id? | snowflake | The ID of the guild |
| reactions | array[[debounced reaction](#debounced-reaction-structure) object] | The reactions added to the message |
#### Debounced Reaction Structure
| Field | Type | Description |
| ----- | ----------------------------------------------------- | ------------------------------------------------ |
| users | array[snowflake] | The IDs of the users who reacted with this emoji |
| emoji | partial [emoji](/resources/emoji#emoji-object) object | The emoji used to react |
#### Message Reaction Remove
Sent when a user removes a reaction from a message.
###### Message Reaction Remove Structure
| Field | Type | Description |
| ---------- | ------------------------------------------------------- | -------------------------------------------------------- |
| user_id | snowflake | The ID of the user |
| channel_id | snowflake | The ID of the channel |
| message_id | snowflake | The ID of the message |
| guild_id? | snowflake | The ID of the guild |
| emoji | a partial [emoji](/resources/emoji#emoji-object) object | The emoji used to react |
| type | integer | The [type of reaction](/resources/message#reaction-type) |
#### Message Reaction Remove All
Sent when a user explicitly removes all reactions from a message.
###### Message Reaction Remove All Structure
| Field | Type | Description |
| ---------- | --------- | --------------------- |
| channel_id | snowflake | The ID of the channel |
| message_id | snowflake | The ID of the message |
| guild_id? | snowflake | The ID of the guild |
#### Message Reaction Remove Emoji
Sent when a user removes all instances of a given emoji from the reactions of a message.
###### Message Reaction Remove Emoji Structure
| Field | Type | Description |
| ---------- | ----------------------------------------------------- | -------------------------- |
| channel_id | snowflake | The ID of the channel |
| message_id | snowflake | The ID of the message |
| guild_id? | snowflake | The ID of the guild |
| emoji | partial [emoji object](/resources/emoji#emoji-object) | The emoji that was removed |
#### Reaction Notification Sent
Sent when a user reacts to a message authored by the current user.
###### Reaction Notification Sent Structure
| Field | Type | Description |
| --------------- | ----------------------------------------------------- | -------------------------------------------------------------------- |
| message | [message](/resources/message#message-object) object | The message that was reacted to |
| reactor_user_id | snowflake | The ID of the user who reacted |
| emoji | partial [emoji](/resources/emoji#emoji-object) object | The emoji used to react |
| title | string | The notification title |
| body | string | The notification body text |
| icon | string | The notification icon URL |
| route | string | The client route opened by the notification |
| tracking_type | string | The notification tracking type (always `reaction_push_notification`) |
#### Recent Mention Delete
Sent when a message that mentioned the current user in the last week is acknowledged and deleted.
###### Recent Mention Delete Structure
| Field | Type | Description |
| ---------- | --------- | --------------------- |
| message_id | snowflake | The ID of the message |
#### Last Messages
Sent in response to [Request Last Messages](#request-last-messages).
###### Last Messages Structure
| Field | Type | Description |
| -------- | ---------------------------------------------------------- | --------------------------------------- |
| guild_id | snowflake | The ID of the guild |
| messages | array[[message](/resources/message#message-object) object] | Last messages of the requested channels |
### Notification Center
#### Notification Center Item Create
Sent when a notification center item is created. The inner payload is a [notification center item](/resources/notification-center#notification-center-item-object) object.
#### Notification Center Item Delete
Sent when a notification center item is deleted.
###### Notification Center Item Delete Structure
| Field | Type | Description |
| ------- | --------- | ---------------------------------------------- |
| id | snowflake | The ID of the deleted notification center item |
| user_id | snowflake | The ID of the current user |
#### Notification Center Items Ack
Sent when a notification center item is acknowledged.
###### Notification Center Items Ack Structure
| Field | Type | Description |
| ----- | --------- | --------------------------------------------------- |
| id | snowflake | The ID of the acknowledged notification center item |
#### Notification Center Item Completed
Sent when a notification center action set is completed.
###### Notification Center Item Completed Structure
| Field | Type | Description |
| --------- | ------- | -------------------------------------------------------------------------------------------------------------- |
| item_enum | integer | The [type of completed notification center item](/resources/notification-center#notification-center-item-enum) |
### Notification Settings
#### Notification Settings Update
Sent when a user's notification settings are updated. The inner payload is a [notification settings](/resources/user-settings#notification-settings-object) object.
### OAuth2
#### OAuth2 Token Create
Sent when an OAuth2 authorization is created. The inner payload is an [OAuth2 authorization](/topics/oauth2#oauth2-authorization-object) object.
#### OAuth2 Token Delete
Sent when an OAuth2 authorization is deleted.
###### OAuth2 Token Delete Structure
| Field | Type | Description |
| -------------- | --------- | ---------------------------------------------------------------- |
| id | snowflake | The ID of the deleted authorization |
| application_id | snowflake | The ID of the OAuth2 application whose authorization was deleted |
#### OAuth2 Token Revoke
Sent when an OAuth2 token is revoked.
###### OAuth2 Token Revoke Structure
| Field | Type | Description |
| --------------- | --------- | -------------------------------------------------------- |
| access_token | string | The access token that was revoked |
| application_id? | snowflake | The ID of the OAuth2 application whose token was revoked |
### Payments
#### Payment Update
Sent when a payment is updated. The inner payload is a [payment](/resources/payment#payment-object) object.
### Presence
#### Presence Update
This event is sent when a user's presence or info, such as name or avatar, is updated. The inner payload is a [presence](/resources/presence#presence-object) object.
For user accounts, this event is only sent for presences they are subscribed to. Users are automatically subscribed to the overall user presence and every per-guild presence of [friends and implicit relationships](/resources/relationships#relationship-object) (depending on the `NO_AFFINE_USER_IDS` [Gateway capability](/gateway/using-gateway#gateway-capabilities)), as well as every per-guild presences of users they have an open DM with.
If you are using [Gateway intents](/gateway/using-gateway#gateway-intents), you _must_ specify the `GUILD_PRESENCES` intent in order to receive Presence Update events.
Presence Update events are never received for the user's own presence. You _must_ track your own presence locally, or via the [Sessions Replace](#sessions-replace) event.
The `user` object within this event can be very partial. The only field which is guaranteed is the `id` field, everything else is optional.
Along with this limitation, no fields are required, and the types of the fields are **not** validated. Your client should expect any combination of fields and types within this event.
### Quests
#### Quests User Status Update
Sent when a user's quest status is updated.
###### Quests User Status Update Structure
| Field | Type | Description |
| ----------- | ---------------------------------------------------------------------- | ------------------------- |
| user_status | [quest user status](/resources/quests#quest-user-status-object) object | The user's quest progress |
#### Quests User Completion Update
Sent when a user's quest completion eligibility is updated.
###### Quests User Completion Update Structure
| Field | Type | Description |
| ------------------------------ | ------------------ | ---------------------------------------- |
| quest_enrollment_blocked_until | ?ISO8601 timestamp | When the user can enroll in quests again |
### Relationships
###### Partial Relationship Structure
| Field | Type | Description |
| ----------------- | ----------------- | ---------------------------------------------------------------------------------------------------------------------------- |
| id | snowflake | The ID of the target user |
| type | integer | The [type](/resources/relationships#relationship-type) of relationship |
| nickname | ?string | The nickname of the user in this relationship (1-32 characters) |
| since? | ISO8601 timestamp | When the user requested a relationship |
| stranger_request? | boolean | Whether the friend request was sent by a user without a mutual friend or small mutual guild (default false) |
| user_ignored | boolean | Whether the target user has been [ignored](https://support.discord.com/hc/en-us/articles/28084948873623) by the current user |
#### Relationship Add
Sent when a relationship is created, relevant to the current user. Inner payload is a [relationship](/resources/relationships#relationship-object) object.
###### Relationship Add Structure Extra Fields
| Field | Type | Description |
| -------------- | ------- | ------------------------------------------------------------------------- |
| should_notify? | boolean | Whether the client should notify the user of this relationship's creation |
#### Relationship Update
Sent when a relationship is updated, relevant to the current user (e.g. friend nickname changed). Inner payload is a [partial relationship](#partial-relationship-structure) object.
This is not sent when the type of a relationship changes; see [Relationship Add](#relationship-add) for that.
#### Relationship Remove
Sent when a relationship is removed, relevant to the current user. Inner payload is a [partial relationship](#partial-relationship-structure) object.
#### Game Relationship Add
Sent when a game relationship is created, relevant to the current user. Inner payload is a [game relationship](/resources/relationships#game-relationship-object) object.
#### Game Relationship Remove
Sent when a game relationship is removed, relevant to the current user.
###### Game Relationship Remove Structure
| Field | Type | Description |
| -------------- | ----------------- | ----------------------------------------------------------------------------------- |
| id | string | The ID of the target user |
| application_id | snowflake | The ID of the application whose game the relationship originated from |
| type | integer | The [type](/resources/relationships#game-relationship-type) of relationship |
| since | ISO8601 timestamp | When the user requested a relationship |
| dm_access_type | integer | The [DM access level](/resources/relationships#dm-access-type) for the relationship |
| user_id | snowflake | The ID of the current user |
### Game Invites
#### Game Invite Create
Sent when a game invite is received. The inner payload is a [game invite](/resources/game-invite#game-invite-object) object.
#### Game Invite Delete
Sent when a game invite is deleted.
###### Game Invite Delete Structure
| Field | Type | Description |
| --------- | --------- | ------------------------- |
| invite_id | snowflake | The ID of the game invite |
#### Game Invite Delete Many
Sent when some game invites are deleted.
###### Game Invite Delete Many Structure
| Field | Type | Description |
| ---------- | ---------------- | ----------------------------------- |
| invite_ids | array[snowflake] | The IDs of the deleted game invites |
### Lobbies
#### Gateway Lobby Object
[Lobby](/resources/lobby#lobby-object) objects received over the Gateway have extended attributes that are not provided in the REST API.
###### Gateway Lobby Structure Extra Fields
| Field | Type | Description |
| ------------ | ---------------------------------------------------------------------- | ------------------------------------------------------------------------------------ |
| voice_states | array[[lobby voice state](/resources/voice#voice-state-object) object] | The voice states of the users already in the lobby |
| region | string | The [voice region](/resources/voice#voice-region-object) ID the lobby is hosted from |
| metadata | ?map[string, string] | The metadata of the lobby |
###### Lobby Deletion Reason
| Value | Description |
| ------- | --------------------- |
| deleted | The lobby was deleted |
| removed | The user was removed |
#### Lobby Create
Sent when a lobby is updated. The inner payload is a [gateway lobby](#gateway-lobby-object) object.
#### Lobby Update
Sent when a lobby is updated. The inner payload is a [gateway lobby](#gateway-lobby-object) object.
#### Lobby Delete
Sent when a lobby is deleted or the user is removed from a lobby.
###### Lobby Delete Structure
| Field | Type | Description |
| ------ | --------- | --------------------------------------------------- |
| id | snowflake | The ID of the lobby |
| reason | string | The [lobby deletion reason](#lobby-deletion-reason) |
#### Lobby Member Add
Sent when an user joins a lobby.
###### Lobby Member Add Structure
| Field | Type | Description |
| -------------- | ----------------------------------------------------------- | ------------------------------------------------ |
| member | [lobby member](/resources/lobby#lobby-member-object) object | The added member |
| lobby_id | snowflake | The ID of the lobby |
| application_id | snowflake | The ID of the application that created the lobby |
#### Lobby Member Connect
Sent when an user joins a lobby call.
###### Lobby Member Connect Structure
| Field | Type | Description |
| -------- | ----------------------------------------------------------- | --------------------------------- |
| member | [lobby member](/resources/lobby#lobby-member-object) object | The member that joined lobby call |
| lobby_id | snowflake | The ID of the lobby |
#### Lobby Member Disconnect
Sent when an user leaves a lobby call.
###### Lobby Member Disconnect Structure
| Field | Type | Description |
| -------- | ----------------------------------------------------------- | ------------------------------- |
| member | [lobby member](/resources/lobby#lobby-member-object) object | The member that left lobby call |
| lobby_id | snowflake | The ID of the lobby |
#### Lobby Member Update
Sent when a lobby member is updated.
###### Lobby Member Update Structure
| Field | Type | Description |
| -------------- | ----------------------------------------------------------- | ------------------------------------------------ |
| member | [lobby member](/resources/lobby#lobby-member-object) object | The updated member |
| lobby_id | snowflake | The ID of the lobby |
| application_id | snowflake | The ID of the application that created the lobby |
#### Lobby Member Remove
Sent when a lobby member is removed.
###### Lobby Member Remove Structure
| Field | Type | Description |
| -------------- | ----------------------------------------------------------- | ------------------------------------------------ |
| member | [lobby member](/resources/lobby#lobby-member-object) object | The removed member |
| lobby_id | snowflake | The ID of the lobby |
| application_id | snowflake | The ID of the application that created the lobby |
#### Lobby Message Create
Sent when a lobby message is created. The inner payload is a [message](/resources/message#message-object) object with the [extra structure](#message-object-extra-fields) above.
When the lobby does not have a channel linked, the message will be a partial [message](/resources/message#message-object) object.
#### Lobby Message Update
Sent when a lobby message is updated. The inner payload is a [message](/resources/message#message-object) object with the [extra structure](#message-object-extra-fields) above.
When the lobby does not have a channel linked, the message will be a partial [message](/resources/message#message-object) object.
The value for `tts` will always be `false` in message updates.
#### Lobby Message Delete
Sent when a lobby message is deleted.
###### Message Delete Structure
| Field | Type | Description |
| -------- | --------- | --------------------- |
| id | snowflake | The ID of the message |
| lobby_id | snowflake | The ID of the lobby |
#### Lobby Voice State Update
Sent when someone joins/leaves/moves lobbies. Inner payload is a [lobby voice state](/resources/voice#voice-state-object) object.
#### Lobby Voice Server Update
Sent when a lobby's voice server is updated. This is sent when initially connecting to voice, and when the current voice instance fails over to a new server.
A `null` endpoint means that the voice server allocated has gone away and is trying to be reallocated. You should attempt to disconnect from the currently connected voice server, and not attempt to reconnect until a new voice server is allocated.
###### Lobby Voice Server Update Structure
| Field | Type | Description |
| -------- | --------- | ----------------------------------------- |
| token | string | The voice connection token |
| lobby_id | snowflake | The lobby this voice server update is for |
| endpoint | ?string | The voice server host |
###### Example Lobby Voice Server Update
```json
{
"token": "66d29164ee8cd919",
"lobby_id": "41771983423143937",
"endpoint": "smart.loyal.discord.media:1337"
}
```
### Passive Update
#### Passive Update V1
Sent periodically to inform the client of the current unread state and active voice states in guilds it's not subscribed to.
This event requires the `PASSIVE_GUILD_UPDATE` [Gateway capability](/gateway/using-gateway#gateway-capabilities).
###### Passive Update V1 Structure
| Field | Type | Description |
| ----------------- | ------------------------------------------------------------------ | ---------------------------------------------------------- |
| guild_id | snowflake | The ID of the guild |
| channels | array[[channel unread](#channel-unread-structure) object] | The unread states for channels in the guild |
| voice_states? ^1^ | array[[voice state](/resources/voice#voice-state-object) object] | The voice states of the users in the guild |
| members? | array[[guild member](/resources/guild#guild-member-object) object] | The members corresponding to the voice states in the guild |
^1^ If empty or omitted, there are no voice states in the guild.
#### Passive Update V2
Sent periodically to inform the client of the current unread state and active voice states in guilds it's not subscribed to.
Functionally the same as [Passive Update V1](#passive-update-v1), but uses a more efficient format.
This event requires the `PASSIVE_GUILD_UPDATE_V2` [Gateway capability](/gateway/using-gateway#gateway-capabilities).
###### Passive Update V2 Structure
| Field | Type | Description |
| -------------------- | ------------------------------------------------------------------ | ------------------------------------------------------------------- |
| guild_id | snowflake | The ID of the guild |
| updated_channels | array[[channel unread](#channel-unread-structure) object] | The modified unread states for channels in the guild |
| updated_voice_states | array[[voice state](/resources/voice#voice-state-object) object] | The modified voice states of the users in the guild |
| removed_voice_states | array[snowflake] | The IDs of the users who no longer have voice states in the guild |
| updated_members | array[[guild member](/resources/guild#guild-member-object) object] | The members corresponding to the modified voice states in the guild |
### Saved Messages
#### Saved Message Create
Sent when a message is saved. The inner payload is a [saved message](/resources/user#saved-message-structure) object.
#### Saved Message Delete
Sent when a message is unsaved.
###### Saved Message Delete Structure
| Field | Type | Description |
| ---------- | --------- | --------------------- |
| channel_id | snowflake | The ID of the channel |
| message_id | snowflake | The ID of the message |
### Sessions
#### Sessions Replace
Sent when the current user's session list or presence is updated. The inner payload is a list of [session](/resources/presence#session-object) objects.
### Stage Instances
#### Stage Instance Create
Sent when a [stage instance](/resources/stage-instance) is created (i.e. the stage is now "live"). The inner payload is a [stage instance](/resources/stage-instance#stage-instance-object) object.
#### Stage Instance Update
Sent when a [stage instance](/resources/stage-instance) is updated. The inner payload is a [stage instance](/resources/stage-instance#stage-instance-object) object.
#### Stage Instance Delete
Sent when a [stage instance](/resources/stage-instance) is deleted (i.e. the stage has been closed). The inner payload is a [stage instance](/resources/stage-instance#stage-instance-object) object.
### Streams
#### Stream Object
###### Stream Structure
| Field | Type | Description |
| ------------------ | --------- | ----------------------------------------------------------------------- |
| stream_key | string | The [stream key](#stream-key) |
| rtc_server_id ^1^ | snowflake | The ID of the RTC server for the stream, used when connecting to voice |
| rtc_channel_id ^1^ | snowflake | The ID of the RTC channel for the stream, used when connecting to voice |
| region | string | The voice region the stream is in |
| viewer_ids | array | The IDs of the viewers currently watching the stream |
| paused | boolean | Whether the stream is paused |
^1^ Only present in [Stream Create](#stream-create) Gateway events.
###### Stream Key
The stream key is a unique identifier for a stream, represented as a colon-delimited list of values. The first value is the type of stream, followed by the location of the stream, and finally the owner of the stream.
###### Stream Key Structure
| Field | Type | Description |
| ----------- | --------- | --------------------------------------- |
| type | string | The [type of stream](#stream-type) |
| guild_id? | snowflake | The ID of the guild being streamed to |
| channel_id? | snowflake | The ID of the channel being streamed to |
| owner_id | snowflake | The ID of the user who owns the stream |
###### Stream Type
| Value | Description |
| ----- | ------------------------------------------------------------------------- |
| guild | A stream in a guild voice channel |
| call | A stream in a DM call |
| test | A stream used for speed tests; not encountered in regular stream contexts |
###### Example Stream Key
```md
- guild:839502008108580904:850360749460553769:852892297661906993
- call:1110739331624210483:852892297661906993
- test:852892297661906993
```
###### Example Stream
```json
{
"stream_key": "call:1110739331624210483:852892297661906993",
"rtc_server_id": "1278201813102755892",
"rtc_channel_id": "1278201813102755893",
"region": "us-east",
"viewer_ids": ["193696591125807105"],
"paused": false
}
```
#### Stream Create
Sent when a stream is created. The inner payload is a [stream](#stream-object) object.
#### Stream Server Update
Sent when a stream's voice server is updated. This is sent when initially connecting to a stream, and when the current stream instance fails over to a new server.
A `null` endpoint means that the voice server allocated has gone away and is trying to be reallocated. You should attempt to disconnect from the currently connected voice server, and not attempt to reconnect until a new voice server is allocated.
###### Stream Server Update Structure
| Field | Type | Description |
| ---------- | ------- | -------------------------- |
| token | string | The voice connection token |
| stream_key | string | The stream key |
| endpoint | ?string | The voice server host |
###### Example Stream Server Update
```json
{
"token": "91f8016f34a5cd17",
"stream_key": "call:1110739331624210483:852892297661906993",
"guild_id": null,
"endpoint": "smart.loyal.discord.media:1337"
}
```
#### Stream Update
Sent when a stream is updated. The inner payload is a [stream](#stream-object) object.
#### Stream Delete
Sent when a stream is deleted, or becomes unavailable due to an outage.
###### Stream Delete Structure
| Field | Type | Description |
| ------------ | ------- | --------------------------------------------------------- |
| stream_key | string | The stream key |
| reason | string | The [reason for ending the stream](#stream-delete-reason) |
| unavailable? | boolean | Whether the stream is unavailable due to an outage |
###### Stream Delete Reason
| Value | Description |
| ------------------------- | ------------------------------------------------------ |
| user_requested | The user requested to end the stream |
| stream_ended | The client was disconnected because the stream ended |
| stream_full | The client attempted to join a full stream |
| unauthorized | The client is not authorized to view the stream |
| safety_guild_rate_limited | The stream was rate limited due to guild restrictions |
| parse_failed | Parsing the stream key failed |
| invalid_channel | The provided channel is not valid for this stream type |
###### Example Stream Delete
```json
{
"stream_key": "call:1110739331624210483:852892297661906993",
"reason": "stream_ended"
}
```
#### Speed Test Create
Sent when an RTC speed test is created. Speed tests are a special type of stream used to test connection quality. Same as [Stream Create](#stream-create).
#### Speed Test Server Update
Sent when a speed test's voice server is updated. Same as [Stream Server Update](#stream-server-update).
#### Speed Test Update
Sent when a speed test is updated. Same as [Stream Update](#stream-update).
#### Speed Test Delete
Sent when a speed test is deleted. Same as [Stream Delete](#stream-delete).
### Typing
#### Typing Start
Sent when a user starts typing in a channel.
###### Typing Start Structure
| Field | Type | Description |
| ---------- | ----------------------------------------------------- | --------------------------------------------------------- |
| channel_id | snowflake | id of the channel |
| guild_id? | snowflake | id of the guild |
| user_id | snowflake | id of the user |
| timestamp | integer | unix time (in seconds) of when the user started typing |
| member? | [member](/resources/guild#guild-member-object) object | the member who started typing if this happened in a guild |
### Current User
#### User Update
Sent when properties about the current user change. Inner payload is a [user](/resources/user#user-object) object.
#### User Application Update
Sent when an integrated application is authorized or updated.
###### User Application Remove Structure
| Field | Type | Description |
| -------------- | --------- | ------------------------- |
| application_id | snowflake | The ID of the application |
#### User Application Remove
Sent when the current user deauthorizes an integrated application.
###### User Application Remove Structure
| Field | Type | Description |
| -------------- | --------- | ------------------------- |
| application_id | snowflake | The ID of the application |
#### User Application Identity Update
Sent when application identity is updated for the current user. The inner payload is an [user application profile](#user-application-profile-structure) object.
#### User Application Identity Remove
Sent when application identity is removed for the current user.
###### User Application Identity Remove Structure
| Field | Type | Description |
| -------------- | --------- | ------------------------- |
| user_id | snowflake | The ID of the user |
| application_id | snowflake | The ID of the application |
#### User Connections Update
Sent when the current user has their connections updated. Inner payload is either a [connection](/resources/connected-accounts#connection-object) object, or the following object:
###### User Connections Update Structure
| Field | Type | Description |
| ------- | --------- | -------------------------- |
| user_id | snowflake | The ID of the current user |
#### User Guild Settings Update
Sent when a guild's user settings are updated. Inner payload is [user guild settings](/resources/user-settings#user-guild-settings-object) object.
#### User Merge Operation Completed
Sent when the current user has their account merged with a provisional account. When this is sent, the following has occured:
- Relationships from the provisional account have been moved to the current user.
- Game relationships from the provisional account have been moved to the current user.
- Lobby memberships from the provisional account have been moved to the current user.
- DMs from the provisional account have been migrated to the current user. If there is a conflict, a group DM is created.
- Users that have blocked the provisional account now block the current user.
###### User Merge Operation Completed Structure
| Field | Type | Description |
| ------------------ | --------- | ------------------------------------------ |
| merge_operation_id | snowflake | The ID of the merge operation |
| source_user_id | snowflake | The ID of the account that was merged with |
#### User Non Channel Ack
Sent when the user updates the read state for a non-channel feature, such as notification center.
###### User Non Channel Ack Structure
| Field | Type | Description |
| ----------- | --------- | -------------------------------------------------------------------- |
| ack_type | integer | The [type of read state](/topics/read-state#read-state-type) updated |
| resource_id | snowflake | The ID of the user |
| entity_id | snowflake | The ID of the last acknowledged entity |
| version | integer | The user read state version |
#### User Note Update
Sent when a note the current user has on another user is modified.
###### User Note Update Structure
| Field | Type | Description |
| ----- | --------- | ------------------------- |
| id | snowflake | The ID of the user |
| note | string | The new note for the user |
#### User Premium Guild Subscription Slot Create
Sent when an user premium guild subscription slot is created. The inner payload is a [premium guild subscription slot](/resources/subscription#premium-guild-subscription-slot-object) object.
#### User Premium Guild Subscription Slot Update
Sent when an user premium guild subscription slot is updated. The inner payload is a [premium guild subscription slot](/resources/subscription#premium-guild-subscription-slot-object) object.
#### User Premium Guild Subscription Slot Delete
Sent when an user premium guild subscription slot is deleted. The inner payload is a [premium guild subscription slot](/resources/subscription#premium-guild-subscription-slot-object) object.
#### User Settings Proto Update
Sent when the client protobuf user settings are modified.
###### User Settings Proto Update Structure
| Field | Type | Description |
| -------- | ------------------------------------------------------------ | ------------------------------------------------------------------------------------------- |
| settings | [user settings proto](#user-settings-proto-structure) object | The new user settings |
| partial | boolean | Whether the settings update is partial (should be merged with the existing cached settings) |
###### User Settings Proto Structure
| Field | Type | Description |
| ----- | ------- | ------------------------------------------------------------------------------------ |
| type | integer | The [type of user settings](/resources/user-settings-proto#user-settings-proto-type) |
| proto | string | The base64-encoded serialized user settings protobuf |
#### User Settings Update
Sent when the client user settings are modified. Inner payload is a partial [user settings](/resources/user-settings#user-settings-object) object with only the modified fields serialized.
This event is not sent when using the `USER_SETTINGS_PROTO` [Gateway capability](/gateway/using-gateway#gateway-capabilities).
#### Audio Settings Update
Sent when audio context settings are modified. Only modified settings are sent.
###### Audio Settings Update Structure
| Field | Type | Description |
| ------ | --------------------------------------------------------------------------------------------- | --------------------------------------- |
| user | map[snowflake, [audio context setting](/resources/user-settings#audio-context-object) object] | Audio context settings for users |
| stream | map[snowflake, [audio context setting](/resources/user-settings#audio-context-object) object] | Audio context settings for user streams |
#### User Payment Browser Checkout Done
Sent when the current user finished checking out a purchase in-browser.
###### User Payment Browser Checkout Done Structure
| Field | Type | Description |
| ------------------------ | ---------- | --------------------------------------------------------------------- |
| load_id | ?string | A client-generated UUID used to identify the current checkout session |
| sku_id | ?snowflake | The ID of the SKU |
| sku_subscription_plan_id | ?snowflake | The ID of the subscription plan the purchase was for |
#### User Payment Client Add
Sent when the client user has a payment client authorized.
###### User Payment Client Add Structure
| Field | Type | Description |
| ------------------- | ----------------- | ------------------------------------------------------- |
| purchase_token_hash | string | The base64-encoded SHA-256 digest of the purchase token |
| expires_at | ISO8601 timestamp | When the payment client expires |
#### User Payment Sources Update
Sent when the client user's payment sources were updated. Inner payload is `null`.
#### User Required Action Update
Sent when the client user must complete a certain action (such as verifying their phone number) before continuing to use Discord.
###### User Required Action Update Structure
| Field | Type | Description |
| --------------- | ------- | --------------------------------------------------------------------------------------------------------------------------------------------------------- |
| required_action | ?string | The [action a user is required to take](/resources/user#required-action-type) before continuing to use Discord, `null` if an action is no longer required |
#### User Subscriptions Update
Sent when the client user's subscriptions were updated. Inner payload is `null`.
### Voice
#### Voice State Update
Sent when someone joins/leaves/moves voice channels or calls. Inner payload is a [voice state](/resources/voice#voice-state-object) object.
#### Voice Server Update
Sent when a guild or call's voice server is updated. This is sent when initially connecting to voice, and when the current voice instance fails over to a new server.
A `null` endpoint means that the voice server allocated has gone away and is trying to be reallocated. You should attempt to disconnect from the currently connected voice server, and not attempt to reconnect until a new voice server is allocated.
###### Voice Server Update Structure
| Field | Type | Description |
| ----------- | ---------- | --------------------------------------------------- |
| token | string | The voice connection token |
| guild_id | ?snowflake | The guild this voice server update is for |
| channel_id? | snowflake | The private channel this voice server update is for |
| endpoint | ?string | The voice server host |
###### Example Voice Server Update
```json
{
"token": "66d29164ee8cd919",
"guild_id": "41771983423143937",
"endpoint": "smart.loyal.discord.media:1337"
}
```
#### Voice Channel Effect Send
Sent when someone sends an effect, such as an emoji reaction or a soundboard sound, in a voice channel the current user is connected to.
###### Voice Channel Effect Send Structure
| Field | Type | Description |
| -------------- | ------------------------------------------------------ | ----------------------------------------------------------------------------------- |
| channel_id | snowflake | The ID of the channel the effect was sent in |
| guild_id | snowflake | The ID of the guild the effect was sent in |
| user_id | snowflake | The ID of the user who sent the effect |
| animation_type | ?integer | The [type of emoji animation](/resources/voice#voice-channel-effect-animation-type) |
| animation_id | integer | The ID of the emoji animation (0-20) |
| emoji | ?partial [emoji](/resources/emoji#emoji-object) object | The emoji sent, if applicable |
| sound_id? | snowflake | The ID of the soundboard sound |
| sound_volume? | float | The volume of the soundboard sound (represented as a float from 0 to 1) |
###### Example Voice Channel Effect Send
```json
{
"guild_id": "839502008108580904",
"animation_id": 0,
"animation_type": 1,
"channel_id": "850360749460553769",
"emoji": {
"animated": false,
"id": null,
"name": "🦆"
},
"sound_id": 1,
"sound_volume": 1,
"user_id": "852892297661906993"
}
```
#### Voice Channel Start Time Update
Sent when a voice channel session is started or ended.
###### Voice Channel Start Time Update Structure
| Field | Type | Description |
| ---------------- | --------- | ---------------------------------------------------------------------------------------------------- |
| id | snowflake | The ID of the voice channel |
| guild_id | snowflake | The ID of the guild |
| voice_start_time | ?integer | The unix timestamp (in seconds) of when the current voice session started, or `null` if it was ended |
#### Voice Channel Status Update
Sent when a voice channel's status is updated.
###### Voice Channel Status Update Structure
| Field | Type | Description |
| -------- | --------- | ---------------------------------------------------- |
| id | snowflake | The ID of the voice channel |
| guild_id | snowflake | The ID of the guild |
| status | ?string | The status of the voice channel (max 500 characters) |
### Virtual Currency
#### Virtual Currency Balance Update
Sent when the current user's Orbs balance is updated.
###### Virtual Currency Balance Update Structure
| Field | Type | Description |
| ------- | ------- | --------------------------- |
| balance | integer | Amount of Orbs the user has |
### Webhooks
#### Webhooks Update
Sent when a guild channel's webhook is created, updated, or deleted.
###### Webhooks Update Structure
| Field | Type | Description |
| ---------- | --------- | --------------------- |
| guild_id | snowflake | The ID of the guild |
| channel_id | snowflake | The ID of the channel |
---
# Experiments
Link: https://docs.discord.food/topics/experiments
Experiments are a form of A/B testing used by Discord in the client- and server-side of their applications to serve
different experiences or behaviours to different users randomly and/or based on location, client version, etc.
Currently, Discord uses two different systems for experiments: the legacy system, which encapsulates user and guild experiments,
and the new Apex system, which is more flexible but provides clients with less data. Both systems are still in use,
but most new experiments are created in the Apex system, so the legacy system will eventually be deprecated.
At their core, rollouts are simply YAML inputted into the Discord admin panel; however, not all of the data
is required by clients. Therefore, the actual experiments clients see are minified and complex to decipher.
## Fingerprints
Even the marketing website uses A/B tests to hook users into the app. Therefore, the app needs a unique way to identify the
person using the website without using authentication (for users initially visiting the landing page), so it resorts to using
"fingerprints".
These aren't the usual fingerprints generated by collecting information about the browser; instead, they are snowflakes generated
by unauthenticated requests to [Get Experiment Assignments](#get-experiment-assignments). It is expected that fingerprints are sent
in the `X-Fingerprint` header in all subsequent requests to the API until authentication, in order to track A/B tests and allow
access to API-locked portions of experiments.
A fingerprint is comprised of a snowflake and a hashed cryptographic value. It looks like this: `1084179945133187083.JQddgNMmwJPghoBtFmaH7jTmdsw`.
When registering a new account, the fingerprint is passed, and (if valid) is used as the created user's ID. This is done in order
to preserve experiments across to the registered user. Therefore, a user account's creation time theoretically represents the first
time they visited Discord's marketing website.
## Installations
The new Apex experiment system introduces the concept of installations, which are a unique identifier for a specific installation of a Discord client.
This allows experiments to be targeted not just by user or guild, but by specific app installations, enabling more granular testing and rollouts.
Installations use an ID system very similar to fingerprints. The biggest difference is that they persist even after authentication. If a client already has
an installation ID, it should be sent in the `X-Installation-ID` header in all requests to the API, and provided in the `installation_id` field when
[identifying](/gateway/using-gateway#identifying) with the Gateway. If an installation ID is invalid or not provided, a new one will be provided in the `installation` field of
the response body of the [Get Apex Experiment Assignments](#get-apex-experiment-assignments) endpoint, or the `apex_experiments` field in the [Ready event](/gateway/gateway-events#ready).
## Rollouts
Legacy experiment rollouts are defined in _populations_ based on the user or guild's [rollout position](#rollout-positions)
and can have _filters_ to narrow each population's availability.
###### Example Rollout
Note that this example is editorial and does not exactly represent how experiments are represented internally.
```md
2023-02_stage_boosting (1816004721)
### Treatment 1
Filters
Guild Features: [COMMUNITY]
Member Count Range: 1000 - null
Hash Range: Hash Key: 1816004721, Target: 10000
Position Ranges
5000-9500, 9500-10000
### Control
Filters
Guild Features: [COMMUNITY]
Member Count Range: 1000 - null
Position Ranges
0 - 10000
### None
Position Ranges
0 - 10000
```
### Treatments
`Control` and `None` are represented in rollouts as the integer values `0` and `-1`, respectively. Note that there are some instances of experiments having specific unnecessary treatments
labelled as `Control` with different treatment values.
### Rollout Positions
A rollout position is calculated using the following pseudo code, where `exp_name` is the human readable name for the experiment and `resource_id` is the user, fingerprint or guild's ID.
This position is used in conjunction with the rollout populations and filters to figure out what the assigned bucket for the experiments are by simply checking which treatment the population is included in.
```py
result = mmh3.hash('exp_name:resource_id', signed=False) % 10000
```
## Data Structures
There are two types of experiments, user experiments and guild experiments. Metadata and human-readable experiment names
are available in the user-facing clients. However, API objects do not contain such data, except for guild experiments which may have a human-readable name provided for hash calculations, overriding the one in clients.
Most of the below objects are represented as arrays following the order the fields are documented in.
### User Experiments
User experiment data returned by the API is very limited. In contrast to the wide range of data the API provides for
guild rollouts, the only values we can programmatically retrieve from the API are the user or [fingerprint](#fingerprints)'s assigned
bucket for the experiment.
User experiments are subject to the same functionality and filters as guild experiments, despite only the calculated final data being provided.
###### User Experiment Structure
This object is represented as an array of the following fields:
| Field | Type | Description |
| -------------------- | -------- | --------------------------------------------------------------------------------------------------------- |
| hash | integer | 32-bit unsigned Murmur3 hash of the experiment's name |
| revision | integer | Current version of the rollout |
| bucket | integer | The requesting user or fingerprint's assigned experiment bucket |
| override | integer | Whether the user or fingerprint has an override for the experiment (`-1` for false, `0` for true) |
| population | integer | The internal population group the requesting user or fingerprint is in |
| hash_result | integer | The calculated [rollout position](#rollout-positions) to use, prioritized over local calculations |
| aa_mode ^1^ | integer | The experiment's A/A testing mode, represented as an integer-casted boolean |
| trigger_debugging | integer | Whether the experiment's analytics trigger debugging is enabled, represented as an integer-casted boolean |
| holdout_name ^2^ | ?string | A human-readable experiment name (formatted as `year-month_name`) that disables the experiment |
| holdout_revision ^2^ | ?integer | The revision of the holdout experiment |
| holdout_bucket ^2^ | ?integer | The requesting user or fingerprint's assigned bucket for the holdout experiment |
^1^ The bucket for A/A tested experiments should always be None (`-1`) unless an override is present for the resource.
^2^ Holdout information is only present if the user or fingerprint has an assigned bucket for the holdout experiment.
Therefore, if holdout experiment information is present and the population bucket is set to None (`-1`), the experiment has been disabled by the holdout.
As user experiments are opaque, no client handling is required for this field. Just follow the `population` field as usual.
###### Example User Experiment
```json
[826493636, 3, -1, -1, 0, 203, 0, 1, "2025-02_user_profile_editing", 2, 0]
```
### Guild Experiments
The data provided here is more detailed, because the client has to figure out itself the assigned bucket for each guild. It may
seem daunting to parse this given the sheer amount of arrays, but it's really quite simple.
While rare, there have been cases in the past of guild experiments used to control group DM rollouts. In these cases, the API remains entirely the same, but filters that cannot apply to group DMs are not used.
An example of this is the `2025-04_gdm_bedazzling` experiment.
###### Guild Experiment Structure
This object is represented as an array of the following fields:
| Field | Type | Description |
| ----------------------- | ------------------------------------------------------------------------------ | ----------------------------------------------------------------------------------------------------------------------------------- |
| hash | integer | 32-bit unsigned Murmur3 hash of the experiment's name |
| hash_key ^1^ | ?string | A human-readable experiment name (formatted as `year-month_name`) to use for hashing calculations, prioritized over the client name |
| revision | integer | Current version of the rollout |
| populations | array[[experiment population](#experiment-population-object) object] | The experiment rollout's populations |
| overrides ^2^ | array[[experiment bucket override](#experiment-bucket-override-object) object] | Specific bucket overrides for the experiment |
| overrides_formatted ^2^ | array[array[[experiment population](#experiment-population-object) object]] | Populations of overrides for the experiment |
| holdout_name ^3^ | ?string | A human-readable experiment name (formatted as `year-month_name`) that disables the experiment |
| holdout_bucket ^3^ | ?integer | The holdout experiment bucket that disables the experiment |
| aa_mode ^2^ | integer | The experiment's A/A testing mode, represented as an integer-casted boolean |
| trigger_debugging | integer | Whether the experiment's analytics trigger debugging is enabled, represented as an integer-casted boolean |
^1^ Used to categorize multiple experiments together for coordinated rollouts.
^2^ The population bucket for A/A tested experiments should always be None (`-1`) unless an override is present for the resource.
^3^ If a holdout experiment is present and the guild is in the holdout bucket, the population bucket will be set to None (`-1`), disabling the experiment unless an override is present.
###### Example Guild Experiment
```json
[
1405831955,
"2021-06_guild_role_subscriptions",
0,
[
[
[
[
-1,
[
{
"s": 7200,
"e": 10000
}
]
],
[
1,
[
{
"s": 0,
"e": 7200
}
]
]
],
[
[
2294888943,
[
[2690752156, 1405831955],
[1982804121, 10000]
]
]
]
]
],
[],
[
[
[
[
[
1,
[
{
"s": 0,
"e": 10000
}
]
]
],
[[1604612045, [[1183251248, ["GUILD_ROLE_SUBSCRIPTIONS"]]]]]
]
]
],
null,
null,
0,
0
]
```
### Experiment Population Object
The population object defines a set of filters and position ranges required to meet specific buckets.
###### Experiment Population Structure
This object is represented as an array of the following fields:
| Field | Type | Description |
| ------- | -------------------------------------------------------------------------------- | ------------------------------------------------------------------- |
| ranges | array[[experiment population range](#experiment-population-range-object) object] | The ranges for this population |
| filters | [experiment population filters](#experiment-population-filters-object) object | The filters that the resource must satisfy to be in this population |
###### Example Experiment Population
```json
[
[
[
-1,
[
{
"s": 7200,
"e": 10000
}
]
]
],
[
[
2294888943,
[
[2690752156, 1405831955],
[1982804121, 10000]
]
]
]
]
```
### Experiment Population Range Object
If the filters in a given population are satisfied and a range includes the resource's [rollout position](#rollout-positions), the resource is then eligible for the given bucket.
###### Experiment Population Range Structure
This object is represented as an array of the following fields:
| Field | Type | Description |
| ------- | --------------------------------------------------------------------------------------- | ---------------------------- |
| bucket | integer | The bucket this range grants |
| rollout | array[[experiment population rollout](#experiment-population-rollout-structure) object] | The range rollout |
###### Experiment Population Rollout Structure
| Field | Type | Description |
| ----- | ------- | ----------------------- |
| s | integer | The start of this range |
| e | integer | The end of this range |
###### Example Experiment Population Range
```json
[
1,
[
{
"s": 0,
"e": 4750
}
]
]
```
### Experiment Population Filters Object
This object defines the filters required to be eligible for the ranges. All provided filters must be satisfied for the resource to be eligible for the given bucket.
The filters are an object represented as an array of arrays. The first item in the nested array is a 32-bit unsigned Murmur3 hashed representation of the key,
and the second item is the value, with the value being another array-represented object. All structures below are represented in this way.
The field order for filter structures (other than the top-level structure below) is guaranteed to be in the same order as documented.
###### Experiment Population Filters Structure
| Field | Type | Description |
| ------------------------- | ---------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------- |
| guild_has_feature? | [experiment population guild feature filter](#experiment-population-guild-feature-filter-structure) object | The [guild features](/resources/guild#guild-features) that are eligible |
| guild_id_range? | [experiment population range filter](#experiment-population-range-filter-structure) object | The range of snowflake resource IDs that are eligible |
| guild_age_range_days? ^1^ | [experiment population range filter](#experiment-population-range-filter-structure) object | The range of guild ages (in days) that are eligible |
| guild_member_count_range? | [experiment population range filter](#experiment-population-range-filter-structure) object | The range of guild member counts that are eligible |
| guild_ids? | [experiment population ID filter](#experiment-population-id-filter-structure) object | A list of resource IDs that are eligible |
| guild_hub_types? | [experiment population hub type filter](#experiment-population-hub-type-filter-structure) object | A list of [hub types](/resources/guild#hub-type) that are eligible |
| guild_has_vanity_url? | [experiment population vanity URL filter](#experiment-population-vanity-url-filter-structure) object | Whether the guild must or must not have a vanity to be eligible |
| guild_in_range_by_hash? | [experiment population range by hash filter](#experiment-population-range-by-hash-filter-structure) object | The special rollout position limits on the population |
^1^ The guild age is determined from the guild's ID. See the [snowflake documentation](/reference#snowflake-format) for more information.
The age can be calculated using the following pseudocode, where `resource_id` is the guild's ID:
```py
timestamp = ((resource_id >> 22) + 1420070400000) / 1000
guild_age = (time.time() - timestamp) / 86400
```
###### Experiment Population Guild Feature Filter Structure
| Field | Type | Description |
| -------------- | ------------- | -------------------------------------------------------------------------------------------------------------------------------- |
| guild_features | array[string] | The [guild features](/resources/guild#guild-features) eligible for this population; only one feature is required for eligibility |
###### Experiment Population Range Filter Structure
| Field | Type | Description |
| ------ | ---------- | -------------------------------------------- |
| min_id | ?snowflake | The exclusive minimum for this range, if any |
| max_id | ?snowflake | The exclusive maximum for this range, if any |
###### Experiment Population ID Filter Structure
| Field | Type | Description |
| --------- | ---------------- | ------------------------------------------------------------------------ |
| guild_ids | array[snowflake] | The list of snowflake resource IDs that are eligible for this population |
###### Experiment Population Hub Type Filter Structure
| Field | Type | Description |
| --------------- | -------------- | ----------------------------------------------------------------------------------- |
| guild_hub_types | array[integer] | The [type of hubs](/resources/guild#hub-type) that are eligible for this population |
###### Experiment Population Vanity URL Filter Structure
| Field | Type | Description |
| -------------------- | ------- | ---------------------------------------------------------- |
| guild_has_vanity_url | boolean | The required vanity URL holding status for this population |
###### Experiment Population Range By Hash Filter Structure
This filter is used to limit rollout position by an additional hash key. The calculated rollout position must be less than the given target. The rollout position can be calculated using the following pseudocode, where `hash_key` is the provided hash key and `resource_id` is the guild ID:
```py
hashed = mmh3.hash('hash_key:resource_id', signed=False)
if hashed > 0:
# Double the hash
hashed += hashed
else:
# Unsigned right shift by 0
hashed = (hashed % 0x100000000) >> 0
result = hashed % 10000
```
| Field | Type | Description |
| -------- | ------- | ------------------------------------------------------------------------- |
| hash_key | integer | The 32-bit unsigned Murmur3 hash of the key used to determine eligibility |
| target | integer | The rollout position limit for this population |
###### Example Experiment Population Filters
```json
[
[
1604612045, // guild_has_feature
[
[
1183251248, // guild_features
["ROLE_SUBSCRIPTIONS_ENABLED"]
]
]
]
]
```
### Experiment Bucket Override Object
An override represents a manual setting by Discord employees to grant a guild early or specific access to an experiment.
###### Experiment Bucket Override Structure
| Field | Type | Description |
| ----- | ---------------- | --------------------------------------- |
| b | integer | Bucket assigned to these resources |
| k | array[snowflake] | Resources granted access to this bucket |
###### Experiment Bucket Override Example
```json
{
"b": 1,
"k": ["882680660588904448", "882703776794959873", "859533785225494528", "859533828754505741"]
}
```
## Apex Experiments
Apex experiments are a new type of experiment that is far more flexible and allows for more complex targeting and assignment logic.
While they are far more powerful, they also provide a lot less data to clients and allow for more opaque experimentation, preventing feature disclosure.
Notably, Apex experiments use the concept of variants instead of buckets, and are assigned to specific units
(i.e. users, guilds, etc.) instead of being calculated on the client side based on filters and rollout positions.
### Eligibility
Apex experiments use flags to determine evaluation precedence, especially for `GUILD` unit type experiments which
evaluate both a guild-level and user-level assignment. Clients should determine final variant using the following priority:
1. **User Override:** If a user assignment is present and has the `IS_OVERRIDE` flag, it should be used as the assigned variant for all guilds
2. **Guild Override:** If a guild assignment is present and has the `IS_OVERRIDE` flag, it should be used as the assigned variant for the guild
3. **Eligibility Gate:** If a guild assignment is present, if and only if a user assignment is present with the `USE_AS_ELIGIBILITY` flag, should the guild assignment be used as the assigned variant for the guild
If none of the above are satisfied, the guild does not have an assigned variant for the experiment.
Additionally, if the _final_ evaluated assignment ever possesses the `USE_AS_ELIGIBILITY` flag,
it should be discarded and the resource should be considered ineligible for the experiment,
as this flag is only meant to be used as an eligibility gate and should not be used as an actual assignment.
###### Apex Experiments Structure
| Field | Type | Description |
| ----------------- | ---------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------- |
| assignments | map[integer, map[snowflake, [apex experiment assignments](#apex-experiment-assignments-structure) object]] | A mapping of [unit type](#apex-experiment-unit-type) to unit IDs to their assignments |
| installation? ^1^ | string | A generated fingerprint of the current date and time |
^1^ This field is omitted if a valid installation ID is provided in request headers or when identifying with the Gateway. See the [installations](#installations) section for more information.
###### Apex Experiment Unit Type
| Value | Name | Description |
| ----- | ------------ | ------------------------------------ |
| 1 | USER | Experiment is for a user |
| 2 | INSTALLATION | Experiment is for an installation |
| 3 | GUILD | Experiment is for a guild |
| 4 | CUSTOM | Experiment is for a custom unit type |
###### Apex Experiment Assignments Structure
| Field | Type | Description |
| ------------- | --------------------------------------------------------------------------------- | -------------------------------------------- |
| evaluation_id | string | The ID of the evaluation |
| assignments | array[[apex experiment assignment](#apex-experiment-assignment-structure) object] | The assignments for the apex experiment unit |
###### Apex Experiment Assignment Structure
This object is represented as an array of the following fields:
| Field | Type | Description |
| ------------------- | -------- | -------------------------------------------------------- |
| hashed_name | integer | 32-bit unsigned Murmur3 hash of the experiment's name |
| variant_id | integer | The assigned experiment variant for the target |
| flags | ?integer | The [experiment's flags](#apex-experiment-flags) |
| revision | integer | Current version of the rollout |
| tracked_variant_id? | integer | The variant that is currently being tracked in analytics |
###### Apex Experiment Flags
| Value | Name | Description |
| -------- | ------------------------- | ----------------------------------------------------------------------- |
| 1 \<\< 0 | IS_OVERRIDE | Experiment assignment is an override |
| 1 \<\< 1 | EXPOSURE_TRACKING_ENABLED | Experiment has exposure tracking enabled |
| 1 \<\< 2 | DEPENDENT_EXPERIMENT | Experiment is dependent on another experiment |
| 1 \<\< 3 | USE_AS_ELIGIBILITY | Experiment assignment acts as an eligibility gate for guild experiments |
###### Example Apex Experiments
```json
{
"assignments": {
"1": {
"852892297661906993": {
"evaluation_id": "cd659a5d",
"assignments": [
[3759954850, 1, 0, 2],
[4240376458, 0, 0, 8],
[956087042, 1, 0, 2],
[1605213660, 0, 2, 0],
[3164674236, 1, 0, 4],
[3436651650, 1, 1, 0],
[1581149260, 0, 0, 3],
[13763179, 1, 2, 0],
[721000765, 1, 2, 0],
[2657741306, 0, 2, 3],
[341733491, 0, 2, 3],
[76075180, 0, 2, 3],
[2722069991, 0, 2, 3],
[196982166, 1, 0, 0],
[1228731397, 1, 2, 0],
[1132732657, 1, 2, 0]
]
}
}
}
}
```
## Endpoints
Get Experiment Assignments
Returns the [user experiment assignments](#user-experiments) and optionally [guild experiment rollouts](#guild-experiments) for the requesting user or fingerprint.
Returned experiments are dependent on the requesting [client properties](/reference#client-properties).
A fingerprint will only be generated and returned if no authorization or fingerprint is provided in request headers. Fingerprint generation has a rate limit of 3 valid fingerprints per 2 minutes per IP. While fingerprints will still be returned past this rate limit, they will not be valid.
###### Query String Parameters
| Field | Type | Description |
| ----------------------- | ------- | ---------------------------------------------------------------------------------- |
| with_guild_experiments? | boolean | Whether to include guild experiments in the returned data |
| platform? ^1^ | string | Whether to also include experiments for the given [platform](#experiment-platform) |
^1^ Including this parameter requires valid [authentication](/reference#authentication).
###### Experiment Platform
| Value | Description |
| ---------------- | -------------------- |
| DEVELOPER_PORTAL | The developer portal |
###### Response Body
| Field | Type | Description |
| ------------------ | -------------------------------------------------------- | --------------------------------------------------------------------- |
| fingerprint? | string | A generated [fingerprint](#fingerprints) of the current date and time |
| assignments | array[[experiment assignment](#user-experiments) object] | The experiment assignments for this user or fingerprint |
| guild_experiments? | array[[guild experiment](#guild-experiments) object] | Guild experiment rollouts for the client to assign |
Create Fingerprint
Generates a new [fingerprint](#fingerprints).
Fingerprint generation has a rate limit of 3 valid fingerprints per 2 minutes per IP. While fingerprints will still be returned past this rate limit, they will not be valid.
###### Response Body
| Field | Type | Description |
| ----------- | ------ | ------------------------------------------------------ |
| fingerprint | string | The generated fingerprint of the current date and time |
Get Apex Experiment Assignments
Returns an [apex experiments](#apex-experiments) object for the requesting user and installation.
Returned experiments are dependent on the requesting [client properties](/reference#client-properties).
###### Query String Parameters
| Field | Type | Description |
| ------- | ------- | --------------------------------------------------------------------------------------------------------------------- |
| surface | integer | The [surface](#apex-experiment-surface) to return apex experiments for (only `APP` and `DEVELOPER_PORTAL` is allowed) |
###### Apex Experiment Surface
| Value | Name | Description |
| ----- | ---------------- | ----------------------------------------------------------------- |
| 1 | API | Return apex experiments that alter API functionality |
| 2 | APP | Return apex experiments that alter client functionality |
| 3 | DEVELOPER_PORTAL | Return apex experiments that alter developer portal functionality |
| 4 | ADMIN_PANEL | Return apex experiments that alter admin panel functionality |
| 5 | ADS_BUDGET_AB | Return apex experiments that alter ads manager functionality |
Get Metadata for Apex Experiments
Returns metadata for apex experiments.
This endpoint is only usable by Discord employees.
###### Query String Parameters
| Field | Type | Description |
| ------- | ------- | ---------------------------------------------------------------------- |
| surface | integer | The [surface](#apex-experiment-surface) to return apex experiments for |
###### Response Body
| Field | Type | Description |
| ----------- | ----------------------------------------------------------------------------- | --------------------------------- |
| experiments | array[[apex experiment metadata](#apex-experiment-metadata-structure) object] | The metadata for apex experiments |
###### Apex Experiment Metadata Structure
| Field | Type | Description |
| --------- | --------------------------------------------------------------------------- | ------------------------------------------------------------------ |
| id | integer | The ID of the apex experiment |
| name | string | The name of the apex experiment |
| title | string | The title of the apex experiment |
| revision | integer | Current version of the rollout |
| unit_type | integer | The [unit type](#apex-experiment-unit-type) of the apex experiment |
| variants | array[[apex experiment variant](#apex-experiment-variant-structure) object] | The variants of the apex experiment |
###### Apex Experiment Variant Structure
| Field | Type | Description |
| ----- | ------- | -------------------------------------------------------- |
| id | integer | The ID of the experiment variant |
| label | string | The label of the variant |
| type | integer | The [type of the variant](#apex-experiment-variant-type) |
###### Apex Experiment Variant Type
| Value | Name | Description |
| ----- | --------- | ---------------------------------------- |
| 1 | ACTIVE | The variant is active |
| 2 | UNUSED | The variant is currently unused |
| 3 | BURNED | The variant failed and is being reverted |
| 4 | PRESERVED | The variant is preserved |
---
# Voice Connections
Link: https://docs.discord.food/topics/voice-connections
Voice connections operate in a similar fashion to the [Gateway](/gateway/using-gateway#connections) connection.
However, they use a different set of payloads and a separate UDP-based connection for RTC data transmission.
Because UDP is generally used for both receiving and transmitting RTC data, your client _must_ be able to receive UDP packets, even through a firewall or NAT (see [UDP Hole Punching](https://en.wikipedia.org/wiki/UDP_hole_punching) for more information).
The Discord voice servers implement functionality (see [IP Discovery](#ip-discovery)) for discovering the local machine's remote UDP IP/Port, which can assist in some network configurations.
If you cannot support a UDP connection, you may implement a [WebRTC connection](#webrtc-connections) instead.
Audio and video from a "Go Live" stream require a [separate connection to another voice server](#streams). Only microphone and camera data are sent over the normal connection.
User accounts can only be connected to one voice channel per session. However, bots can be connected to one voice channel per guild per session.
## Voice Gateway
To ensure that you have the most up-to-date information, please use [version 9](#gateway-versions). Otherwise, the events and commands documented here may not reflect what you receive over the socket. Video is only fully supported on Gateway v5 and above.
###### Gateway Versions
The voice server does not provide a default version. You must explicitly pass a version with the `?v=` query parameter.
| Version | Status | Change |
| ------- | ----------- | ------------------------------------------------------------------------------------------------------- |
| 9 | Recommended | Added `channel_id` to [Opcode 0 Identify](#identify-structure) and [Opcode 7 Resume](#resume-structure) |
| 8 | Recommended | Added buffered resuming |
| 7 | Available | Added [Opcode 17 Channel Options Update](#gateway-events) |
| 6 | Available | Added [Opcode 16 Voice Backend Version](#gateway-events) |
| 5 | Available | Added [Opcode 15 Media Sink Wants](#gateway-events) |
| 4 | Available | Changed [speaking status](#speaking-flags) from boolean to bitmask |
| 3 | Deprecated | Added video functionality, consolidated [Opcode 1 Hello](#gateway-events) payload |
| 2 | Deprecated | Changed Gateway heartbeat reply to [Opcode 6 Heartbeat ACK](#gateway-events) |
| 1 | Deprecated | Initial version |
###### Gateway Commands
| Name | Description |
| --------------------------------------------------------- | ----------------------------------------- |
| [Identify](#identify-structure) | Start a new voice connection |
| [Resume](#resume-structure) | Resume a dropped connection |
| [Heartbeat](#example-heartbeat) | Maintain an active WebSocket connection |
| [Media Sink Wants](#simulcasting) | Indicate the desired media stream quality |
| [Select Protocol](#select-protocol-structure) | Select the voice protocol and mode |
| [Session Update](<#session-update-structure-(send)>) | Indicate the client's supported codecs |
| [Speaking](#speaking-structure) | Indicate the user's speaking state |
| [Video](#video) | Indicate the user's video state |
| [Voice Backend Version](#voice-backend-version-structure) | Request the current voice backend version |
| [DAVE Protocol Transition Ready](#protocol-transitions) | Indicate that a DAVE transition is ready |
| [MLS Key Package](#key-packages) | Send an MLS key package |
| [MLS Commit Welcome](#proposals-and-commits) | Send an MLS commit and optional welcome |
| [MLS Invalid Commit Welcome](#invalid-group) | Report an invalid MLS commit or welcome |
| [No Route](#no-route) | Indicate that no RTC route was available |
###### Gateway Events
| Name | Description |
| ------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------- |
| [Hello](#hello-structure) | Defines the heartbeat interval |
| [Heartbeat ACK](#example-heartbeat-ack) | Acknowledges a received client heartbeat |
| [DAVE Protocol Execute Transition](#protocol-transitions) | Execute a prepared DAVE protocol or MLS group transition |
| [DAVE Protocol Prepare Epoch](#version-change-%26-upgrade) | Prepare a DAVE protocol version or MLS epoch transition |
| [DAVE Protocol Prepare Transition](#downgrade) | Prepare a transition away from the current DAVE protocol |
| [Clients Connect](#client-connections) | A user connected to voice, also sent on initial connection to inform the client of existing users |
| [Client Flags](#client-connections) | Contains the flags of a user that connected to voice, also sent on initial connection for each existing user |
| [Client Platform](#client-connections) | Contains the platform type of a user that connected to voice, also sent on initial connection for each existing user |
| [Client Disconnect](#client-disconnections) | A user disconnected from voice |
| [Media Sink Wants](#simulcasting) | Requested media stream quality updated |
| [MLS Announce Commit Transition](#proposals-and-commits) | Dispatches the winning MLS commit for the current epoch |
| [MLS External Sender Package](#external-sender) | Provides the voice server's MLS external sender package |
| [MLS Proposals](#proposals-and-commits) | Dispatches MLS proposals that group members must process |
| [MLS Welcome](#welcome) | Welcomes a pending member into the MLS group |
| [Ready](#ready-structure) | Contains SSRC, IP/Port, experiment, and encryption mode information |
| [Resumed](#example-resumed) | Acknowledges a successful connection resume |
| [Session Description](#session-description-structure) | Acknowledges a successful protocol selection and contains the information needed to send/receive RTC data |
| [Session Update](<#session-update-structure-(receive)>) | Client session description changed |
| [Speaking](#speaking-structure) | User speaking state updated |
| [Voice Backend Version](<#example-voice-backend-version-(receive)>) | Current voice backend version information, as requested by the client |
## Connecting to Voice
### Retrieving Voice Server Information
The first step in connecting to a voice server (and in turn, a guild's voice channel or private channel) is formulating a request that can be sent to the [Gateway](/gateway/using-gateway), which will return information about the voice server we will connect to. Because Discord's voice platform is widely distributed, users **should never** cache or save the results of this call. To inform the Gateway of our intent to establish voice connectivity, we first send an [Update Voice State](/gateway/gateway-events#update-voice-state) payload.
If our request succeeded, the Gateway will respond with _two_ events—a [Voice State Update](/gateway/gateway-events#voice-state-update) event and a [Voice Server Update](/gateway/gateway-events#voice-server-update) event—meaning you must properly wait for both events before continuing. The first will contain a new key, `session_id`, and the second will provide voice server information we can use to establish a new voice connection.
With this information, we can move on to establishing a voice WebSocket connection.
When changing channels within the same guild, it is possible to receive a [Voice Server Update](/gateway/gateway-events#voice-server-update) with the same `endpoint` as the existing session. However, the `token` will be changed and you cannot re-use the previous session during a channel change, even if the endpoint remains the same.
When the voice channel user limit is reached (the channel is full), you will not receive any events in response to your request.
Having the `MOVE_MEMBERS` permission bypasses this limit and allows you to join regardless of the channel being full or not.
Similarly, when the voice channel video user limit is reached, you will not receive any events in response to your request.
However, having the `MANAGE_CHANNELS` permission allows an additional **one** user to join the channel (i.e. moderators have a limit of `max_video_channel_users + 1`).
So, assuming the channel is not already oversaturated, you will be able to join the channel even if the video user limit is reached.
In the case of streams, a stage channel's max stream user limit is given by `max_stage_video_channel_users`.
For voice channels, the limit is typically 50, but clients should attempt to join the channel regardless of the limit.
If the limit is reached, the Gateway will respond with a [Stream Delete](/gateway/gateway-events#stream-delete) event, containing a `reason` of `stream_full`.
This signals that the client cannot join the stream.
Private channel voice connections work exactly the same as guild voice channels, except that the channel's ID is used as the server ID below.
If the client is the first to join a private channel, a call will be created for the channel and a [Call Create](/gateway/gateway-events#call-create) Gateway event will be fired.
Once a call exists, clients can choose to [ring the channel recipients](/resources/channel#ring-channel-recipients).
### Establishing a Voice WebSocket Connection
Once we retrieve a `session_id`, `token`, and `endpoint` information, we can connect and handshake with the voice server over another secure WebSocket.
Unlike the Gateway endpoint we receive in a [Get Gateway](/gateway/using-gateway#get-gateway) request, the endpoint received from our [Voice Server Update](/gateway/gateway-events#voice-server-update) payload does not contain a URL protocol,
so some libraries may require manually prepending it with `wss://` before connecting. Once connected to the voice WebSocket endpoint, we can immediately send an [Opcode 0 Identify](#gateway-commands) payload:
All JSON payloads sent to the Gateway must be text frames. Binary frames are not supported.
###### Identify Structure
| Field | Type | Description |
| -------------------------- | ----------------------------------------- | ------------------------------------------------------------------------- |
| server_id | snowflake | The ID of the guild, private channel, stream, or lobby being connected to |
| channel_id ^1^ | snowflake | The ID of the channel being connected to |
| user_id | snowflake | The ID of the current user |
| session_id | string | The session ID of the current session |
| token | string | The voice token for the current session |
| video? | boolean | Whether this connection supports video (default false) |
| streams? | array[[stream](#stream-structure) object] | [Simulcast](#simulcasting) streams to send |
| max_dave_protocol_version? | integer | The maximum DAVE protocol version supported by the client (default 0) |
^1^ Only required for Gateway v9 and above.
###### Stream Structure
| Field | Type | Description |
| ---------------- | -------------------------------------------------------- | --------------------------------------------------------- |
| type | string | The [type of media stream](#media-type) to send |
| rid | string | The RTP stream ID, conventionally the stringified quality |
| quality? | integer | The media quality to send (0-100, default 0) |
| active? | boolean | Whether the stream is active (default false) |
| max_bitrate? ^1^ | integer | The maximum bitrate to send in bps |
| max_framerate? | integer | The maximum framerate to send in fps |
| max_resolution? | [stream resolution](#stream-resolution-structure) object | The maximum resolution to send |
| ssrc? | integer | The SSRC of the stream |
| rtx_ssrc? ^2^ | integer | The SSRC of the retransmission stream |
^1^ Not sent by the voice server.
^2^ If omitted for a negotiated video stream, clients should derive the RTX SSRC as the primary stream `ssrc + 1`.
###### Media Type
| Value | Description |
| ---------- | ----------- |
| video | Video |
| screen ^1^ | Screenshare |
| test | Speed test |
^1^ For stream connections, clients may offer `screen` in [Identify](#identify-structure). The voice server will still populate the negotiated stream as `video` in [Ready](#ready-structure), as `video` is the actual underlying media type.
###### Stream Resolution Structure
| Field | Type | Description |
| ------ | ------ | ---------------------------------------------- |
| type | string | The [resolution type](#resolution-type) to use |
| width | number | The fixed resolution width, or 0 for source |
| height | number | The fixed resolution height, or 0 for source |
###### Resolution Type
| Value | Description |
| ------ | ----------------- |
| fixed | Fixed resolution |
| source | Source resolution |
###### Example Identify
```json
{
"op": 0,
"d": {
"server_id": "41771983423143937",
"channel_id": "127121515262115840",
"user_id": "104694319306248192",
"session_id": "30f32c5d54ae86130fc4a215c7474263",
"token": "66d29164ee8cd919",
"video": true,
"streams": [
{ "type": "video", "rid": "100", "quality": 100 },
{ "type": "video", "rid": "50", "quality": 50 }
],
"max_dave_protocol_version": 1
}
}
```
The voice server should respond with an [Opcode 2 Ready](#gateway-events) payload, which informs us of our SSRCs and connection information:
###### Ready Structure
| Field | Type | Description |
| ----------- | ----------------------------------------- | ------------------------------------------------------------------ |
| ssrc | integer | The SSRC of the user's voice connection |
| ip | string | The IP address of the voice server |
| port | integer | The port of the voice server |
| modes | array[string] | Supported [transport encryption modes](#transport-encryption-mode) |
| experiments | array[string] | Available voice experiments |
| streams | array[[stream](#stream-structure) object] | Populated simulcast streams |
###### Example Ready
```json
{
"op": 2,
"d": {
"ssrc": 12871,
"ip": "127.0.0.1",
"port": 1234,
"modes": ["aead_aes256_gcm_rtpsize", "aead_xchacha20_poly1305_rtpsize"],
"experiments": ["fixed_keyframe_interval"],
"streams": [
{
"type": "video",
"ssrc": 12872,
"rtx_ssrc": 12873,
"rid": "50",
"quality": 50,
"active": false
},
{
"type": "video",
"ssrc": 12874,
"rtx_ssrc": 12875,
"rid": "100",
"quality": 100,
"active": false
}
]
}
}
```
When `streams` is populated, the voice server has assigned local send SSRCs for the offered simulcast streams. Use each stream's `ssrc` and `rtx_ssrc` when announcing local video state with [Opcode 12 Video](#video), and when configuring a WebRTC packetizer.
### Establishing a Voice Connection
Once we receive the properties of a voice server from our [Ready](#ready-structure) payload, we can proceed to the final step of voice connections, which entails establishing and handshaking a connection for RTC data.
First, we establish either a [UDP connection](#udp-connections) using the [Ready](#ready-structure) payload data, or prepare a [WebRTC](#webrtc-connections) SDP. We then send an [Opcode 1 Select Protocol](#gateway-events) with details about our connection:
###### Select Protocol Structure
| Field | Type | Description |
| ------------------ | ---------------------------------------------------- | --------------------------------------------------------------------------------- |
| protocol | string | The [voice protocol](#protocol-type) to use |
| data | ?[protocol data](#protocol-data-structure) \| string | The voice connection data or WebRTC SDP |
| rtc_connection_id? | string | The UUID RTC connection ID, used for analytics |
| codecs? | array[[codec](#codec-structure) object] | The supported audio/video codecs |
| experiments? | array[string] | The [received voice experiments](#ready-structure) or selected experiments to use |
###### Protocol Type
| Value | Description |
| -------------- | ------------------------------------------------- |
| udp | [Standard UDP voice connection](#udp-connections) |
| webrtc | [WebRTC voice connection](#webrtc-connections) |
| ~~webrtc-p2p~~ | ~~WebRTC peer-to-peer voice connection~~ |
###### Protocol Data Structure
| Field | Type | Description |
| ----------- | ------- | ------------------------------------------------------------------ |
| address ^1^ | string | The discovered IP address of the client |
| port ^1^ | integer | The discovered UDP port of the client |
| mode | string | The [transport encryption mode](#transport-encryption-mode) to use |
^1^ These fields are only used to receive RTC data. If you only wish to send frames and do not care about receiving, you can randomize these values.
###### Codec Structure
| Field | Type | Description |
| ----------------- | ------- | ----------------------------------------------------------------------------- |
| name | string | The [name of the codec](#supported-codecs) |
| type | string | The [type of codec](#supported-codecs) |
| priority ^1^ | integer | The preferred priority of the codec as a multiple of 1000 (unique per `type`) |
| payload_type ^2^ | integer | The dynamic RTP payload type of the codec |
| rtx_payload_type? | integer | The dynamic RTP payload type of the retransmission codec (video-only) |
| encode? | boolean | Whether the client supports encoding this codec (default true) |
| decode? | boolean | Whether the client supports decoding this codec (default true) |
^1^ For audio, Opus is the only available codec and should be priority `1000`.
^2^ No payload type should be set to `96`, as it is reserved for probe packets.
###### Supported Codecs
Providing codecs is optional due to backwards compatibility with old clients and bots that do not handle video.
If the client does not provide any codecs, the server assumes an Opus audio codec with a payload type of `120` and no specific video codec.
Codec support is used by the server to negotiate a send codec per-client that all other clients can decode. If multiple are supported, the one with the lowest priority will be chosen.
If the client does not support any codec others can decode, the server will choose the client's highest priority encode codec. If no codecs are supported, the server will fall back to `H264`.
| Type | Name | Status |
| ----- | ---- | --------- |
| audio | opus | Required |
| video | AV1 | Preferred |
| video | H265 | Preferred |
| video | H264 | Default |
| video | VP8 | Available |
| video | VP9 | Available |
###### Example Select Protocol
```json
{
"op": 1,
"d": {
"protocol": "udp",
"data": {
"address": "127.0.0.1",
"port": 1337,
"mode": "aead_aes256_gcm_rtpsize"
},
"codecs": [
{
"name": "opus",
"type": "audio",
"priority": 1000,
"payload_type": 120
},
{
"name": "AV1",
"type": "video",
"priority": 1000,
"payload_type": 101,
"rtx_payload_type": 102,
"encode": false,
"decode": true
},
{
"name": "H264",
"type": "video",
"priority": 2000,
"payload_type": 103,
"rtx_payload_type": 104,
"encode": true,
"decode": true
}
],
"rtc_connection_id": "d6b92f64-40df-48eb-8bce-7facb043149a",
"experiments": ["fixed_keyframe_interval"]
}
}
```
###### Transport Encryption Mode
The RTP size variants determine the unencrypted size of the RTP header in [the same way as SRTP](https://tools.ietf.org/html/rfc3711#section-3.1), which considers CSRCs and (optionally) the extension preamble to be part of the unencrypted header.
The deprecated variants use a fixed size unencrypted header for RTP.
The Gateway will report what encryption modes are available in [Opcode 2 Ready](#gateway-events).
Compatible modes will always include `aead_xchacha20_poly1305_rtpsize` but may not include `aead_aes256_gcm_rtpsize` depending on the underlying hardware.
You must support `aead_xchacha20_poly1305_rtpsize`. You should prefer to use `aead_aes256_gcm_rtpsize` when it is available.
| Value | Name | Nonce | Status |
| ------------------------------- | ---------------------------------- | ----------------------------------------------------- | ---------- |
| aead_aes256_gcm_rtpsize | AEAD AES256 GCM (RTP Size) | 32-bit incremental integer value appended to payload | Preferred |
| aead_xchacha20_poly1305_rtpsize | AEAD XChaCha20 Poly1305 (RTP Size) | 32-bit incremental integer value appended to payload | Required |
| xsalsa20_poly1305_lite_rtpsize | XSalsa20 Poly1305 Lite (RTP Size) | 32-bit incremental integer value appended to payload | Deprecated |
| aead_aes256_gcm | AEAD AES256-GCM | 32-bit incremental integer value appended to payload | Deprecated |
| xsalsa20_poly1305 | XSalsa20 Poly1305 | Copy of RTP header | Deprecated |
| xsalsa20_poly1305_suffix | XSalsa20 Poly1305 (Suffix) | 24 random bytes | Deprecated |
| xsalsa20_poly1305_lite | XSalsa20 Poly1305 (Lite) | 32-bit incremental integer value, appended to payload | Deprecated |
Finally, the voice server will respond with an [Opcode 4 Session Description](#gateway-events) that includes the `mode` and `secret_key`, a 32 byte array used for [sending and receiving](#sending-and-receiving-media) RTC data:
###### Session Description Structure
| Field | Type | Description |
| -------------------------------- | -------------- | -------------------------------------------------------------------------------------------- |
| audio_codec ^1^ | string | The audio codec to use |
| video_codec ^1^ | string | The video codec to use |
| media_session_id | string | The media session ID, used for analytics |
| mode? | string | The [transport encryption mode](#transport-encryption-mode) to use, not applicable to WebRTC |
| secret_key? | array[integer] | The 32 byte secret key used for encryption, not applicable to WebRTC |
| sdp? | string | The WebRTC session description protocol |
| keyframe_interval? | integer | The keyframe interval in milliseconds |
| bandwidth_estimation_experiment? | string | The selected bandwidth estimation experiment |
| dave_protocol_version? | integer | The DAVE protocol version to use, where 0 indicates no DAVE support |
^1^ Note that these describe the codecs the client should _send_. Other clients may send media in a different codec that you indicated decode support for.
###### Example Session Description
```json
{
"op": 4,
"d": {
"audio_codec": "opus",
"media_session_id": "89f1d62f166b948746f7646713d39dbb",
"mode": "aead_aes256_gcm_rtpsize",
"secret_key": [ ... ],
"video_codec": "H264",
"dave_protocol_version": 1
}
}
```
We can now start sending and receiving RTC data over the previously established [UDP](#udp-connections) or [WebRTC](#webrtc-connections) connection.
### Session Updates
At any time, the client may update the `codecs` they support using an [Opcode 14 Session Update](#gateway-events).
If a user joins that does not support the current codecs, or a user indicates that they no longer support the current codecs, the voice server will send an [Opcode 14 Session Update](#gateway-events):
This may also be sent to update the current `media_session_id` or `keyframe_interval`.
###### Session Update Structure (Send)
| Field | Type | Description |
| ------ | --------------------------------------- | -------------------------------- |
| codecs | array[[codec](#codec-structure) object] | The supported audio/video codecs |
###### Session Update Structure (Receive)
| Field | Type | Description |
| ------------------ | ------- | -------------------------------------------- |
| audio_codec? | string | The new audio codec to use |
| video_codec? | string | The new video codec to use |
| media_session_id? | string | The new media session ID, used for analytics |
| keyframe_interval? | integer | The keyframe interval in milliseconds |
## End-to-End Encryption
Since September 2024, Discord has migrated voice and video in private channels, voice channels, and streams to use end-to-end encryption (E2EE) through the DAVE protocol.
When any DAVE protocol is enabled for a call, the full contents of media frames sent and received by call participants are end-to-end encrypted.
To support long-term privacy goals, Discord will **only support E2EE calls starting on March 1st, 2026** for all audio and video conversations in direct messages, group channels, voice channels, and streams.
Clients that do not support the DAVE protocol by then will be disconnected from voice with [close code `4017`](/gateway/opcodes-and-close-codes#voice-close-event-codes).
Stage channels will not be affected by this change and will continue to operate without E2EE.
This section is a high-level overview of how to support Discord's audio & video end-to-end encryption (DAVE) protocol, centered around the Gateway opcodes necessary for the protocol.
The most thorough documentation on the DAVE protocol is found in the [protocol whitepaper](https://daveprotocol.com). You may additionally be able to leverage or refer to Discord's open-source library [libdave](https://github.com/discord/libdave) to assist your implementation.
The exact format of the DAVE protocol opcodes is detailed in the [opcodes section of the protocol whitepaper](https://daveprotocol.com/#voice-gateway-opcodes).
When a call is E2EE, all members of the call exchange keys via a [Messaging Layer Security](https://www.rfc-editor.org/rfc/rfc9420.html) (MLS) group. This group is used to derive per-sender ratcheted media keys (known only to the participants of the group) to encrypt/decrypt media frames sent in the call.
### Binary Websocket Messages
To reduce overhead, some of the new DAVE protocol opcodes are sent as binary instead of JSON text. See the format column in [voice opcodes](/gateway/opcodes-and-close-codes#voice) to identify them.
Client-to-server binary messages start with a 1-byte opcode followed by the payload. Server-to-client binary messages on Gateway v8 and above include a 2-byte sequence number before the opcode:
| Field | Type | Description | Size |
| ------------ | --------------------------- | ------------------------ | -------------- |
| Sequence ^1^ | Unsigned short (big endian) | Sequence number | 2 bytes |
| Opcode | Unsigned byte | Opcode value | 1 byte |
| Payload | Binary data | Format defined by opcode | Variable bytes |
^1^ Sequence numbers are only sent from the server to the client on Gateway v8 and above. See [Buffered Resume](#buffered-resume) for further details on how sequence numbers are used when present.
### Indicating DAVE Protocol Support
Include the highest DAVE protocol version you support in [Opcode 0 Identify](#identify-structure) as `max_dave_protocol_version`. Sending version 0, or omitting the `max_dave_protocol_version` field, indicates no DAVE protocol support.
The voice Gateway specifies the initial protocol version in [Opcode 4 Session Description](#session-description-structure) under `dave_protocol_version`. This may be any non-discontinued protocol version equal to or less than your supported protocol version.
Clients must retain backwards-compatibility of any non-discontinued DAVE protocol versions. The Gateway selects
the lowest shared protocol version for the call.
### Protocol Transitions
The voice server negotiates protocol version and MLS group transitions to ensure the continuity of media being sent for the call. This can occur when the call is upgrading/downgrading to/from E2EE (in the initial transition phase), changing protocol versions, or when the MLS group is changing.
Some opcodes include a transition ID. After preparing local state necessary to perform the transition, send [Opcode 23 DAVE Protocol Transition Ready](/gateway/opcodes-and-close-codes#voice) to indicate to the Gateway that you are ready to execute the transition.
When all participants are ready or when a timeout has been reached, the Gateway dispatches [Opcode 22 DAVE Protocol Execute Transition](/gateway/opcodes-and-close-codes#voice) to confirm execution of the transition.
The transition execution is what indicates to media senders that they can begin sending media with the new protocol context (e.g. without E2EE after a downgrade, with a new protocol version after a protocol version change, or using a new key ratchet after a group participant change).
#### Downgrade
Downgrades to protocol version 0 are announced via [Opcode 21 DAVE Protocol Prepare Transition](/gateway/opcodes-and-close-codes#voice). This can occur during the transition phase when a client that does not support the protocol joins the call.
When this transition is executed, senders should stop sending media using the protocol format.
#### Version Change & Upgrade
Protocol version transitions (including upgrades from protocol version 0) are announced via [Opcode 24 DAVE Protocol Prepare Epoch](/gateway/opcodes-and-close-codes#voice). In addition to the `transition_id`, this opcode includes the `epoch` for the upcoming MLS epoch.
Receiving [Opcode 24 DAVE Protocol Prepare Epoch](/gateway/opcodes-and-close-codes#voice) with `epoch = 1` indicates that a new MLS group is being created. Participants must:
- Prepare a local MLS group with the parameters appropriate for the DAVE protocol version
- Generate and send [Opcode 26 MLS Key Package](/gateway/opcodes-and-close-codes#voice) to deliver a new MLS key package to the Gateway
When the `epoch` is greater than 1, the protocol version of the existing MLS group is changing.
When the transition is executed, senders must start sending media using the new protocol context (e.g. formatted for the new protocol version or using a new key ratchet).
#### MLS Group Changes
When the participants of the MLS group must change, existing participants receive an [Opcode 29 MLS Announce Commit Transition](/gateway/opcodes-and-close-codes#voice),
whereas new members being added to the group receive [Opcode 30 MLS Welcome](/gateway/opcodes-and-close-codes#voice). Both opcodes include the transition ID and binary MLS Commit or MLS Welcome message.
To prepare for the protocol transition, existing group members must apply the commit to progress their local MLS group to the correct next state. [Opcode 23 DAVE Protocol Transition Ready](/gateway/opcodes-and-close-codes#voice) is sent when the MLS commit has been processed.
Welcomed members send [Opcode 23 DAVE Protocol Transition Ready](/gateway/opcodes-and-close-codes#voice) after successfully joining the group received in the MLS Welcome message.
### External Sender
The voice server must be an external sender of the MLS group, so that it can send external MLS proposals to add and remove call participants when appropriate (i.e. proposing the addition of new members when they connect and the removal of previous members when they disconnect).
DAVE protocol participants only process proposals which arrive from the external sender, and not from any other group members. The external sender only sends Add or Remove proposals.
The Gateway uses [Opcode 25 MLS External Sender Package](/gateway/opcodes-and-close-codes#voice) to provide the external sender public key and credential to MLS group participants.
This message may be sent immediately on Gateway connect or at a later time when the call is upgrading to use the DAVE protocol.
Group creators must include the external sender they receive from the Gateway in their MLS group extensions when creating the group. Welcomed group members ensure that the expected external sender extension is present in the group they are about to join.
### Joining the MLS Group
Except for the initial creation of the first group for the call, joining the MLS group always occurs after receiving [Opcode 30 MLS Welcome](/gateway/opcodes-and-close-codes#voice).
#### Key Packages
To be proposed to be added to the MLS group, pending members must send an MLS key package via [Opcode 26 MLS Key Package](/gateway/opcodes-and-close-codes#voice).
Key packages are only used one time, and a new key package must be generated each time pending member is waiting to be added or re-added to the group.
##### Identity Public Key
MLS participants use an asymmetric keypair for MLS message signatures and authentication. The public key of this keypair is included in the key package and MLS tree.
It is known to other participants in the call and is leveraged for out-of-band identity verification.
You can choose to generate a new ephemeral keypair for every protocol call or use the same persistent keypair at all times.
Keys can be uploaded and verified using [Upload Voice Public Key](/resources/voice#upload-voice-public-key) and [Verify Voice Public Key](/resources/voice#verify-voice-public-key) respectively.
#### Initial Group
When there is not yet an MLS group (e.g. a transport-only encrypted call is upgrading or two members have just joined a new call), all pending group members create a local group using the MLS parameters defined by the DAVE protocol version and
including the voice server external sender received via [Opcode 25 MLS External Sender Package](/gateway/opcodes-and-close-codes#voice). Every pending member of the group has the chance to produce the initial commit that creates the MLS group with `epoch = 1`.
Pending group members receive add proposals for every other pending group member from the Gateway. If an additional pending member joins while there is not yet an MLS group, they receive all in-flight proposal messages.
Proposal and commit handling follows the same process whether or not there is an established group. See [Proposals and Commits](#proposals-and-commits).
#### Welcome
Pending group members receive a welcome message from another group member which adds them to the MLS group. This is dispatched from the Gateway via [Opcode 30 MLS Welcome](/gateway/opcodes-and-close-codes#voice).
#### Invalid Group
If the group received in an [Opcode 30 MLS Welcome](/gateway/opcodes-and-close-codes#voice) or [Opcode 29 MLS Announce Commit Transition](/gateway/opcodes-and-close-codes#voice) is unprocessable,
the member receiving the unprocessable message sends [Opcode 31 MLS Invalid Commit Welcome](/gateway/opcodes-and-close-codes#voice) to the Gateway.
Additionally, the local group state is reset and a new key package is generated and sent to the Gateway via [Opcode 26 MLS Key Package](/gateway/opcodes-and-close-codes#voice).
This causes the Gateway to propose the removal and re-addition of the requesting member.
### Proposals and Commits
The Gateway dispatches proposals which must be appended or revoked via [Opcode 27 MLS Proposals](/gateway/opcodes-and-close-codes#voice). All members of the established or pending MLS group must append or revoke the proposals they receive,
and then produce an MLS commit message and optionally an MLS welcome message (when committing add proposals which add new members) which they send to the Gateway via [Opcode 28 MLS Commit Welcome](/gateway/opcodes-and-close-codes#voice).
In each epoch, the Gateway dispatches the "winning" commit via [Opcode 29 MLS Announce Commit Transition](/gateway/opcodes-and-close-codes#voice) and optionally the associated welcome messages via [Opcode 30 MLS Welcome](/gateway/opcodes-and-close-codes#voice).
The Gateway broadcasts the first valid commit and welcome(s) it sees in the given epoch, and drops any commits later received for the out-of-date epoch. All dispatched unrevoked proposals in the epoch must be included in the commit for it to be valid.
All members added in the epoch must be welcomed for the welcome to be valid.
### Payload Format
Some fields in the protocol frame payload use [ULEB128 encoding](https://en.wikipedia.org/wiki/LEB128#Unsigned_LEB128). This is a variable-length code compression to represent arbitrarily large unsigned integers in a small number of bytes.
| Field | Type | Description | Size |
| ---------------------- | ----------------------------- | ------------------------------------------------------------ | -------------- |
| Media Frame | Binary data | Interleaved unencrypted and encrypted media frame | Variable bytes |
| Authentication Tag | Binary data | Truncated AES128-GCM AEAD Authentication Tag | 8 bytes |
| Nonce | ULEB128 | Truncated synchronization nonce | Variable bytes |
| Unencrypted Ranges | ULEB128 | Unencrypted range offset and length pairs | Variable bytes |
| Supplemental Data Size | Unsigned integer (big endian) | Byte size of supplemental data | 1 byte |
| Magic Marker | Binary data | `0xFAFA` marker to assist with protocol frame identification | 2 bytes |
###### Media Frame
The encrypted frame transformer is codec-aware and processes incoming encoded frames from WebRTC to determine which ranges must be left unencrypted so that they can pass through the WebRTC packetizer and depacketizer.
All of the (potentially discontiguous) encrypted ranges are joined together, in their order in the original frame, to be encrypted as one block of plaintext, using the AES128-GCM AEAD encryption described below.
All of the (potentially discontiguous) unencrypted ranges from the frame are joined together and included as additional data to be authenticated by the AEAD ciphersuite. This ensures the SFU is unable to include or replace content in user media frames.
In the resulting interleaved protocol media frame, the unencrypted ranges remain unmodified in their original location from the incoming frame. Encrypted ranges are replaced by their associated ciphertext range.
The encrypting frame transformer may mutate the encoded frame it receives to ensure it can pass through the packetizer and depacketizer in an expected and reproducible manner.
###### Authentication Tag
The authentication tag is an 8-byte truncated version of the authentication tag resulting from the AEAD encryption.
###### Nonce
The ULEB128 nonce is a variable length representation of the nonce used for encryption/decryption.
###### Unencrypted Ranges
The unencrypted ranges identify which portions of the interleaved protocol media frame are plaintext and which are ciphertext.
Each included range is represented as a byte offset and byte size pair, with both encoded using ULEB128. Unencrypted ranges are ordered by their ascending byte offset.
The encrypting frame transformer is codec-aware, and processes each incoming encoded frame to determine the unencrypted ranges for the frame.
The decrypted frame transformer deserializes the unencrypted ranges from the protocol supplemental data, and reconstructs the merged additional data and ciphertext necessary for decryption.
###### Supplemental Data Size
The supplemental data size is the sum of bytes required for:
- 8-byte authentication tag
- Variable length ULEB128 nonce
- Variable length ULEB128 unencrypted ranges
- 1 byte supplemental data size
- 2 byte magic marker
###### Magic Marker
The magic marker is a constant 2-byte value `0xFAFA`. This is used by media receivers to detect protocol frames as well as by the SFU to avoid sending protocol frames to non-protocol-supporting receivers during transition periods.
### Payload Encryption
Media frames are encrypted for E2EE using AES128-GCM. Depending on the protocol, some bytes may be left unencrypted to allow for packetization and depacketization of frames. For more detail, see the [codec handling section of the protocol whitepaper](https://daveprotocol.com/#codec-handling).
#### Sender Key Derivation
Each media sender has a ratcheted per-sender key. There is a new per-sender ratchet created in each MLS group epoch. The initial secret for each sender's ratchet is an exported 16-byte secret from the MLS group.
Keys are retrieved from the ratchet via a generation counter derived from the most-significant byte of the 4-byte nonce.
For very long lived epochs, the nonce wrap-around must be handled so the generation does not also wrap back around to 0.
See the [sender key derivation section of the protocol whitepaper](https://daveprotocol.com/#sender-key-derivation) for the detailed process.
###### Authentication Tag
The authentication tag resulting from the AES128-GCM encryption is truncated to 8 bytes. Some implementations may provide the desired tag length as a parameter whereas some may always return the full 12-byte tag from which the 4 least significant bytes should be removed.
###### Nonce
The nonce passed to the AES128-GCM encryption and decryption functions is a full 12-byte nonce, but the protocol only uses at most 4-bytes.
The 12-byte nonce can be expanded from a 4-byte truncated nonce by setting the 8 most significant bytes of the nonce to zero, with the 4 least significant bytes carrying the value of the truncated nonce.
The generation used for the sender's key ratchet is retrieved from the most-significant byte of the 4-byte nonce (i.e. the 4th least significant byte of the full 12-byte nonce).
###### AEAD Additional Data
The additional data passed to the AEAD encryption and decryption functions is the concatenation of all unencrypted ranges from the frame. This ensures that the SFU cannot modify any unencrypted content in the frame without being detected by receivers.
## Heartbeating
In order to maintain your WebSocket connection, you need to continuously send heartbeats at the interval determined in [Opcode 8 Hello](#gateway-events).
This is sent at the start of the connection. Be warned that the [Opcode 8 Hello](#gateway-events) structure differs by Gateway version.
Versions below v3 follow a flat structure without `op` or `d` fields, including only a single `heartbeat_interval` field. Be sure to expect this different format based on your version.
This heartbeat interval is the minimum interval you should heartbeat at. You can heartbeat at a faster interval if you wish.
For example, the web client uses a heartbeat interval of `min(heartbeat_interval, 5000)` if the Gateway version is v4 or above, and `heartbeat_interval * 0.1` otherwise. The desktop client uses the provided heartbeat interval if the Gateway version is v4 or above, and `heartbeat_interval * 0.25` otherwise.
###### Hello Structure
| Field | Type | Description |
| ------------------ | ------- | --------------------------------------------------------------------- |
| v | integer | The [voice server version](#gateway-versions) |
| heartbeat_interval | integer | The minimum interval (in milliseconds) the client should heartbeat at |
###### Example Hello
```json
{
"op": 8,
"d": {
"v": 8,
"heartbeat_interval": 41250
}
}
```
The Gateway may request a heartbeat from the client in some situations by sending an [Opcode 3 Heartbeat](#gateway-events). When this occurs, the client should immediately send an [Opcode 3 Heartbeat](#gateway-events) without waiting the remainder of the current interval.
After receiving [Opcode 8 Hello](#gateway-events), you should send [Opcode 3 Heartbeat](#gateway-events)—which contains an integer nonce—every elapsed interval:
###### Heartbeat Structure
| Field | Type | Description |
| -------- | ------- | -------------------------------------------------------- |
| t | integer | A unique integer nonce (e.g. the current unix timestamp) |
| seq_ack? | integer | The last received sequence number |
###### Example Heartbeat
```json
{
"op": 3,
"d": {
"t": 1501184119561,
"seq_ack": 10
}
}
```
Since Gateway v8, heartbeat messages must include `seq_ack` which contains the sequence number of the last numbered message received from the gateway. See [Buffered Resume](#buffered-resume) for more information.
Previous versions follow a flat structure, with the `d` field representing the `t` field in both the [Heartbeat](#example-heartbeat) and [Heartbeat ACK](#example-heartbeat-ack) structure.
In return, you will be sent back an [Opcode 6 Heartbeat ACK](#gateway-events) that contains the previously sent nonce:
###### Example Heartbeat ACK
```json
{
"op": 6,
"d": {
"t": 1501184119561
}
}
```
## UDP Connections
UDP is the most likely protocol that clients will use. First, we open a UDP connection to the IP and port provided in the Ready payload. If required, we can now perform an [IP Discovery](#ip-discovery) using this connection.
Once we've fully discovered our external IP and UDP port, we can then tell the voice WebSocket what it is by sending a [Select Protocol](#select-protocol-structure) as outlined above, and receive our [Session Description](#session-description-structure) to begin sending/receiving RTC data.
### IP Discovery
Generally routers on the Internet mask or obfuscate UDP ports through a process called NAT. Most users who implement voice will want to utilize IP discovery to find their external IP and port which will then be used for receiving voice communications. To retrieve your external IP and port, send the following UDP packet to your voice port (all numeric are big endian):
| Field | Type | Description | Size |
| ------- | ----------------------------- | ------------------------------------------------------------------ | -------- |
| Type | Unsigned short (big endian) | Values `0x1` and `0x2` indicate request and response, respectively | 2 bytes |
| Length | Unsigned short (big endian) | Message length excluding Type and Length fields (value `70`) | 2 bytes |
| SSRC | Unsigned integer (big endian) | The [SSRC](#ready-structure) of the user | 4 bytes |
| Address | Null-terminated string | The external IP address of the user | 64 bytes |
| Port | Unsigned short (big endian) | The external port number of the user | 2 bytes |
### UDP Ping
Clients may also send a small UDP ping on the same socket. Pinging should start shortly after the UDP socket connects, using a 5 second timeout. Successful responses may be used as the UDP RTT. Media receivers should filter these packets before RTP/RTCP decoding.
#### UDP Ping Structure
| Field | Type | Description | Size |
| -------- | ----------------------------- | ------------------------------------------------- | ------- |
| Magic | Unsigned integer (big endian) | `0x1337CAFE` for requests, `0x1337F00D` responses | 4 bytes |
| Sequence | Unsigned integer | Client-chosen sequence echoed by the response | 4 bytes |
### Sending and Receiving Media
Despite the heading, the UDP transport carries all voice, camera, and stream media. Audio is encoded with [Opus](https://www.opus-codec.org/) at 48kHz stereo.
Video is encoded with the selected codec from the [Session Description](#session-description-structure), then packetized according to that codec's RTP payload format.
UDP media uses RTP for media packets and RTCP for sender reports, receiver reports, and video feedback. IP discovery and UDP ping packets are Discord UDP control packets and are not RTP or RTCP.
The outbound media pipeline is:
1. Encode an audio or video frame
2. Apply [DAVE](#end-to-end-encryption) to the encoded frame if the session has an active usable DAVE transition
3. Packetize the encoded frame as RTP
4. Add RTP header extensions for audio level, speaking state, transport sequence, playout delay, RID, and other negotiated metadata as applicable
5. Encrypt the RTP packet with the transport `secret_key` and selected `mode`
6. Send the encrypted packet to the selected UDP endpoint
The inbound pipeline is the reverse: receive UDP, decrypt transport encryption, parse RTP or RTCP, undo RTX/NACK repair when applicable, depacketize encoded frames, decrypt DAVE when applicable, then decode or dispatch the media.
Transport encryption between the client and the selective forwarding unit (SFU) is still used even in E2EE calls.
In RTP-size AEAD modes, the encrypted UDP packet carries a small nonce suffix that must be stripped before decrypting. The packet size protected by the AEAD authentication tag includes the RTP header and encrypted body, so decryptors should not treat the suffix as RTP payload.
When receiving media, the sender is identified by caching SSRC mappings from [Speaking](#speaking) and [Video](#video) events. Audio-only clients can usually rely on the Speaking event arriving before media,
but full media clients should still treat SSRC mapping as state: video, RTX, and stream SSRCs are announced separately and can change when users enable camera, stream, or simulcast layers.
For suffix and RTP-size encryption modes, strip the appended nonce suffix before decrypting and append a fresh nonce suffix after encrypting media or RTCP packets.
#### RTP Packet Structure
| Field | Type | Description | Size |
| ------------------- | ----------------------------- | ------------------------------------------------------------------------------------------------- | ------- |
| Version + Flags ^1^ | Unsigned byte | The RTP version and flags; version 2 with no padding, extension, or CSRCs is `0x80` | 1 byte |
| Payload Type ^2^ | Unsigned byte | Marker bit plus the [payload type](#codec-structure) (`0x78` with the default Opus configuration) | 1 byte |
| Sequence | Unsigned short (big endian) | The RTP sequence number, wraps at `65535` | 2 bytes |
| Timestamp | Unsigned integer (big endian) | The RTP timestamp; Opus commonly advances by `960` per 20ms frame; video uses a 90kHz clock | 4 bytes |
| SSRC | Unsigned integer (big endian) | The SSRC for the media or RTX stream | 4 bytes |
| CSRCs? | array[integer] | Optional contributing sources when the CSRC count flag is non-zero | n bytes |
| Extension? ^3^ | Binary data | Optional RTP header extension block, usually using the one-byte extension profile `0xBEDE` | n bytes |
| Payload | Binary data | Encrypted audio, video, or RTX payload | n bytes |
^1^ If sending an RTP header extension, set the extension bit (`1 << 4`).
^2^ For video, set the marker bit (`1 << 7`) on the final RTP packet of an encoded frame.
^3^ With RTP-size AEAD transport modes, the clear authenticated data is only the fixed RTP header, any CSRCs, and the 4 byte RTP extension preamble. The individual RTP extension elements are encrypted with the RTP payload.
#### Native RTP Header Extensions
Discord uses the one-byte RTP header extension profile (`0xBEDE`). Extension IDs are negotiated out of band by the Discord client and RTC worker rather than through a public SDP document on UDP connections.
| ID | URI | Applies to | Description |
| --- | --------------------------------------------------------------------------- | ------------ | --------------------------------------------------------------------------------- |
| 1 | `urn:ietf:params:rtp-hdrext:ssrc-audio-level` | Audio | One byte. The high bit is voice activity and the lower 7 bits are audio level |
| 2 | `urn:ietf:params:rtp-hdrext:toffset` | Video | RTP timestamp offset from the send time |
| 3 | `http://www.webrtc.org/experiments/rtp-hdrext/abs-send-time` | Audio, video | Compact send-time value used by congestion control |
| 4 | `urn:3gpp:video-orientation` | Video | Encoded camera orientation |
| 5 | `http://www.ietf.org/id/draft-holmer-rmcat-transport-wide-cc-extensions-01` | Video | Transport sequence number used for congestion control |
| 6 | `http://www.webrtc.org/experiments/rtp-hdrext/playout-delay` | Video | Minimum and maximum receiver playout delay. Discord expects this on video packets |
| 7 | `http://www.webrtc.org/experiments/rtp-hdrext/video-content-type` | Video | Indicates normal video or screen content |
| 8 | `http://www.webrtc.org/experiments/rtp-hdrext/video-timing` | Video | Optional encode/decode timing metadata |
| 9 | `https://discord.com/#rtp-hdrext/2018-07-29/speaker` | Audio | Custom [Discord speaking extension](#discord-speaking-extension) |
| 10 | `urn:ietf:params:rtp-hdrext:sdes:mid` | Audio, video | Media section identifier |
| 11 | `urn:ietf:params:rtp-hdrext:sdes:rtp-stream-id` | Audio, video | RID for primary media packets, such as `100` or `50` |
| 12 | `urn:ietf:params:rtp-hdrext:sdes:repaired-rtp-stream-id` | Audio, video | RID for repaired packets, normally RTX video packets |
#### Audio RTP
Opus audio commonly uses payload type `120` unless a different payload type is selected by [Session Description](#session-description-structure). A normal 20ms Opus frame advances the RTP timestamp by `960` samples at a 48kHz clock. See [Voice Data Interpolation](#voice-data-interpolation) for the silence-frame shutdown behavior.
Clients should send a [Speaking](#speaking) payload before sending audible Opus packets. The Discord speaking RTP extension can also carry packet-level speaking state, while the audio-level extension carries VAD and level metadata for receivers.
##### Discord Speaking Extension
The custom Discord speaking extension is audio RTP extension ID `9` with URI `https://discord.com/#rtp-hdrext/2018-07-29/speaker`.
Its payload is a single byte that encodes the Gateway [speaking flags](#speaking-flags) value from the `speaking` field.
| Extension bit | Speaking flag |
| ------------- | ------------- |
| `0x01` | `PRIORITY` |
| `0x02` | `VOICE` |
| `0x04` | `SOUNDSHARE` |
When sending, let `speaking_flags` be the integer used in the Gateway `speaking` field. Convert it into the extension byte as:
```python
extension = ((speaking_flags & 0x03) << 1) | ((speaking_flags & 0x04) >> 2)
```
This shifts `VOICE` and `SOUNDSHARE` one bit left and moves `PRIORITY` from `0x04` to `0x01`. For example, `VOICE | PRIORITY` (`0x05`) becomes `0x03`.
When receiving a speech packet, missing extension ID `9` and extension value `0x00` should fallback to `VOICE` speaking. If bit `0x01` is set, receivers should also implicitly set `VOICE`. Opus silence packets clear speaking state regardless of this extension.
#### Video RTP
Clients must send [Video](#video) state before sending camera or stream video. The RTP SSRC must match one of the announced video streams, and the RTX SSRC must match that stream's repair SSRC.
Video RTP uses a 90kHz timestamp clock. Encoded frames may be split across multiple RTP packets; only the last packet for the frame should have the RTP marker bit set.
Primary video packets use the negotiated video payload type and the primary stream RID extension. RTX packets use the negotiated RTX payload type and repaired RID extension.
#### RTCP and RTX
Discord uses RTCP sender reports and receiver reports for quality and clock information. Clients should send an RTCP Sender Report roughly every 5 seconds for each sent media SSRC.
Discord sends RTCP Receiver Reports back to the client with packet loss, jitter, and timing feedback.
Video clients should also handle RTCP Generic NACK feedback. When the server reports missing video packets, retransmit them as RTX packets when they are still available.
RTX packets use the stream's `rtx_ssrc`, an RTX payload type, and a payload beginning with the original RTP sequence number followed by the original media payload. Receivers map RTX packets back to the primary media SSRC before depacketizing.
RTCP packets are protected by the same transport encryption. For RTP-size AEAD modes, RTCP feedback packets keep the RTCP header clear as authenticated data and encrypt the feedback body.
#### Media Receive Loop
RTP and RTCP are multiplexed on the same UDP socket. The clear packet header is enough to route packets before transport decryption: RTCP packets use RTCP packet types such as
Sender Report (`200`), Receiver Report (`201`), RTPFB (`205`), and PSFB (`206`), while RTP packets use the negotiated media payload types.
After transport decryption, parse RTP headers, extensions, payload type, sequence, timestamp, and SSRC before dispatching to a decoder. Audio payloads are decoded as Opus.
Video payloads must first be reordered, repaired through RTX when possible, depacketized according to the negotiated codec, DAVE-decrypted when applicable, and then decoded.
Receivers should route media to sinks by user ID when the SSRC is known. During short races where RTP arrives before the matching Gateway state,
implementations can queue briefly by SSRC or route to an SSRC-based fallback sink, then attach the user ID once the [Speaking](#speaking) or [Video](#video) event arrives.
### Quality of Service
Discord utilizes [RTCP](http://www.rfcreader.com/#rfc3550_line855) packets to monitor connection quality, synchronize audio and video, and repair lost video frames.
At minimum, media clients should parse [RTCP Receiver Reports](http://www.rfcreader.com/#rfc3550_line1879) and send [RTCP Sender Reports](http://www.rfcreader.com/#rfc3550_line1614).
Video clients should additionally parse RTCP transport feedback and Generic NACK so they can update congestion state and retransmit recently sent packets through RTX.
The voice server also uses [Media Sink Wants](#simulcasting) to communicate desired send quality. While RTCP describes packet delivery and timing, Media Sink Wants describes what video layers and approximate pixel counts the SFU wants the sender to provide.
## WebRTC Connections
WebRTC is the browser-compatible voice transport. Despite the name, modern Discord WebRTC voice is not peer-to-peer between users. The browser establishes a WebRTC connection to Discord's RTC worker/SFU,
while the voice Gateway WebSocket continues to carry signaling, user, SSRC, video, and media-sink state.
WebRTC replaces the UDP-specific parts of the flow. It does not use [IP Discovery](#ip-discovery), UDP protocol data, `mode`, `secret_key`, or the transport encryption modes from [UDP connections](#udp-connections).
Browser media is protected by ICE, DTLS, and SRTP; when DAVE is active, encoded media frames are additionally encrypted with [DAVE](#end-to-end-encryption).
### Peer Connection Configuration
Modern Discord WebRTC clients use Unified Plan and bundle all media onto one ICE/DTLS transport:
```js
const pc = new RTCPeerConnection({
bundlePolicy: "max-bundle",
sdpSemantics: "unified-plan",
encodedInsertableStreams: daveEnabled,
});
```
Create the base receive transceivers before the first offer. These establish stable media sections and `mid` values for answer generation:
```js
const audio = pc.addTransceiver("audio", { direction: "recvonly" });
const video = pc.addTransceiver("video", { direction: "recvonly" });
```
When the local microphone or camera is enabled, replace the sender track on the matching transceiver and set its direction to `sendrecv`. When a local track is removed, replace it with `null` and set the direction back to `recvonly`. If the track identity changes, renegotiate.
If DAVE is enabled, attach encoded frame transforms to every sender and receiver before media flows. Browser support may be exposed through `RTCRtpScriptTransform` or through the older `RTCRtpSender.createEncodedStreams()` and `RTCRtpReceiver.createEncodedStreams()` APIs.
### Local Offer Processing
The browser's full local offer is not sent to the voice server. Discord web clients derive three pieces of state from the offer:
1. **SDP fragment**: Sent as `data` in [Select Protocol](#select-protocol-structure)
2. **Codec list**: Sent as `codecs` in [Select Protocol](#select-protocol-structure)
3. **Outbound streams**: Kept locally to synthesize the eventual browser remote answer from the server-provided SDP data
#### Outbound Streams
For every media section in the browser offer, record:
| Field | Source | Description |
| ----------- | ------------------------- | ----------------------------------------------------- |
| `type` | `m=` | `audio` or `video` |
| `mid` | `a=mid:` | Browser media-section ID |
| `direction` | media direction attribute | One of `sendrecv`, `sendonly`, `recvonly`, `inactive` |
This list is later used to generate one answer media section for each offered media section. Do not remove, reorder, or collapse entries in this list.
#### Codec Extraction
Extract codecs from the offer's `a=rtpmap` and `a=fmtp` lines. Discord clients advertise only codecs that are present in the browser offer. Opus is used for audio. For video, modern clients prefer H265 when it is enabled and present, otherwise they use H264 first, followed by VP8 and VP9.
For each codec:
1. Find the `a=rtpmap: /` entry for the codec name.
2. Set `payload_type` to that RTP payload number.
3. For video, find a matching RTX payload by locating an `a=fmtp: apt=` line whose `apt` points back to the video payload, then find the corresponding `a=rtpmap: rtx/90000` line.
4. Set `rtx_payload_type` to the RTX payload number for video, or `null` for audio.
5. Assign codec priority by codec order within each media type, multiplied by 1000 on the wire.
The codec order used by modern clients is:
- Audio: `opus`
- Video: `H265`, `H264`, `VP8`, and `VP9`
For browser-generated offers, the browser chooses the dynamic payload types. Do not rewrite browser WebRTC payload types to UDP defaults. For example, Opus is usually payload type `111` in browser offers, not the default UDP Opus payload type `120`.
Non-browser WebRTC stacks that construct their own offer may choose different dynamic payload types, but the payload numbers must remain consistent across the local SDP, [Select Protocol](#select-protocol-structure) codec list, and generated answer.
#### Local SSRC Extraction
When a local media section is `sendrecv`, extract the local SSRCs from `a=ssrc` lines:
| Media | Extracted value | Source |
| ----- | --------------- | ------------------------------------------------------------------- |
| audio | Audio SSRC | First audio `a=ssrc: cname:...` in a `sendrecv` audio section |
| video | Video SSRC | First video `a=ssrc: cname:...` in a `sendrecv` video section |
| video | RTX SSRC | Last video `a=ssrc: cname:...` in a `sendrecv` video section |
The local audio/video SSRCs are used for [Speaking](#speaking), [Video](#video), and DAVE sender state. The video and RTX SSRCs should also be reflected in the [Video](#video) payload's stream parameters.
### Select Protocol SDP Fragment
The `data` field in a WebRTC [Select Protocol](#select-protocol-structure) payload is not the full local SDP. It is a stripped SDP fragment built from the browser's local offer after ICE gathering has completed.
Build it from the full local SDP using this exact rule:
1. Keep every line matching `^a=(extmap-allow-mixed|ice-|fingerprint|extmap:)`.
2. Keep only `a=rtpmap` lines for Opus, VP8, and the RTX payload whose `apt` points at VP8.
3. Remove duplicates.
4. Join the remaining lines with `\n`.
Other video codecs are still advertised in the `codecs` field of [Select Protocol](#select-protocol-structure) when they are present in the browser offer; their `a=rtpmap` lines are not included in this SDP fragment.
In pseudocode:
```js
const vp8Codec = codecs.find((codec) => codec.name === "VP8");
const data = localSdp
.split(/\r?\n/)
.filter((line) => {
if (/^a=(extmap-allow-mixed|ice-|fingerprint|extmap:)/i.test(line)) return true;
if (/^a=rtpmap:\d+\s+opus\//i.test(line)) return true;
if (/^a=rtpmap:\d+\s+VP8\//i.test(line)) return true;
const rtxRtpmap = /^a=rtpmap:(\d+)\s+rtx\//i.exec(line);
return rtxRtpmap != null && Number(rtxRtpmap[1]) === vp8Codec?.rtx_payload_type;
})
.filter((line, index, lines) => lines.indexOf(line) === index)
.join("\n");
```
The fragment intentionally does **not** contain `v=`, `o=`, `s=`, `t=`, `m=`, `c=`, `a=group`, `a=mid`, `a=setup`, `a=rtcp-mux`, `a=sendrecv`, `a=recvonly`, `a=ssrc`, `a=fmtp`, or `a=rtcp-fb` lines.
#### Example Select Protocol SDP Fragment
```sh
a=extmap-allow-mixed
a=ice-ufrag:9WZo
a=ice-pwd:vcfFowC3gQI1KHu0Fm5ZTXum
a=ice-options:trickle
a=fingerprint:sha-256 71:20:4C:BE:C2:D0:B7:9B:73:5B:4B:29:7C:32:41:25:D8:D2:BC:66:74:D3:93:98:B3:0D:01:F7:67:19:01:13
a=extmap:1 urn:ietf:params:rtp-hdrext:ssrc-audio-level
a=extmap:2 http://www.webrtc.org/experiments/rtp-hdrext/abs-send-time
a=extmap:3 http://www.ietf.org/id/draft-holmer-rmcat-transport-wide-cc-extensions-01
a=extmap:4 urn:ietf:params:rtp-hdrext:sdes:mid
a=rtpmap:111 opus/48000/2
a=extmap:14 urn:ietf:params:rtp-hdrext:toffset
a=extmap:13 urn:3gpp:video-orientation
a=extmap:5 http://www.webrtc.org/experiments/rtp-hdrext/playout-delay
a=extmap:6 http://www.webrtc.org/experiments/rtp-hdrext/video-content-type
a=extmap:7 http://www.webrtc.org/experiments/rtp-hdrext/video-timing
a=extmap:8 http://www.webrtc.org/experiments/rtp-hdrext/color-space
a=extmap:10 urn:ietf:params:rtp-hdrext:sdes:rtp-stream-id
a=extmap:11 urn:ietf:params:rtp-hdrext:sdes:repaired-rtp-stream-id
a=rtpmap:96 VP8/90000
a=rtpmap:97 rtx/90000
```
### Server SDP Validation
For WebRTC, [Session Description](#session-description-structure) contains `sdp` instead of `mode` and `secret_key`. The server `sdp` must include the transport information needed to construct the browser remote answer.
Validate at least the following before generating the answer:
| Required data | Required line pattern or field |
| --------------------- | --------------------------------------------- |
| DTLS fingerprint | `a=fingerprint:...` |
| ICE username fragment | `a=ice-ufrag:...` |
| ICE password | `a=ice-pwd:...` |
| ICE candidate | `a=candidate:...` |
| Connection address | `c= ` |
The `c=` line must have at least three space-separated components. If any of these are absent, the SDP cannot produce a valid browser remote description.
### Generating the Browser Remote Answer
The `sdp` value from [Session Description](#session-description-structure) is not enough by itself to describe all remote users and browser transceivers. Discord web clients synthesize a complete `RTCSessionDescription` of type `answer` by combining:
- The server `sdp` transport/codec template,
- The selected `audio_codec` and `video_codec`,
- The selected audio, video, and RTX payload types from the local offer,
- The local offer's outbound stream list (`type`, `mid`, `direction`),
- Known remote user audio/video SSRCs from [Speaking](#speaking) and [Video](#video), and
- The RTP header extensions extracted from the local offer.
The generated answer has the following session-level shape:
```sh
v=0
o=- 1420070400000 0 IN IP4 127.0.0.1
s=-
t=0 0
a=group:BUNDLE
a=msid-semantic: WMS *
```
The BUNDLE mids are the `mid` values of every generated media section that has a `mid`.
For every media section from the local offer's outbound stream list, generate exactly one answer media section, in the same order. The answer direction is based on the offer direction:
| Offer direction | Answer direction when a remote SSRC is assigned | Answer direction when no remote SSRC is assigned |
| --------------- | ----------------------------------------------- | ------------------------------------------------ |
| `recvonly` | `sendonly` | `inactive` |
| `sendonly` | `recvonly` | `recvonly` |
| `sendrecv` | `sendrecv` | `recvonly` |
| `inactive` | `inactive` | `inactive` |
The remote answer must keep the same m-line count and order as the local offer. If another remote user is discovered and there are not enough inactive receive transceivers for that media type, add more `recvonly` transceivers and create a new local offer before generating the next answer. Do not reorder existing transceivers.
The transceiver and remote-user assignment rules above describe browser clients. Custom WebRTC stacks that construct their own local offer with fixed send/receive m-lines can generate a simpler answer for those offered m-lines, as long as the answer preserves the offer's m-line count and order and uses the negotiated transport, codec, SSRC, and RTP extension values consistently.
Each generated media section uses:
| Property | Value |
| ------------- | ------------------------------------------------------------ |
| `m=` protocol | `UDP/TLS/RTP/SAVPF` |
| `a=setup` | `passive` for the answer |
| `a=mid` | The original offered media section's `mid` |
| `a=rtcp-mux` | Present |
| payloads | Selected codec payload, plus RTX payload for video when used |
Custom WebRTC stacks that construct their own answers may include `a=ice-lite` for easier implementation.
#### Answer Audio Media Sections
For an audio media section:
| SDP field | Value |
| ------------ | ---------------------------------------------------------------------- |
| `a=rtpmap` | Selected audio payload with `opus/48000/2` |
| `a=fmtp` | For Opus: `minptime=10;useinbandfec=1;usedtx=<0 or 1>` |
| `a=maxptime` | `60` |
| `a=rtcp-fb` | `transport-cc`, optionally `nack`, except in Firefox-specific handling |
| `a=extmap` | Audio level and transport-wide congestion control, when offered |
`usedtx` is `0` when the local client is sending video and `1` otherwise.
#### Answer Video Media Sections
For a video media section:
| SDP field | Value |
| -------------- | -------------------------------------------------------------------------------------------- |
| `a=rtpmap` | Selected video payload with a 90 kHz clock rate |
| `a=fmtp` | `x-google-max-bitrate=` |
| H264 `a=fmtp` | Also include `level-asymmetry-allowed=1;packetization-mode=1;profile-level-id=42e01f` |
| `a=rtcp-fb` | `ccm fir`, `nack`, `nack pli`, `goog-remb`, and `transport-cc` |
| RTX `a=rtpmap` | RTX payload with `rtx/90000`, when RTX is used |
| RTX `a=fmtp` | `apt=` |
| `a=extmap` | Video timestamp, orientation, congestion-control, and playout-delay extensions, when offered |
Video answers include RTX by appending the RTX payload to the media payload list and adding the RTX `rtpmap` and `fmtp` lines.
#### Answer SSRC and MSID Lines
For an assigned stream, generate SSRC metadata from the remote user ID and SSRC. For a primary SSRC `S`, user ID `U`, and media sentinel `a` for audio or `v` for video:
```sdp
a=ssrc:S cname:U-S
a=ssrc:S msid:U-S U-S
a=ssrc:S mslabel:U-S
a=ssrc:S label:U-S
```
In Unified Plan, browsers generally require the media-level `a=msid` and only the `cname` SSRC attribute:
```sdp
a=msid:U-S U-S
a=ssrc:S cname:U-S
```
For video with RTX, include an `FID` SSRC group and matching SSRC metadata for the retransmission SSRC. The web SDP generator derives the answer-side retransmission SSRC as the primary video SSRC plus one; it does not consume the `rtx_ssrc` value from a received [Video](#video) stream object when building the answer:
```sdp
a=ssrc-group:FID
```
### Transceivers, SSRCs, and Remote Users
Discord still uses voice Gateway events to identify users and SSRCs. WebRTC clients should not rely only on browser track arrival order to identify speakers.
Use [Speaking](#speaking) events to learn a user's audio SSRC. Use [Video](#video) events to learn a user's video SSRC and stream parameters, including any `rtx_ssrc` metadata reported by the Gateway. The browser answer assigns receive media sections from the primary audio and video SSRCs;
RTX metadata in the answer is generated from the assigned primary video SSRC. When a new remote SSRC appears, ensure there is a receive transceiver available for the corresponding media type and renegotiate if necessary.
In Unified Plan, the generated remote description should assign incoming SSRCs to media sections by `mid`. When there are more remote audio or video streams than inactive receive transceivers, add new `recvonly` transceivers and create a new offer before applying the next answer.
Do not reorder existing transceivers because browsers require remote answers to keep the offer's m-line order.
Incoming `MediaStreamTrack` objects can be mapped back to users using the SSRC/user mapping from Gateway events and, where present, the SDP `msid`/stream labels. Treat the voice Gateway SSRC mapping as authoritative.
### Local Media State
The WebRTC transport uses normal browser `MediaStreamTrack` objects for local microphone and camera media. Muting should stop microphone media from being sent; web clients can do this by disabling the local audio track and sending a non-speaking state.
Replacing the sender track with `null` is used when the local stream or track is removed. Camera changes require renegotiation when the video track changes.
When a local camera stream starts, clients should also send [Opcode 12 Video](#video) with the current audio SSRC, video SSRC, RTX SSRC, and stream parameters.
When camera stops, send another Video payload indicating an inactive or zero video SSRC state, depending on the negotiated state.
Screenshare/Go Live streams use separate stream connections, as described in [Streams](#streams), even when the transport for that stream connection is WebRTC.
### WebRTC RTP Header Extensions
The Select Protocol SDP fragment sends every `a=extmap` line from the local offer. During answer generation, include only extensions that make sense for the media section.
Note that not all extensions are necessarily offered in every WebRTC client or available in every browser.
Browser clients let the browser serialize RTP header extensions. Custom packetizers should use the negotiated extension IDs from their SDP and include Discord-required extensions themselves;
in particular, video packets are expected to carry the playout-delay extension when that extension is negotiated.
The common Discord extension URIs are listed in [Native RTP Header Extensions](#native-rtp-header-extensions), but the numeric IDs in WebRTC are the IDs from SDP, not the native UDP IDs.
For example, a browser offer might use audio-level as `a=extmap:1 ...` and transport-wide CC as `a=extmap:3 ...`, while the native UDP video map uses transport-wide CC ID `5`.
### Congestion, Quality, and Sink Wants
After WebRTC is connected, the client should continue sending [Media Sink Wants](#simulcasting) for remote video streams.
WebRTC clients should monitor `RTCPeerConnection.getStats()` for packet loss, jitter, frames, bitrate, and round-trip time. Discord clients use these stats for connection quality, video quality, ping display, stream health, and analytics.
### WebRTC and DAVE
DAVE negotiation uses the same voice Gateway fields and opcodes for UDP and WebRTC.
The WebRTC-specific requirement is that encoded frame encryption/decryption must be attached to each relevant sender and receiver. If encoded transforms are unavailable, the client should advertise DAVE protocol version `0` and expect calls that require E2EE to close with the relevant voice close code.
## Speaking
To notify the voice server that you are speaking or have stopped speaking, send an [Opcode 5 Speaking](#gateway-commands) payload:
You must send at least one [Speaking](#speaking) payload before sending or receiving data, or you will be disconnected with an Invalid SSRC error.
###### Speaking Structure
| Field | Type | Description |
| ------------ | --------- | ------------------------------------- |
| speaking ^1^ | integer | The [speaking flags](#speaking-flags) |
| ssrc | integer | The SSRC of the speaking user |
| user_id ^2^ | snowflake | The user ID of the speaking user |
| delay? ^3^ | integer | The speaking packet delay |
^1^ For Gateway v3 and below, this field is a boolean.
^2^ Only sent by the voice server.
^3^ Not sent by the voice server.
###### Speaking Flags
| Value | Name | Description |
| -------- | ---------- | -------------------------------------------------------------- |
| 1 \<\< 0 | VOICE | Normal transmission of voice audio |
| 1 \<\< 1 | SOUNDSHARE | Transmission of context audio for video, no speaking indicator |
| 1 \<\< 2 | PRIORITY | Priority speaker, lowering audio of other speakers |
###### Example Speaking (Send)
```json
{
"op": 5,
"d": {
"speaking": 5,
"delay": 0,
"ssrc": 1
}
}
```
When a different user's speaking state is updated, and for each user with a speaking state at connection start, the voice server will send an [Opcode 5 Speaking](#gateway-events) payload:
###### Example Speaking (Receive)
```json
{
"op": 5,
"d": {
"speaking": 5,
"ssrc": 2,
"user_id": "852892297661906993"
}
}
```
### Voice Data Interpolation
When there's a break in the sent data, the packet transmission shouldn't simply stop. Instead, send five frames of silence (`0xF8, 0xFF, 0xFE`) before stopping to avoid unintended Opus interpolation with subsequent transmissions.
Likewise, when you receive these five frames of silence, you know that the user has stopped speaking.
## Video
To notify the voice server that you are sending video, send an [Opcode 12 Video](#gateway-commands) payload:
You must send at least one [Video](#video) payload before sending or receiving video data, or you will be disconnected with an Invalid SSRC error.
###### Video Structure
| Field | Type | Description |
| ------------ | ----------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| audio_ssrc | integer | On send, this connection's audio SSRC from [Ready](#ready-structure). On receive, the remote user's audio SSRC associated with this video state |
| video_ssrc | integer | On send, the selected primary outbound video SSRC, or `0` when clearing video. On receive, the remote user's primary video SSRC |
| rtx_ssrc ^1^ | integer | On send, the RTX SSRC paired with `video_ssrc`, or `0` when clearing video. This should match the selected stream's `rtx_ssrc` when RTX is active |
| streams | array[[stream](#stream-structure) object] | Current video stream state. For simulcast, this is the authoritative list of primary and RTX SSRCs for every layer. Send an empty array when clearing local video |
| user_id ^2^ | snowflake | The user ID of the video user |
^1^ The top-level `rtx_ssrc` is not sent by the voice server. Received stream objects can still include `rtx_ssrc`.
^2^ Only sent by the voice server.
###### Example Video (Send)
```json
{
"op": 12,
"d": {
"audio_ssrc": 13959,
"video_ssrc": 13960,
"rtx_ssrc": 13961,
"streams": [
{
"type": "video",
"rid": "100",
"ssrc": 13960,
"active": true,
"quality": 100,
"rtx_ssrc": 13961,
"max_bitrate": 9000000,
"max_framerate": 60,
"max_resolution": {
"type": "source",
"width": 0,
"height": 0
}
}
]
}
}
```
When a different user's video state is updated, and for each user with a video state at connection start, the voice server will send an [Opcode 12 Video](#gateway-events) payload:
###### Example Video (Receive)
```json
{
"op": 12,
"d": {
"user_id": "852892297661906993",
"audio_ssrc": 13959,
"video_ssrc": 13960,
"streams": [
{
"ssrc": 13960,
"rtx_ssrc": 13961,
"rid": "100",
"quality": 100,
"max_resolution": {
"width": 0,
"type": "source",
"height": 0
},
"max_framerate": 60,
"active": true
}
]
}
}
```
### Sending Video
Video state is negotiated in three places:
1. [Identify](#identify-structure) advertises whether this voice connection supports video and which local simulcast RIDs the client supports.
2. [Ready](#ready-structure) assigns the actual primary and RTX SSRCs for those streams.
3. [Video](#video) announces which of those assigned streams are currently active.
The top-level `video_ssrc`/`rtx_ssrc` pair should point at the selected primary outbound stream. The `streams` array carries the full active video state, including every simulcast layer a receiver may map or request.
When a local source is paused, send another [Video](#video) payload with that stream's `active` flag set to `false`. When resuming, send `active: true` and prefer sending a keyframe as soon as possible so receivers can decode without waiting for an old reference frame.
RTP packetization, header extensions, and RTX retransmission details are covered in [Video RTP](#video-rtp) and [RTCP and RTX](#rtcp-and-rtx).
### Receiving Video
Receiving clients should cache SSRC ownership from every received [Video](#video) payload:
- `audio_ssrc` maps the user's audio stream.
- Each stream `ssrc` maps primary video RTP for that user.
- Each stream `rtx_ssrc` maps repaired video RTP for the same stream.
- `rid` and `quality` identify the simulcast layer represented by the stream.
Video RTP packets are not self-describing enough to choose a user, stream, or sink without this state. If a packet arrives before the Video event that maps its SSRC, queue it briefly or drop it; do not assume all unknown video packets belong to the speaking audio SSRC.
Receivers request layers through [Media Sink Wants](#simulcasting). The SFU may still send packets during transitions, so receivers should tolerate short overlap between old and new layer choices.
## Resuming Voice Connection
When your client detects that its connection has been severed, it should open a new WebSocket connection. Once the new connection has been opened, your client should send an [Opcode 7 Resume](#gateway-commands) payload:
###### Resume Structure
| Field | Type | Description |
| -------------- | --------- | ------------------------------------------------------------------------- |
| server_id | snowflake | The ID of the guild, private channel, stream, or lobby being connected to |
| channel_id ^2^ | snowflake | The ID of the channel being connected to |
| session_id | string | The session ID of the current session |
| token | string | The voice token for the current session |
| seq_ack? ^1^ | integer | The last received sequence number |
^1^ Only available on Gateway v8 and above.
^2^ Only required for Gateway v9 and above.
###### Example Resume
```json
{
"op": 7,
"d": {
"server_id": "41771983423143937",
"channel_id": "127121515262115840",
"session_id": "30f32c5d54ae86130fc4a215c7474263",
"token": "66d29164ee8cd919",
"seq_ack": 10
}
}
```
If successful, the voice server will respond with an [Opcode 9 Resumed](#gateway-commands) to signal that your client is now resumed:
###### Example Resumed
```json
{
"op": 9,
"d": null
}
```
If the resume is unsuccessful—for example, due to an invalid session—the WebSocket connection will close with the appropriate [close code](/gateway/opcodes-and-close-codes#voice-close-event-codes). You should then follow the [Connecting](#connecting-to-voice) flow to reconnect.
### Buffered Resume
Since version 8, the Gateway can resend buffered messages that have been lost upon resume. To support this, the Gateway includes a sequence number with all messages that may need to be re-sent.
###### Example Message With Sequence Number
```json
{
"op": 5,
"d": {
"speaking": 0,
"delay": 0,
"ssrc": 110
},
"seq": 10
}
```
A client using Gateway v8 must include the last sequence number they received under the data `d` key as `seq_ack` in both the [Opcode 3 Heartbeat](#gateway-commands) and [Opcode 7 Resume](#gateway-commands) payloads.
If no sequence numbered messages have been received, `seq_ack` can be omitted or included with a value of -1.
The Gateway uses a fixed bit length sequence number and handles wrapping the sequence number around. Since Gateway messages will always arrive in order, a client only needs to retain the last sequence number they have seen.
If the session is successfully resumed, the Gateway will respond with an [Opcode 9 Resumed](#gateway-events) and will re-send any messages that the client did not receive.
The resume may be unsuccessful if the buffer for the session no longer contains a message that has been missed. In this case the session will be closed and you should then follow the [Connecting](#connecting-to-voice) flow to reconnect.
## Connected Clients
### Client Connections
At connection start, and when a client thereafter connects to voice, the voice server will send a series of events.
This includes an [Opcode 11 Clients Connect](#gateway-events) containing every connected user, as well as individual [Opcode 18 Client Flags](#gateway-events) and [Opcode 20 Client Platform](#gateway-events) for each user.
These events are meant to inform a new client of all existing clients and their flags/platform, and inform existing clients of a newly-connected client.
[Opcode 18 Client Flags](#gateway-events) and [Opcode 20 Client Platform](#gateway-events) are erroneously sent in stream contexts and should be ignored.
###### Clients Connect Structure
| Field | Type | Description |
| -------- | ---------------- | ----------------------------------- |
| user_ids | array[snowflake] | The IDs of the users that connected |
###### Example Clients Connect
```json
{
"op": 11,
"d": {
"user_ids": ["852892297661906993"]
}
}
```
###### Client Flags Structure
| Field | Type | Description |
| ------- | --------- | -------------------------------------- |
| user_id | snowflake | The ID of the user that connected |
| flags | ?integer | The [user's voice flags](#voice-flags) |
###### Voice Flags
| Value | Name | Description |
| -------- | ---------------------- | -------------------------------------------------------------------------------------------- |
| 1 \<\< 0 | CLIPS_ENABLED | User has [clips](https://support.discord.com/hc/en-us/articles/16861982215703-Clips) enabled |
| 1 \<\< 1 | ALLOW_VOICE_RECORDING | User has allowed their voice to be recorded in another user's clips |
| 1 \<\< 2 | ALLOW_ANY_VIEWER_CLIPS | User has allowed stream viewers to clip them |
###### Example Client Flags
```json
{
"op": 18,
"d": {
"user_id": "852892297661906993",
"flags": 3
}
}
```
###### Client Platform Structure
| Field | Type | Description |
| -------- | --------- | -------------------------------------------- |
| user_id | snowflake | The ID of the user that connected |
| platform | ?integer | The [user's voice platform](#voice-platform) |
###### Voice Platform
| Value | Name | Description |
| ----- | ----------- | ----------------------- |
| 0 | DESKTOP | Desktop-based client |
| 1 | MOBILE | Mobile client |
| 2 | XBOX | Xbox integration |
| 3 | PLAYSTATION | PlayStation integration |
###### Example Client Platform
```json
{
"op": 20,
"d": {
"user_id": "852892297661906993",
"platform": 0
}
}
```
### Client Disconnections
When a user disconnects from voice, the voice server will send an [Opcode 13 Client Disconnect](#gateway-events):
When received, the SSRC of the user should be discarded.
###### Client Disconnect Structure
| Field | Type | Description |
| ------- | --------- | ------------------------------------ |
| user_id | snowflake | The ID of the user that disconnected |
###### Example Client Disconnect
```json
{
"op": 13,
"d": {
"user_id": "852892297661906993"
}
}
```
## Simulcasting
The voice server supports simulcasting, allowing clients to send multiple video layers and allowing receivers to request the layer that best fits the current view.
A full-size focused video can request quality `100`, while a thumbnail, background stream, or muted/off-screen user can request lower quality or `0`.
Simulcast state is described by [stream objects](#stream-structure). The `rid` identifies the RTP stream ID, `quality` describes the layer's intended quality, `ssrc` identifies primary RTP, `rtx_ssrc` identifies retransmissions, and `active` tells receivers whether the sender currently intends to transmit that layer.
Camera video commonly offers two layers: one full-size stream at quality `100`, and another reduced-quality stream at `50`.
Stream connections commonly offer one screen layer at quality `100`. The client proposes RIDs in [Identify](#identify-structure), but the [Ready](#ready-structure) payload assigns the real SSRCs.
[Media Sink Wants](#media-sink-wants-structure) is the control message for desired receive and send quality. A receiving client sends [Opcode 15 Media Sink Wants](#gateway-commands) to tell the SFU which remote SSRCs it wants and at what quality.
The voice server may also send [Opcode 15 Media Sink Wants](#gateway-events) to tell a sender which of its local SSRCs should currently be active or reduced.
The keys in the payload are primary media SSRCs, not RTX SSRCs. A special key of `any` applies to otherwise unspecified streams. Values are `0` through `100`, where `0` disables a stream and `100` requests the highest available layer.
The optional `pixelCounts` object gives the SFU approximate rendered pixel counts for each SSRC, which helps it choose between layers when a view is resized.
A sender should treat server-sent wants as dynamic encoder input, not as the sole source of [Video](#video) stream state. If a layer is wanted at `0`, pause that layer and announce it inactive when appropriate.
If a layer is wanted at a lower quality, reduce bitrate, resolution, framerate, or choose a lower RID rather than continuing to send the full layer.
Receivers should keep sending updated wants as views appear, disappear, resize, pin, or move between foreground and background.
This functionality is only available on [Gateway version 5 and above](#gateway-versions).
###### Media Sink Wants Structure
| Field | Type | Description |
| ------------ | ----------------------- | ----------------------------------------------------------------- |
| \{ssrc\}? | integer | Desired quality for the stream with the matching SSRC key (0-100) |
| any? | integer | Desired quality for all otherwise unspecified streams (0-100) |
| pixelCounts? | object[integer, number] | Desired approximate pixel count for each stream, keyed by SSRC |
###### Example Media Sink Wants
```json
{
"op": 15,
"d": {
"8964": 100,
"any": 50,
"pixelCounts": {
"8964": 1189844.5769597634
}
}
}
```
## Voice Backend Version
For analytics, the client may want to receive information about the voice backend's current version. To do so, send an [Opcode 16 Voice Backend Version](#gateway-commands) with an empty payload.
This functionality is only available on [Gateway version 6 and above](#gateway-versions).
###### Voice Backend Version Structure
| Field | Type | Description |
| ---------- | ------ | --------------------------- |
| voice | string | The voice backend's version |
| rtc_worker | string | The WebRTC worker's version |
###### Example Voice Backend Version (Send)
```json
{
"op": 16,
"d": {}
}
```
In response, the voice server will send an [Opcode 16 Voice Backend Version](#gateway-events) payload with the versions:
###### Example Voice Backend Version (Receive)
```json
{
"op": 16,
"d": {
"voice": "0.9.1",
"rtc_worker": "0.3.35"
}
}
```
## No Route
If a client cannot establish any usable RTC route after selecting a protocol, it may send an [Opcode 32 No Route](#gateway-commands) payload with an empty payload.
This informs the voice server that connection setup failed at the RTC transport layer.
###### Example No Route
```json
{
"op": 32,
"d": {}
}
```
## Streams
Stream connections operate in a similar fashion to regular voice connections. In fact, on the protocol side, they are identical and use all of the payloads and processes described above.
The main differences are within the [Gateway](/gateway/using-gateway) protocol, as streams are started and joined differently to regular voice connections.
### Connecting to Streams
To start or join a stream, the client must first be connected to the voice instance that the stream is hosted on.
Then, send a [Create Stream](/gateway/gateway-events#create-stream) or [Watch Stream](/gateway/gateway-events#watch-stream) payload to the Gateway.
If our request succeeded, as with voice, you must wait for the Gateway to respond with _two_ events—a [Stream Create](/gateway/gateway-events#stream-create) event and a [Stream Server Update](/gateway/gateway-events#stream-server-update).
You can then use the information provided in these events to establish a connection to the stream server as outlined in [Connecting to Voice](#connecting-to-voice).
Note that the `server_id` and `channel_id` used when [identifying](#establishing-a-voice-websocket-connection) will be provided in the [Stream Create](/gateway/gateway-events#stream-create) event.
Note that if joining a stream fails, the Gateway will instead respond with a [Stream Delete](/gateway/gateway-events#stream-delete) event which will contain the reason for the failure.
### Stream Media Connections
A stream uses a separate RTC connection from the parent voice channel. The parent voice connection must remain connected so the user remains in the voice instance, but the stream has its own WebSocket, transport, state, and media packets.
If the stream includes application or system audio, send that audio on the stream RTC connection as Opus.
Clients should mark this with the [`SOUNDSHARE` speaking flag](#speaking-flags) rather than normal voice speaking, so viewers can treat it as contextual stream audio.
Stream viewers connect to the stream RTC connection and request the stream SSRCs they want with [Media Sink Wants](#simulcasting).
Do not use the parent voice connection's audio or video SSRCs for stream media; the stream connection has its own SSRC namespace.
Additionally, do not attempt to send media to streams you are viewing. Only stream owners should transmit data to the RTC connection.
For stream E2EE, clients must use a stream-specific MLS group ID rather than the voice channel ID. Current stream RTC uses the media-session ID, which is one less than the stream `rtc_server_id`, as the DAVE/MLS group ID.
If a stream becomes unavailable, reset RTP receive, RTCP feedback, DAVE, and transport state for that stream RTC connection. The parent voice connection and its media state are independent and unaffected.
---
# Phone Verification
Link: https://docs.discord.food/topics/phone-verification
Discord allows users to add a phone number to their account for various purposes, such as account security, verification, and contact syncing.
There are a few different flows for phone verification, depending on the context in which the phone number is being used.
## Registering with a Phone Number
When registering a new account, users can provide a phone number to verify their account. This flow is outlined in the [account registration documentation](/authentication#phone-registration).
## Adding a Phone Number
Users can add a phone number to their account at any time. This is required for certain features, or, in some cases, for [anti-abuse purposes](/resources/user#required-action-type).
To add a phone number, clients must first send a request to the [Add Phone Number](#add-phone-number) endpoint with the phone number the user wishes to add, and preferrably a reason for the change. This will send a verification code to the phone number via SMS.
After the user receives the code, clients must then use the [Verify Phone Number](#verify-phone-number) endpoint with the phone number and the code to receive a phone verification token.
After receiving the token, clients can then use the [Add Phone Number](#add-phone-number) endpoint again, providing the verification token, the user's password, and the same reason to complete the process.
Phone numbers can only be associated with one Discord account at a time. Adding a phone number that is already associated with another account may result in the phone number being removed from the other account.
Registering a new account with a phone number that is already associated with another account will fail, and the user will need to remove the phone number from the other account first.
## Reverifying Your Phone Number
Users may be prompted to reverify their phone number for [anti-abuse purposes](/resources/user#required-action-type).
In this case, clients must follow the same flow as [adding a phone number](#adding-a-phone-number), but instead of the [Add Phone Number](#add-phone-number) endpoint, they must use the [Reverify Phone Number](#reverify-phone-number) endpoint.
## Removing Your Phone Number
Users can remove a phone number from their account at any time. Note that if a phone number was added for anti-abuse purposes, the user may be required to add a new phone number before they can continue using their account.
To remove a phone number, clients must send a request to the [Remove Phone Number](#remove-phone-number) endpoint with the user's password and an optional reason for removing the phone number.
###### Change Phone Reason
| Value | Description |
| -------------------- | ----------------------------------------------------------------------- |
| user_action_required | Phone number is required for anti-abuse purposes |
| user_settings_update | Phone number is manually added by the user |
| guild_phone_required | Phone number is required to fulfill a guild's verification requirements |
| mfa_phone_update | Phone number is desired to enable SMS MFA |
| contact_sync | Phone number is desired to sync contacts |
## Endpoints
Verify Phone Number
Verifies a phone number for use in Discord. A code must first be sent to the phone number via a verification flow.
###### JSON Params
| Field | Type | Description |
| ----- | ------ | ------------------------------------------ |
| phone | string | The E.164-formatted phone number to verify |
| code | string | The code received via SMS |
###### Response Body
| Field | Type | Description |
| ----- | ------ | --------------------------------------- |
| token | string | The token to use for phone verification |
Resend Verification Code
Resends a verification code to the given phone number. Returns a 204 empty response on success.
###### JSON Params
| Field | Type | Description |
| ----- | ------ | ---------------------------------------------------- |
| phone | string | The E.164-formatted phone number to resend a code to |
Add Phone Number
Adds a phone number to the current user's account. Returns a 204 empty response on success. Fires a [User Update](/gateway/gateway-events#user-update) and optionally a [User Required Action Update](/gateway/gateway-events#user-required-action-update) Gateway event.
Providing the `phone` parameter will send a verification code to the phone number. After the phone number is [verified](#verify-phone-number), the request should be retried, providing `phone_token` and `password` (and NOT `phone`) to complete the process.
###### JSON Params
| Field | Type | Description |
| -------------------- | ------ | ------------------------------------------------------------------------------------------------ |
| phone? | string | The E.164-formatted phone number to send a verification code to |
| phone_token? | string | The phone verification token received from the [phone registration flow](#adding-a-phone-number) |
| password? | string | The user's current password; if the account does not have a password, this sets it |
| change_phone_reason? | string | The [reason](#change-phone-reason) for adding a phone number |
Reverify Phone Number
Reverifies a phone number for the current user. This endpoint should only be used when a [relevant required action](/resources/user#required-action-type) is received. The phone number provided must match the phone number currently associated with the account.
Fires a [User Update](/gateway/gateway-events#user-update) and optionally a [User Required Action Update](/gateway/gateway-events#user-required-action-update) Gateway event.
Providing the `phone` parameter will send a verification code to the phone number. After the phone number is [verified](#verify-phone-number), the request should be retried, providing `phone_token` and `password` (and NOT `phone`) to complete the process.
###### JSON Params
| Field | Type | Description |
| -------------------- | ------ | ------------------------------------------------------------------------------------------------ |
| phone? | string | The E.164-formatted phone number to send a verification code to |
| phone_token? | string | The phone verification token received from the [phone registration flow](#adding-a-phone-number) |
| password? | string | The user's current password; if the account does not have a password, this sets it |
| change_phone_reason? | string | The [reason](#change-phone-reason) for adding a phone number |
Remove Phone Number
Removes the phone number from the current user. Returns a 204 empty response on success. Fires a [User Update](/gateway/gateway-events#user-update) and optionally a [User Required Action Update](/gateway/gateway-events#user-required-action-update) Gateway event.
###### JSON Params
| Field | Type | Description |
| ------------------- | ------ | ---------------------------------------------------------------------------------- |
| password | string | The user's current password; if the account does not have a password, this sets it |
| change_phone_reason | string | The [removal reason](#change-phone-reason) |
---
# Threads
Link: https://docs.discord.food/topics/threads
[Threads](/resources/channel#channel-object) are a new Discord feature. Threads can be thought of as temporary sub-channels inside an existing channel, to help better organize conversation in a busy channel.
Threads have been designed to be very similar to [channel](/resources/channel#channel-object) objects, and this topic aggregates all of the information about threads, which should all help to make migrating very straightforward.
## Backwards Compatibility
Threads are only available in API v9. Users that do not update to API v9 will not receive most Gateway events for threads, or things that happen in threads (such as [Message Create](/gateway/gateway-events#message-create)). Users on API v8 will still receive Gateway events for Interactions though.
The list of Gateway events that may be dropped includes, but is not limited to:
- MESSAGE_CREATE
- MESSAGE_DELETE
- MESSAGE_DELETE_BULK
- MESSAGE_REACTION_ADD
- MESSAGE_REACTION_REMOVE
- MESSAGE_REACTION_REMOVE_ALL
- MESSAGE_REACTION_REMOVE_EMOJI
- MESSAGE_UPDATE
- THREAD_CREATE
- THREAD_UPDATE
- THREAD_DELETE
- THREAD_MEMBER_UPDATE
- THREAD_MEMBERS_UPDATE
## Thread Fields
Since threads are a new [type of channel](/resources/channel#channel-type), they share and re-purpose a number of the existing fields on a [channel](/resources/channel#channel-object) object:
- `id`, `guild_id`, `type`, `name`, `last_message_id`, `last_pin_timestamp`, `rate_limit_per_user`, and `flags` are being re-used
- `owner_id` has been repurposed to store the ID of the user that started the thread
- `parent_id` has been repurposed to store the ID of the `GUILD_TEXT` or `GUILD_NEWS` channel the thread was created in
Additionally, there are a few new fields that are only available on threads:
- `member_count` stores an approximate member count, but it stops counting at 50
- `message_count` and `total_message_sent` store the number of messages in a thread. The difference is that when a message is deleted, `message_count` is decremented, but `total_message_sent` will not be (threads created before July 1, 2022 stop counting both values at 50).
- `thread_metadata` contains a few thread specific fields, `archived`, `archive_timestamp`, `auto_archive_duration`, `locked`. `archive_timestamp` is changed when creating, archiving, or unarchiving a thread, and when changing the `auto_archive_duration` field.
## Public & Private Threads
Public threads are viewable by everyone who can view the parent channel of the thread. Public threads must be created from an existing message, but can be "orphaned" if that message is deleted. The created thread and the message it was started from will share the same id. The [type](/resources/channel#channel-type) of thread created matches the [type](/resources/channel#channel-type) of the parent channel. `GUILD_TEXT` channels [create](/resources/channel#create-thread-from-message) `PUBLIC_THREAD` and `GUILD_NEWS` channels [create](/resources/channel#create-thread-from-message) `NEWS_THREAD`.
Private threads behave similar to group DMs, but in a guild. Private threads are always [created](/resources/channel#create-thread) with the `PRIVATE_THREAD` [type](/resources/channel#channel-type) and can only be created in `GUILD_TEXT` channels.
## Active & Archived Threads
Every thread can be either active or archived. Changing a thread from archived -> active is referred to as unarchiving the thread. Threads that have `locked` set to true can only be unarchived by a user with the `MANAGE_THREADS` permission.
Besides helping to de-clutter the UI for users, archiving exists to limit the working set of threads that need to be kept around. Since the number of archived threads can be quite large, keeping all of them in memory may be quite prohibitive. Therefore guilds are capped at a certain number of active threads, and only active threads can be manipulated. Users cannot edit messages, add reactions, use application commands, or join archived threads. The only operation that should happen within an archived thread is messages being deleted. Sending a message will automatically unarchive the thread, unless the thread has been locked by a moderator.
Because of this constraint, the Gateway protocol is designed to ensure that users are able to have an accurate view of the full set of active threads, but archived threads are not synced up-front via the gateway.
Threads do not count against the max-channels limit in a guild, but there will be a new limit on the maximum number of active threads in a guild.
Threads automatically archive after a period of inactivity (as a guild approaches the max thread limit this timer will automatically lower, but never below the `auto_archive_duration`). "Activity" is defined as sending a message, unarchiving a thread, or changing the auto-archive time. The `auto_archive_duration` field previously controlled how long a thread could stay active, but is now repurposed to control how long the thread stays in the channel list. Channels can also set `default_auto_archive_duration`, which is used by official clients to pre-select a different `auto_archive_duration` value when a user creates a thread.
## Permissions
Threads generally inherit permissions from the parent channel (e.g. if you can add reactions in the parent channel, you can do that in a thread as well).
Three permission bits are specific to threads: `CREATE_PUBLIC_THREADS`, `CREATE_PRIVATE_THREADS`, and `SEND_MESSAGES_IN_THREADS`.
The `SEND_MESSAGES` permission has no effect in threads; users must have `SEND_MESSAGES_IN_THREADS` to talk in a thread.
Private threads are similar to group DMs, but in a guild: You must be invited to the thread to be able to view or participate in it, or be a moderator (`MANAGE_THREADS` permission).
Finally, threads are treated slightly differently from channels in the Gateway protocol. Clients will not be informed of a thread through the Gateway if they do not have permission to view that thread.
## Gateway Events
- [Guild Create](/gateway/gateway-events#guild-create) contains a new field, `threads`, which is an array of channel objects. For bots, this represents all active threads in the guild that the current user is able to view. For user accounts, only joined threads are sent.
- When a thread is created, updated, or deleted, a [Thread Create](/gateway/gateway-events#thread-create), [Thread Update](/gateway/gateway-events#thread-update), or [Thread Delete](/gateway/gateway-events#thread-delete) event is sent. Like their channel counterparts, these just contain a thread.
- Since the Gateway only syncs active threads that the user can see, if a user _gains_ access to a channel, then the Gateway may need to sync the active threads in that channel to the user. It will send a [Thread List Sync](/gateway/gateway-events#thread-list-sync) event for this.
## Thread Membership
Each thread tracks explicit membership. There are two primary use cases for this data:
- Clients use _their own_ [thread member](/resources/channel#thread-member-object) to calculate read states and notification settings.
- Knowing everyone that is in a thread.
Membership is tracked in an array of [thread member](/resources/channel#thread-member-object) objects. These have four fields, `id` (the thread id), `user_id`, `join_timestamp`, and `flags`. Currently the only `flags` are for notification settings, but others may be added in future updates.
### Syncing for the current user
- A [Thread Members Update](/gateway/gateway-events#thread-members-update) Gateway Event is always sent when the current user is added to or removed from a thread.
- A [Thread Member Update](/gateway/gateway-events#thread-member-update) Gateway Event is sent whenever the current user's [thread member](/resources/channel#thread-member-object) object is updated.
- Certain API calls, such as listing archived threads and search will return an array of [thread member](/resources/channel#thread-member-object) objects for any returned threads the current user is a member of. Other API calls, such as getting a channel will return the [thread member](/resources/channel#thread-member-object) object for the current user as a property on the channel, if the current user is a member of the thread.
- The [Guild Create](/gateway/gateway-events#guild-create) Gateway Event will contain a [thread member](/resources/channel#thread-member-object) object as a property on any returned threads the current is a member of.
- The [Thread Create](/gateway/gateway-events#thread-create) Gateway Event will contain a [thread member](/resources/channel#thread-member-object) object as a property of the thread if the current user is a member of, and the user has recently gained access to view the parent channel.
- The [Thread List Sync](/gateway/gateway-events#thread-list-sync) Gateway Event will contain an array of [thread member](/resources/channel#thread-member-object) objects for any returned threads the current user is a member of.
### Syncing for other users
These require the `GUILD_MEMBERS` [Gateway intent](/gateway/using-gateway#gateway-intents)
- An API `GET` call to [`/channels//thread-members`](/resources/channel#list-thread-members) which returns an array of [thread member](/resources/channel#thread-member-object) objects.
- The [Thread Members Update](/gateway/gateway-events#thread-members-update) Gateway Event which will include all users who were added to or removed from a thread by an action.
## Editing & Deleting Threads
Threads can be edited and deleted with the existing `PATCH` and `DELETE` endpoints to edit a channel.
- Deleting a thread requires the `MANAGE_THREADS` permission.
- Editing a thread to set `archived` to `false` only requires the current user has already been added to the thread. If `locked` is true, then the user must have `MANAGE_THREADS`
- Editing a thread to change the `name`, `archived`, `auto_archive_duration` fields requires `MANAGE_THREADS` or that the current user is the thread creator.
- Editing a thread to change `rate_limit_per_user` or `locked` requires `MANAGE_THREADS`. `locked` can also be set to `true` by the thread creator.
## NSFW Threads
Threads do not explicitly set the `nsfw` field. All threads in a channel marked as `nsfw` inherit that setting though.
## New Message Types
Threads introduce a few new [message types](/resources/message#message-type), and re-purpose some others:
- `RECIPIENT_ADD` and `RECIPIENT_REMOVE` have been repurposed to also send when a user is added to or removed from a thread by someone else.
- `CHANNEL_NAME_CHANGE` has been repurposed and is sent when the thread's name is changed.
- `THREAD_CREATED` is a new message sent to the parent `GUILD_TEXT` channel, used to inform users that a thread has been created. It is currently only sent in one case: when a `PUBLIC_THREAD` is created from an older message (older is still TBD, but is currently set to a very small value). The message contains a [message reference](/resources/message#message-reference-structure) with the `guild_id` and `channel_id` of the thread. The `content` of the message is the `name` of the thread.
- `THREAD_STARTER_MESSAGE` is a new message sent as the first message in threads that are started from an existing message in the parent channel. It _only_ contains a [message reference](/resources/message#message-reference-structure) field that points to the message from which the thread was started.
## Enumerating Threads
There are many `GET` routes for enumerating threads in a specific channel:
- [`/guilds//threads/active`](/resources/channel#list-guild-active-threads) returns all active threads in a guild that the current user can access, includes public & private threads
- [`/channels//threads/active`](/resources/channel#list-active-threads) returns all active threads in a channel that the current user can access, includes public & private threads
- [`/channels//threads/search`](/resources/channel#search-threads) returns all active and archived threads in a channel that the current user can access, includes public & private threads and can be filtered by query
- [`/channels//users/@me/threads/archived/private`](/resources/channel#list-joined-private-archived-threads) returns all archived, private threads in a channel, that the current user has is a member of, sorted by thread ID descending
- [`/channels//threads/archived/public`](/resources/channel#list-public-archived-threads) returns all archived, public threads in a channel, sorted by archive timestamp descending
- [`/channels//threads/archived/private`](/resources/channel#list-private-archived-threads) returns all archived, private threads in a channel, sorted by archive timestamp descending
## Webhooks
Webhooks can send messages to threads by using the `thread_id` query parameter. See the [Execute Webhook](/resources/webhook#execute-webhook) docs for more details.
While threads are mostly similar to channels in terms of structure and how they are synced, there are two important product requirements that lead to differences in how threads and channels are synced. This section helps explain the behavior behind the [Thread List Sync](/gateway/gateway-events#thread-list-sync) and [Thread Create](/gateway/gateway-events#thread-create) dispatches by going over those problems and how they are solved.
The two product requirements are: The Gateway will only sync threads to a client that the client has permission to view, and it will only sync those threads once the client has "subscribed" to the guild. For context, in Discord's official clients, a subscription happens when the user visits a channel in the guild.
As mentioned, these lead to a couple of edge cases that are worth going into:
## Details About Thread Access and Syncing
While the syncing of threads is similar to channels, there are two important differences that are relevant for [Thread List Sync](/gateway/gateway-events#thread-list-sync) and [Thread Create](/gateway/gateway-events#thread-create) events:
1. The Gateway will only sync threads that the user has permission to view.
2. The Gateway will only sync threads once the user has "subscribed" to the guild. For context, in Discord's official clients, a subscription happens when the user visits a channel in the guild.
These differences mean there is some unique behavior that is worth going into.
### Thread Access
#### Gaining Access to Private Threads
When a user is added to a private thread, it likely doesn't have that thread in memory yet since it doesn't have permission to view it.
Private threads are only synced to you if you are a member or a moderator. Whenever a user is added to a private thread, the Gateway also sends a [Thread Create](/gateway/gateway-events#thread-create) event. This ensures the client always has a non-null value for that thread.
The [Thread Create](/gateway/gateway-events#thread-create) event is also sent when the user is a moderator (and thus would already have the channel in memory).
#### Gaining Access to Public Threads
When a client is added to a public thread, but has not yet subscribed to threads, they might not have that public thread in memory yet. This is actually only a problem for user accounts, and not for bots. The Gateway will auto-subscribe bots to all thread dispatches and active threads on connect. But user accounts only receive threads that are active and they have also joined on connect in order to reduce the amount of data needed on initial connect. But this means when a user account is added to a thread, that thread now becomes an "active-joined" thread and needs to be synced to the client. To solve this, whenever a user is added to _any_ thread, the Gateway also sends a [Thread Create](/gateway/gateway-events#thread-create) dispatch.
### Channel Access
#### Gaining Access to Channels
When a user gains access to a channel (for example, they're given the moderator role), they likely won't have the threads in memory for that channel since the Gateway only syncs threads that the client has permission to view. To account for this, a [Thread List Sync](/gateway/gateway-events#thread-list-sync) event is sent.
#### Losing Access to Channels
When a user loses access to a channel, the Gateway does **not** send it [Thread Delete](/gateway/gateway-events#thread-delete) event (or any equivalent thread-specific event). Instead, the user will receive the event that caused its permissions on the channel to change.
If a user wanted to track when it lost access to any thread, it's possible but difficult as it would need to handle all cases correctly. Usually, events that cause permission changes are a [Guild Role Update](/gateway/gateway-events#guild-role-update), [Guild Member Update](/gateway/gateway-events#guild-member-update) or [Channel Update](/gateway/gateway-events#channel-update) event.
Discord's official clients check their permissions _first_ when performing an action. That way, even if it has some stale data, it does not end up acting on it.
Additionally, when a user loses access to a channel, they are not removed from the thread and will continue to be reported as a member of that thread. However, they will **not** receive any new Gateway events unless they are removed from the thread, in which case they will receive a [Thread Members Update](/gateway/gateway-events#thread-members-update) event.
### Unarchiving a Thread
When a thread is unarchived, as user accounts only load active threads into memory on start, there is no guarantee that a user has the thread or its member status in memory. To account for this, the Gateway will send two events (in the listed order):
1. A [Thread Update](/gateway/gateway-events#thread-update) event, which contains the full channel object.
2. A [Thread Member Update](/gateway/gateway-events#thread-member-update) event, which is sent to all members of the unarchived thread, so users know they are a member and what their notification setting is.
# Forums
A `GUILD_FORUM` channel is similar to a `GUILD_TEXT` channel, except _only_ threads can be created in them. Unless otherwise noted, threads in forum channels behave in the same way as in text channels—meaning they use the same endpoints and receive the same Gateway events.
More information about forum channels and how they appear in Discord can be found in the [Forum Channels FAQ](https://support.discord.com/hc/en-us/articles/6208479917079-Forum-Channels-FAQ#h_01G69FJQWTWN88HFEHK7Z6X79N).
## Media Channels
A `GUILD_MEDIA` channel is similar to a `GUILD_FORUM` channel. Similar to forum channel, only threads can be created in them. Unless otherwise noted, threads in media channels behave in the same way as in forum channel—meaning they use the same endpoints and receive the same Gateway events.
More information about media channels and how they appear in Discord can be found in the [Media Channels FAQ](https://creator-support.discord.com/hc/en-us/articles/14346342766743).
### Creating Threads in Thread-Only Channels
Within a thread-only channel, threads appear as posts. They can be created using the [Create Thread](/resources/channel#create-thread) endpoint as threads in text channels, but with [slightly different parameters](/resources/channel#thread-only-channel-message-structure). For example, when creating threads in a threads-only channel, a message is created that has the same ID as the thread. This requires you to pass parameters for both a thread _and_ a message.
Threads in a thread-only channel have the same permissions behavior as threads in a text channel, inheriting all permissions from the parent channel, with one exception: creating a thread in a thread-only channel only requires the `SEND_MESSAGES` permission.
### Thread-Only Channel Fields
It's worth calling out a few details about fields specific to thread-only channels that may be important to keep in mind:
- The `last_message_id` field is the ID of the most recently created thread in that channel. As with messages, you will not receive a [Channel Update](/gateway/gateway-events#channel-update) event when the field is changed. Instead, clients should update the value when receiving [Thread Create](/gateway/gateway-events#thread-create) events.
- The `topic` field is what is shown in the "Guidelines" section within clients.
- The `rate_limit_per_user` field limits how frequently threads can be created. There is a new `default_thread_rate_limit_per_user` field on thread-only channels as well, which limits how often messages can be sent _in a thread_. This field is copied into `rate_limit_per_user` on the thread at creation time.
- The `available_tags` field can be set when creating or updating a channel, which determines which tags can be set on individual threads within the thread's `applied_tags` field.
All fields for channels, including thread-only channels, can be found in the [Channel Object](/resources/channel#channel-object).
### Thread-Only Channel Thread Fields
A thread can be pinned within a thread-only channel, which is represented by the [`PINNED` flag](/resources/channel#channel-flags). A thread that is pinned will have the flag set, and archiving that thread will unset the flag. A pinned thread will _not_ auto-archive.
The `message_count` and `total_message_sent` fields on threads in thread-only channels will increment on [Message Create](/gateway/gateway-events#message-create) events, and decrement on [Message Delete](/gateway/gateway-events#message-delete) and [Message Delete Bulk](/gateway/gateway-events#message-delete-bulk) events. There will be no specific [Channel Update](/gateway/gateway-events#channel-update) event that notifies you of changes to those fields—instead, you should update those values when receiving corresponding events.
All fields for threads in thread-only channels can be found in the [channel resource documentation](/resources/channel#create-thread).
---
# Read State
Link: https://docs.discord.food/topics/read-state
Initially, read states in Discord were built to keep track of unread messages and pings in channels. Over time, the system evolved and now powers the unread and badging system across many other surfaces, as indicated by [read state type](#read-state-type).
## How Unreads Work
Read states are a simple data store that contain the last acknowledged entity ID (message, guild scheduled event, etc.). As snowflakes are monotonically increasing, any entity with an ID greater than the last acknowledged ID is considered unread.
A resource is considered unread if there exists at least one entity with an ID greater than the last acknowledged ID. For example, a channel is considered unread if there exists at least one message with an ID greater than the last acknowledged message ID.
How this is determined depends on the read state type:
- For read states of type `CHANNEL`, the [channel `last_message_id` field](/resources/channel#channel-object) is compared against the read state's `last_message_id`. The [channel `last_pin_timestamp` field](/resources/channel#channel-object) is also compared against the read state's `last_pin_timestamp` to determine if there are any unacknowledged pinned messages.
- For read states of type `GUILD_EVENT`, the ID of the newest scheduled event in the guild is compared against the read state's `last_acked_id`.
- For read states of type `GUILD_HOME`, no specific entity is tracked; guild home is considered unread if the timestamp of the read state's `last_acked_id` is more than 24 hours old.
- For read states of type `GUILD_ONBOARDING_QUESTION`, the [guild `latest_onboarding_question_id` field](/resources/guild#guild-object) is compared against the read state's `last_acked_id`.
- For read states of type `NOTIFICATION_CENTER`, the ID of the newest [notification center item](/resources/notification-center#notification-center-item-object) is compared against the read state's `last_acked_id`. Mobile clients also use the same read state to track whether notification tab message mentions have been viewed, comparing the mentioned message IDs against `last_acked_id`.
- For read states of type `MESSAGE_REQUESTS`, the ID of the newest message request is compared against the read state's `last_acked_id`.
These same principles can be applied to determine what entity ID to use when acknowledging a read state.
For notification center, the `NOTIFICATION_CENTER` read state and the `acked` state on individual notification center items are separate.
The read state controls the notification center's overall unread badge by storing an acknowledged item threshold,
while [notification center item acknowledgements](/resources/notification-center#acknowledge-notification-center-item) control whether individual items are marked as acknowledged.
## Automations
As with all stateful resources in Discord, clients are expected to manage read states locally and update them as necessary from Gateway events such as
[Message Ack](/gateway/gateway-events#message-ack), [Channel Pins Ack](/gateway/gateway-events#channel-pins-ack), [Guild Feature Ack](/gateway/gateway-events#guild-feature-ack), and [User Non Channel Ack](/gateway/gateway-events#user-non-channel-ack).
However, certain read state updates are done automatically by Discord without firing ack events. As a result, clients must make sure to keep their local read state store in sync by implementing the same logic.
#### Channel Read State Automations
- When a [Message Create](/gateway/gateway-events#message-create) Gateway event is received, if the author is not [blocked or ignored](/resources/relationships):
- If the message is in a private channel, the message type is not [`RECIPIENT_REMOVE`](/resources/message#message-type), and the private channel is not [muted](/resources/user-settings#user-guild-settings-object) or the message mentions the current user, the corresponding read state must be updated to increment `mention_count` by one. ^1^
- If the message is in a guild channel and the message mentions the current user, the corresponding read state must be updated to increment `mention_count` by one. ^1^
- If the message is not in a voice or stage channel, the channel is not [muted](/resources/user-settings#user-guild-settings-object), the channel's [notification level](/resources/user-settings#user-guild-settings-object) is set to `ALL_MESSAGES`, and the user has the [`MENTION_ON_ALL_MESSAGES` setting](/resources/user-settings#notification-settings-flags) enabled, the corresponding read state must be updated to increment `mention_count` by one. ^2^
- When a [Message Create](/gateway/gateway-events#message-create) Gateway event is received, if the message type is not [`POLL_RESULT`](/resources/message#message-type) and is authored by the current user, the corresponding read state must be updated to set `last_message_id` to the new message's ID, thereby resetting `mention_count` to zero.
- When a [Thread Create](/gateway/gateway-events#thread-create) Gateway event is received, if the thread's parent is a thread-only channel and the thread is created by the current user, the corresponding parent read state must be updated to set `last_message_id` to the new thread's ID, thereby resetting `mention_count` to zero.
^1^ When considering if a message mentions the current user, clients must take into account user mentions, role mentions, and everyone mentions. When considering role and everyone mentions, clients must check the channel's [notification settings](/resources/user-settings#user-guild-settings-object) to ensure those mentions are not suppressed.
^2^ These mentions are considered low importance as they do not ping the user. See the [Calculating Flags](#calculating-flags) section for more information.
#### Guild Read State Automations
- When a [Guild Scheduled Event Create](/gateway/gateway-events#guild-scheduled-event-create) Gateway event is received, if the guild's [notification settings](/resources/user-settings#user-guild-settings-object) does not have `mute_scheduled_events` set, the corresponding read state must be updated to increment `badge_count` by one.
- When a [Guild Scheduled Event Create](/gateway/gateway-events#guild-scheduled-event-create) Gateway event is received, if the event's `creator_id` matches the current user's ID, the corresponding read state must be updated to set `last_acked_id` to the new event's ID, thereby resetting `badge_count` to zero.
#### User Read State Automations
- When a [Notification Center Item Create](/gateway/gateway-events#notification-center-item-create) Gateway event is received, the `NOTIFICATION_CENTER` read state must be updated to increment `badge_count` by one.
- When a [Relationship Add](/gateway/gateway-events#relationship-add) Gateway event is received with q`type` `INCOMING_REQUEST`, the `NOTIFICATION_CENTER` read state must be updated to increment `badge_count` by one.
- When a [Relationship Add](/gateway/gateway-events#relationship-add) Gateway event is received with `type` `FRIEND`, or a [Relationship Remove](/gateway/gateway-events#relationship-remove) Gateway event is received with `type` `INCOMING_REQUEST`, the `NOTIFICATION_CENTER` read state must be updated to decrement `badge_count` by one, without going below zero.
- On mobile, message mentions can also contribute to the `NOTIFICATION_CENTER` badge. When they do, clients must use the message's ID as the latest entity for the notification center read state.
## Management
Read states are almost entirely managed by clients, with the server not doing much other than storing them.
#### Calculating Flags
Flags are only applicable to read states of type `CHANNEL`. Clients must calculate the flags based on the channel's properties before acknowledging a message.
If the calculated flags differ from the stored flags, clients must specify the `flags` field in the request.
Flags must be calculated as follows:
- If the channel has a `guild_id`, set the `IS_GUILD_CHANNEL` flag.
- If the channel's `type` is one of the thread types (`NEWS_THREAD`, `PUBLIC_THREAD`, `PRIVATE_THREAD`), set the `IS_THREAD` flag.
- If the read state's `mention_count` is comprised entirely of non-ping mentions, set the `IS_MENTION_LOW_IMPORTANCE` flag. ^1^
^1^ When the user has the [`MENTION_ON_ALL_MESSAGES` setting](/resources/user-settings#notification-settings-flags) enabled and the channel's [notification level](/resources/user-settings#user-guild-settings-object) is set to `ALL_MESSAGES`, all messages in the channel increase the `mention_count`. These mentions are considered low importance as they do not ping the user. However, if there is at least one ping mention in the channel, the read state is not considered low importance.
#### Calculating Last Viewed
For read states of type `CHANNEL`, clients must calculate the `last_viewed` value before acknowledging a message.
The value is the number of days since the Discord epoch (January 1, 2015 00:00:00 UTC) at the time the channel was viewed.
If the calculated value differs from the stored value, clients must specify the `last_viewed` field in the request.
#### Deleting Read States
Clients should delete read states that are no longer relevant to the user. Official clients do this at application start, deleting read states that meet the following criteria:
- Read states of type `CHANNEL` for channels that no longer exist (with a 30 day grace period to account for archived threads).
- Read states of type `CHANNEL` for channels the user no longer has `VIEW_CHANNEL` and `READ_MESSAGE_HISTORY` permissions in.
- Read states of type `GUILD_EVENT`, `GUILD_HOME`, or `GUILD_ONBOARDING_QUESTION` for guilds that the user is no longer a member of.
Make sure to ignore unrecognized read state and channel types to allow for forward compatibility.
## Ack Tokens
The new, Rust-based read state service no longer uses ack tokens, returning them as `null` in all responses. For backwards compatibility, clients may continue to send ack tokens, but they will be ignored.
Ack tokens are used to identify a specific client when interacting with read states.
The client should initially set its ack token to `null` when making the first ack request. The server will respond with a new token in the `token` field of the response, which the client should store locally.
When acknowledging a read state, the client should then send this token back to the server in the `token` field. The server will respond with an updated token, which the client should again store locally for future requests.
The client should reset the ack token to `null` whenever it switches accounts or a [User Update](/gateway/gateway-events#user-update) Gateway event is received.
### Read State Object
###### Read State Structure
| Field | Type | Description |
| ----------------------- | ----------------- | ------------------------------------------------------------------- |
| id ^1^ | snowflake | The ID of the resource the read state is for |
| read_state_type? | integer | The [type of read state](#read-state-type) (default `CHANNEL`) |
| last_message_id? ^2^ | snowflake | The ID of the last acknowledged message |
| last_acked_id? ^2^ | snowflake | The ID of the last acknowledged entity |
| mention_count? ^3^ | integer | The number of unread mentions |
| badge_count? ^3^ | integer | The number of unread badges |
| last_pin_timestamp? ^4^ | ISO8601 timestamp | When the last acknowledged pinned message was pinned |
| flags? ^4^ | integer | The [read state flags](#read-state-flags) |
| last_viewed? ^4^ | ?integer | When the resource was last viewed (in days since the Discord epoch) |
^1^ For user features, the resource ID is the current user's ID.
^2^ `last_message_id` and `last_acked_id` are mutually exclusive; only one will be present depending on the `read_state_type`, for backwards compatibility reasons.
^3^ `mention_count` and `badge_count` are mutually exclusive; only one will be present depending on the `read_state_type`, for backwards compatibility reasons.
^4^ Only applicable for read states of type `CHANNEL`.
###### Read State Type
| Value | Name | Description |
| ----- | ------------------------- | -------------------------------- |
| 0 | CHANNEL | Channel message unreads |
| 1 | GUILD_EVENT | Guild scheduled event feature |
| 2 | NOTIFICATION_CENTER | User notification center feature |
| 3 | GUILD_HOME | Guild home feature |
| 4 | GUILD_ONBOARDING_QUESTION | Guild onboarding feature |
| 5 | MESSAGE_REQUESTS | User message requests feature |
###### Read State Flags
| Value | Name | Description |
| -------- | ------------------------- | ---------------------------------------------- |
| 1 \<\< 0 | IS_GUILD_CHANNEL | Whether the channel is part of a guild |
| 1 \<\< 1 | IS_THREAD | Whether the channel is a thread |
| 1 \<\< 2 | IS_MENTION_LOW_IMPORTANCE | Whether channel mentions are of low importance |
## Endpoints
Acknowledge Message
Updates the channel's read state for the current user. Fires a [Message Ack](/gateway/gateway-events#message-ack) Gateway event.
The message ID parameter does not need to be a valid message ID, but it must be a valid snowflake. If the message ID is being set to a message sent prior to the latest acknowledged one, `manual` should be `true` or the resulting read state update might be ignored by clients, resulting in undefined behavior.
In this case, `mention_count` should also be updated to the amount of mentions unacknowledged as it is not automatically calculated by Discord.
###### JSON Params
| Field | Type | Description |
| ------------------ | ------- | ------------------------------------------------------------------ |
| token? | ?string | The last received [ack token](#ack-tokens), or `null` |
| manual? | boolean | Whether the acknowledged message ID is manually set |
| mention_count? ^1^ | integer | The new unread indicator for the channel |
| flags? ^2^ | integer | The [read state flags](#read-state-flags) for the channel |
| last_viewed? ^2^ | integer | When the channel was last viewed (in days since the Discord epoch) |
^1^ Requires `manual` to be `true`.
^2^ If omitted, the current value is retained.
###### Response Body
| Field | Type | Description |
| ----- | ------- | -------------------------------- |
| token | ?string | The new [ack token](#ack-tokens) |
Acknowledge Pinned Messages
Acknowledges the currently pinned messages in a channel. Returns a 204 empty response on success. Fires a [Channel Pins Ack](/gateway/gateway-events#channel-pins-ack) Gateway event.
Acknowledge Guild
Updates all read states in a guild to acknowledge all features and messages. Fires multiple [Message Ack](/gateway/gateway-events#message-ack) and [Guild Feature Ack](/gateway/gateway-events#guild-feature-ack) Gateway events.
This endpoint is deprecated. It is replaced by [Bulk Update Read States](#bulk-update-read-states).
Acknowledge Guild Feature
Updates a guild feature's read state for the current user. Fires a [Guild Feature Ack](/gateway/gateway-events#guild-feature-ack) Gateway event.
###### JSON Params
| Field | Type | Description |
| ------ | ------- | ----------------------------------------------------- |
| token? | ?string | The last received [ack token](#ack-tokens), or `null` |
###### Response Body
| Field | Type | Description |
| ----- | ------- | -------------------------------- |
| token | ?string | The new [ack token](#ack-tokens) |
Acknowledge User Feature
Updates a non-channel feature's read state for the current user. Fires a [User Non Channel Ack](/gateway/gateway-events#user-non-channel-ack) Gateway event.
###### JSON Params
| Field | Type | Description |
| ------ | ------- | ----------------------------------------------------- |
| token? | ?string | The last received [ack token](#ack-tokens), or `null` |
###### Response Body
| Field | Type | Description |
| ----- | ------- | -------------------------------- |
| token | ?string | The new [ack token](#ack-tokens) |
Bulk Update Read States
Updates multiple read states for the current user. Returns a 204 empty response on success. Fires multiple [Message Ack](/gateway/gateway-events#message-ack), [Guild Feature Ack](/gateway/gateway-events#guild-feature-ack), and [User Non Channel Ack](/gateway/gateway-events#user-non-channel-ack) Gateway events.
###### JSON Params
| Field | Type | Description |
| ----------- | --------------------------------------------------------------- | -------------------------------- |
| read_states | array[[read state update](#read-state-update-structure) object] | The read state updates to update |
###### Read State Update Structure
| Field | Type | Description |
| ------------------ | --------- | ------------------------------------------------------------------------------------ |
| read_state_type? | integer | The [type of read state](#read-state-type) (default `CHANNEL`) |
| channel_id | snowflake | The ID of the resource the read state is for |
| message_id ^1^ ^2^ | snowflake | The ID of the entity to set the read state to (message, guild scheduled event, etc.) |
^1^ Unlike standalone ack endpoints, the message ID must be greater than `0` or the read state update will be ignored.
^2^ As bulk updates do not accept a `manual` field, it is not recommended to set channel read states to a message ID lower than the current acknowledged one using this endpoint, as it will lead to undefined behavior.
Delete Read State
Deletes a read state for the current user. Returns a 204 empty response on success.
While this endpoint is under the channel resource, it can be used to delete read states of any type by specifying the appropriate resource ID.
###### JSON Params
| Field | Type | Description |
| ---------------- | ------- | ------------------------------------------------------------------------------------------------------------------------------------------- |
| read_state_type? | integer | The [read state type](#read-state-type) to delete (default `CHANNEL`) |
| version? | integer | The version of the read state protocol the client has implemented, used to prevent accidental deletions from outdated clients (currently 2) |
---
# Client Distribution
Link: https://docs.discord.food/topics/client-distribution
While mobile clients can be distributed through most system app stores, desktop clients require a custom solution for downloading and updating. Discord provides various APIs for downloading clients, their native modules, and keeping everything up-to-date. Visit the [downloads page](https://discord.com/download) to learn more about the clients currently offered.
###### Distribution Base URLs
These URLs, provided for convenience, provide access to all client downloads (and redirect access to [CDN-hosted ones](/reference#cdn-formatting)), but are NOT used for the API requests below. For those, see the [API Base URL](/reference#base-url).
Note that downloads links obtained from the API may not always use these URLs.
```
https://dl.discordapp.net/
https://dl-ptb.discordapp.net/
https://dl-canary.discordapp.net/
https://dl-development.discordapp.net/
```
## Clients
### Web
Discord offers a web client that can be used in a browser. This same web client is also used in the desktop client in tandem with native modules to provide a richer experience.
###### Web Release Channel
| Value | URL | Description |
| ---------- | ------------------------------ | ----------------- |
| stable | https://discord.com/app | Stable build |
| ptb ^1^ | https://ptb.discord.com/app | Public test build |
| canary ^1^ | https://canary.discord.com/app | Alpha test build |
^1^ See the [Help Center article](https://support.discord.com/hc/en-us/articles/360035675191-Discord-Testing-Clients) for more information on Discord testing clients.
### Desktop
Discord offers Electron desktop clients for Windows, macOS, and Linux.
###### Windows
The Windows application uses a separate install and update stack from the other desktop platforms. See [Get Latest Distributed Application Installer](#get-latest-distributed-application-installer) for more information on getting the latest application installer, and [Get Latest Distributed Application Manifest](#get-latest-distributed-application-manifest) for more information on getting the latest application updates.
###### macOS
See [Get Latest Application Installer](#get-latest-application-installer) for more information on getting the latest application installer, and [Get Application Updates](#get-application-updates) for more information on getting the latest application updates.
###### Linux
See [Get Latest Application Installer](#get-latest-application-installer) for more information on getting the latest application installer, and [Get Application Updates](#get-application-updates) for more information on getting the latest application updates. Note that the Linux application is not auto-updated.
###### Desktop Release Channel
Desktop release channels follow [web release channels](#web-release-channel) when rendering the client. However, the application host and native modules are updated separately from the client itself.
| Value | Description |
| --------------- | ----------------- |
| stable | Stable build |
| ptb ^1^ | Public test build |
| canary ^1^ | Alpha test build |
| development ^2^ | Development build |
^1^ See the [Help Center article](https://support.discord.com/hc/en-us/articles/360035675191-Discord-Testing-Clients) for more information on Discord testing clients.
^2^ The development build follows the [`canary` web release channel](#web-release-channel) and is not recommended for use. It may be unstable or broken at any time.
###### Desktop Platform Type
| Value | Description |
| ----- | ----------- |
| win | Windows |
| osx | macOS |
| linux | Linux |
###### Desktop Architecture Type
| Value | Description |
| ----- | ---------------- |
| x86 | 32-bit x86 build |
| x64 | 64-bit x86 build |
| arm64 | 64-bit ARM build |
###### Desktop Executable Format
| Value | Description |
| ----------- | --------------------------------- |
| deb | Debian software package file |
| tar.gz | Compressed archive file |
| rpm | RPM software package file |
| pkg.tar.zst | Zstandard-compressed package file |
### Mobile
Discord maintains stable and beta mobile clients for both Android and iOS.
###### Android Release Channel
Official Android clients employ a minimum version check at startup. If the installed version is below the minimum version, the client will refuse to start and prompt the user to update.
This minimum version data is available at `https://dl.discordapp.net/apps/android/versions.json`. The response contains a `discord_android_min_version` field, which is a string containing the minimum version.
| Value | URL | Description |
| --------- | --------------------------------------------------------- | ------------------------ |
| stable | https://play.google.com/store/apps/details?id=com.discord | Stable application build |
| beta ^1^ | https://play.google.com/apps/testing/com.discord | Beta application build |
| alpha ^1^ | https://groups.google.com/g/discord-android-alpha-testers | Alpha application build |
^1^ See the [Help Center article](https://support.discord.com/hc/en-us/articles/360035675191-Discord-Testing-Clients) for more information on Discord testing clients.
###### iOS Release Channel
| Value | URL | Description |
| --------- | -------------------------------------------------------------------- | --------------------------- |
| stable | https://apps.apple.com/us/app/discord-talk-chat-hang-out/id985746746 | Stable application build |
| beta ^1^ | https://testflight.apple.com/join/gdE4pRzI | Beta application build |
| alpha ^1^ | \ | Internal application builds |
^1^ See the [Help Center article](https://support.discord.com/hc/en-us/articles/360035675191-Discord-Testing-Clients) for more information on Discord testing clients.
## Endpoints
Get Latest Application Installer
Redirects to the latest application installer for the provided [release channel](#desktop-release-channel) and selected platform.
This endpoint is in the process of being decommissioned in favor of [Get Latest Distributed Application Installer](#get-latest-distributed-application-installer).
A special release channel of `mobile` may be used to redirect to the download page of the mobile clients.
###### Query String Params
| Name | Type | Description |
| ----------- | ------ | -------------------------------------------------------------------------------------------- |
| platform | string | The [platform](#desktop-platform-type) to get the installer for |
| format? ^1^ | string | The [executable format](#desktop-executable-format) to get the installer for (default `deb`) |
^1^ Only applicable to the [Linux platform](#desktop-platform-type).
Get Application Updates
Returns information about the latest application host update for the provided [release channel](#desktop-release-channel) and selected platform.
This endpoint is in the process of being decommissioned in favor of [Get Latest Distributed Application Manifest](#get-latest-distributed-application-manifest).
###### Query String Params
| Name | Type | Description |
| --------- | ------ | ------------------------------------------------------------------------------------ |
| platform? | string | The [platform](#desktop-platform-type) to get update information for (default `osx`) |
###### Response Body
| Name | Type | Description |
| ---------- | ----------------- | -------------------------------------- |
| name | string | The latest host version |
| pub_date | ISO8601 timestamp | When the update was published |
| url? ^1^ | string | The URL to the corresponding installer |
| notes? ^1^ | string | Any extra notes for the update |
^1^ Only provided if auto updates are available for the selected platform.
###### Example Response
```json
{
"name": "0.0.75",
"pub_date": "2023-07-05T17:16:10",
"url": "https://dl-ptb.discordapp.net/apps/osx/0.0.75/DiscordPTB.zip",
"notes": ""
}
```
Get Native Module Versions
Returns a mapping of module names to integer versions representing the found native module versions for the provided [release channel](#desktop-release-channel) and selected platform.
This endpoint is in the process of being decommissioned in favor of [Get Latest Distributed Application Manifest](#get-latest-distributed-application-manifest).
Native modules are versioned uniquely per host version. This endpoint may return an empty object if no native modules are available for the provided parameters (e.g. if the provided host version doesn't exist).
###### Query String Params
| Name | Type | Description |
| ------------- | ------ | ------------------------------------------------------------------------------------ |
| platform? | string | The [platform](#desktop-platform-type) to get update information for (default `osx`) |
| host_version? | string | The host version to get update information for (default `0`) |
###### Example Response
```json
{
"discord_cloudsync": 1,
"discord_desktop_core": 1,
"discord_dispatch": 1,
"discord_erlpack": 1,
"discord_game_utils": 1,
"discord_krisp": 1,
"discord_modules": 1,
"discord_rpc": 1,
"discord_spellcheck": 1,
"discord_utils": 1,
"discord_voice": 1
}
```
Get Native Module
Redirects to a ZIP archive of the native module for the provided [release channel](#desktop-release-channel), module name, and module version, if found.
This endpoint is in the process of being decommissioned in favor of [Get Latest Distributed Application Manifest](#get-latest-distributed-application-manifest).
Native modules are versioned uniquely per host version.
###### Query String Params
| Name | Type | Description |
| ------------- | ------ | ------------------------------------------------------------------------------------ |
| platform? | string | The [platform](#desktop-platform-type) to get update information for (default `osx`) |
| host_version? | string | The host version to get update information for (default `0`) |
Get Latest Distributed Application Installer
Redirects to the latest application installer for the selected platform.
This endpoint is currently [Windows-only](#desktop-platform-type).
###### Query String Params
| Name | Type | Description |
| -------- | ------ | ------------------------------------------------------------------------ |
| channel | string | The [release channel](#desktop-release-channel) to get the installer for |
| platform | string | The [platform](#desktop-platform-type) to get the installer for |
| arch | string | The [architecture](#desktop-architecture-type) to get the installer for |
Get Latest Distributed Application Manifest
Returns information about the latest application updates for the selected platform.
This endpoint is primarily available at `https://updates.discord.com/distributions/app/manifests/latest`.
The version of the endpoint on the main API may not support all features described below.
Note that the rehosted version is proxied, so error responses are different, and new host versions may not be available to everyone immediately after release.
###### Query String Params
| Name | Type | Description |
| ----------------- | ------ | --------------------------------------------------------------------------- |
| install_id? | string | A client-generated UUID unique to the current installation |
| channel | string | The [release channel](#desktop-release-channel) to get the manifest for |
| platform | string | The [platform](#desktop-platform-type) to get the manifest for |
| arch ^1^ | string | The [architecture](#desktop-architecture-type) to get the manifest for |
| platform_version? | string | The version of the client's operating system (e.g. `10.0.19045` on Windows) |
| client_version? | string | The `metadata_version` of the client currently installed |
^1^ `x86` builds are only provided for Windows. `arm64` builds are not provided for Linux.
###### Response Body
| Name | Type | Description |
| -------------------- | ----------------------------------------------------------------------------- | -------------------------------------------------------- |
| full | [manifest package version](#manifest-package-version-structure) object | The full host package for the latest host version |
| deltas | array[[manifest package version](#manifest-package-version-structure) object] | The delta host packages for previous host versions |
| modules | map[string, [manifest package](#manifest-package-structure) object] | The available native modules to download/update |
| required_modules | array[string] | The names of the native modules that the client requires |
| metadata_version ^1^ | ?integer | The version of the manifest metadata |
| required_update ^1^ | boolean | Whether the update is mandatory |
^1^ These fields are only provided via the above rehosted updates endpoint. `metadata_version` is only non-null if `install_id` is provided.
###### Manifest Package Structure
| Name | Type | Description |
| ------ | ----------------------------------------------------------------------------- | -------------------------------------------- |
| full | [manifest package version](#manifest-package-version-structure) object | The full package for the latest host version |
| deltas | array[[manifest package version](#manifest-package-version-structure) object] | The delta package for previous host versions |
###### Manifest Package Version Structure
| Name | Type | Description |
| --------------- | -------------------------------- | --------------------------------------------------------- |
| host_version | array[integer, integer, integer] | The host version that the package targets |
| module_version? | integer | The version of the module included in the package |
| package_sha256 | string | The SHA256 hash of the package file |
| url | string | The download URL to the Brotli-compressed package tarball |
###### Example Response
```json
{
"modules": {
"discord_overlay2": {
"full": {
"host_version": [1, 0, 9015],
"module_version": 1,
"package_sha256": "baa1196292f888c8a90413ea19201849c7a8b7be1a52f2d6b9a185e04ab1b49a",
"url": "https://dl.discordapp.net/distro/app/stable/win/x86/1.0.9015/discord_overlay2/1/full.distro"
},
"deltas": [
{
"host_version": [1, 0, 9014],
"module_version": 1,
"package_sha256": "7634e584b90bb0315fff0b69dd19712c1acbb0687657548e698e5348dc59c824",
"url": "https://dl.discordapp.net/distro/app/stable/win/x86/1.0.9015/discord_overlay2/1/from/1.0.9014/1"
},
{
"host_version": [1, 0, 9013],
"module_version": 2,
"package_sha256": "60b2876b144d918cf8f1ba61110162782c9dc52def8d64b97222cd607989c211",
"url": "https://dl.discordapp.net/distro/app/stable/win/x86/1.0.9015/discord_overlay2/1/from/1.0.9013/2"
}
]
}
},
"full": {
"host_version": [1, 0, 9015],
"package_sha256": "bde31e984e70465fcc9dc01241e3fd8bbb3f84cb49567b8b9930a6a7bc193b7b",
"url": "https://dl.discordapp.net/distro/app/stable/win/x86/1.0.9015/full.distro"
},
"deltas": [
{
"host_version": [1, 0, 9014],
"package_sha256": "48b8f905c7a40ca588e02db4b2903926bc62dbc9e3c9f38f8548882724fac6fa",
"url": "https://dl.discordapp.net/distro/app/stable/win/x86/1.0.9015/from/1.0.9014"
},
{
"host_version": [1, 0, 9013],
"package_sha256": "357914897b025320fe139e3ddb9bc8b81c8d4747947026b83d0627f282d35aff",
"url": "https://dl.discordapp.net/distro/app/stable/win/x86/1.0.9015/from/1.0.9013"
}
],
"required_modules": [
"discord_desktop_core",
"discord_erlpack",
"discord_spellcheck",
"discord_utils",
"discord_voice"
]
}
```
---
# Email Verification
Link: https://docs.discord.food/topics/email-verification
Discord accounts typically require email verification to unlock full functionality. While this is usually done during account registration, users can add or change their email address at any time.
## Registering with an Email Address
When registering a new account, users typically provide an email address to verify their account during the [standard registration process](/authentication#register).
## Adding an Email Address
Users can add an email address to their account at any time. This is required for certain features, or, in some cases, for [anti-abuse purposes](/resources/user#required-action-type). Having an email address associated with your account is recommended.
To add an email address, clients must first send a request to the [Modify Current User](/resources/user#modify-current-user) endpoint with the email address the user wishes to add.
This will send a verification link to the email address that redirects to the official Discord client with a verification token present in the URL's fragment (e.g. `https://discord.com/verify#token=eyJpZCI6ODUyODkyMjk3NjYxOTA2OTkzLCJlbWFpbCI6Im5lbGx5QGRpc2NvcmRhcHAuY29tIn0.Z6pQDg.pKCZBaaiodflO6FZhdttm6B_z74`).
After receiving the token, clients can then procede to [verify the change](#verify-email-address) to complete the process.
## Changing Your Email Address
Users can change their email address at any time.If the current email address is verified, the user will need to have access to it to initiate the change.
In this case, clients must first send a request to the [Send Email Change Challenge](#send-email-change-challenge) endpoint, which will send a verification code to the user's current email address.
After receiving the code, clients can then send a request to the [Verify Email Change Code](#verify-email-change-code) endpoint with the code to receive a verification token that can be used to change the user's email address via the [Modify Current User](/resources/user#modify-current-user) endpoint.
If the current email address is not verified, clients can directly send a request to the [Modify Current User](/resources/user#modify-current-user) endpoint with the new email address, similar to [adding an email address](#adding-an-email-address).
Finally, the user must verify the new email address as outlined in the [above flow](#adding-an-email-address).
## Reverifying Your Email Address
Users may be prompted to reverify their email address for [anti-abuse purposes](/resources/user#required-action-type).
In this case, a verification link will be automatically sent to the email address on file. If the user has not received a link, clients can [choose to resend it](#resend-verification-email).
The link should be used to verify the email address as outlined in the [adding an email address](#adding-an-email-address) flow.
## Removing Your Email Address
Users cannot remove the registered email address from their account. Instead, they must [change it to a new one](#changing-your-email-address) or [delete their account entirely](/resources/user#delete-user-account).
## Endpoints
Verify Email Address
Verifies an email address and links it to the user's account. Fires a [User Update](/gateway/gateway-events#user-update) Gateway event.
###### JSON Params
| Field | Type | Description |
| ----- | ------ | ----------------------------------------- |
| token | string | The verification token received via email |
###### Response Body
| Field | Type | Description |
| --------- | ------- | ------------------------------------------- |
| user_id | string | The ID of the user whose email was verified |
| token ^1^ | ?string | The authentication token for the user |
^1^ A token is not returned if the user has MFA enabled and valid authorization is not provided.
Resend Verification Email
Resends a verification link to the user's email address. Requires that the user's account has an email address marked as unverified. Returns a 204 empty response on success.
Send Email Change Challenge
Sends an email to the current user with a verification code to initiate the email change process. Returns a 204 empty response on success.
Verify Email Change Code
Verifies the email change code sent to the user's email address. If successful, the returned token can be used with the [Modify Current User](/resources/user#modify-current-user) endpoint to change the user's email address.
###### JSON Params
| Field | Type | Description |
| ----- | ------ | --------------------- |
| code | string | The verification code |
###### Response Body
| Field | Type | Description |
| ----- | ------ | --------------------------------------- |
| token | string | The token to use for email verification |
---
# Rate Limits
Link: https://docs.discord.food/topics/rate-limits
Rate limits exist across Discord's APIs to prevent spam, abuse, and service overload. Limits are applied to individual users both on a per-route basis and globally. Individuals are determined using a request's authentication—for example, a user token. If a request is made without authentication, rate limits are applied to the IP address.
Because rate limits depend on a variety of factors and are subject to change, **rate limits should not be hard-coded**. Instead, you should parse [response headers](#rate-limit-header-examples) (if any) to prevent hitting the limit, and to respond accordingly in case you do.
**Per-route rate limits** exist for many individual endpoints, and may include the HTTP method (`GET`, `POST`, `PUT`, or `DELETE`). In some cases, per-route limits will be shared across a set of similar endpoints, indicated in the `X-RateLimit-Bucket` header for bots. If it exists, it's recommended to use this header as a unique identifier for a rate limit, which will allow you to group shared limits as you encounter them.
During calculation, per-route rate limits often account for top-level resources within the path using an identifier—for example, `guild_id` when calling [`/guilds/{guild.id}/channels`](/resources/channel#list-guild-channels). Top-level resources are currently limited to channels (`channel_id`), guilds (`guild_id`), and webhooks (`webhook_id` or `webhook_id + webhook_token`). This means that an endpoint with two different top-level resources may calculate limits independently. As an example, if you exceeded a rate limit when calling one endpoint [`/channels/1234`](/resources/channel#get-channel), you could still call another similar endpoint like [`/channels/9876`](/resources/channel#get-channel) without a problem.
**Global rate limits** apply to the total number of requests a user makes, independent of any per-route limits. You can read more on [global rate limits](#global-rate-limit) below.
[Routes for controlling emojis](/resources/emoji) do not follow the normal rate limit conventions. These routes are specifically limited on a per-guild basis to prevent abuse. This means that the quota returned by our APIs may be inaccurate, and you may encounter **429**s.
## Header Format
For most API requests made with bot or OAuth2 authorization, Discord returns optional HTTP response headers containing the rate limit encountered during your request.
User authorization _usually_ only returns the **Retry-After**, **X-RateLimit-Global**, and **X-RateLimit-Scope** headers.
###### Rate Limit Header Examples
```
X-RateLimit-Limit: 5
X-RateLimit-Remaining: 0
X-RateLimit-Reset: 1470173023
X-RateLimit-Bucket: abcd1234
```
- **Retry-After** - Returned only on **429** responses: the number of seconds to wait before the entire bucket resets
- **X-RateLimit-Global** - Returned only on a **429** response if the rate limit encountered is the global rate limit (not per-route)
- **X-RateLimit-Limit** - The number of requests that can be made
- **X-RateLimit-Remaining** - The number of remaining requests that can be made
- **X-RateLimit-Reset** - Epoch time (seconds since 00:00:00 UTC on January 1, 1970) at which the rate limit resets
- **X-RateLimit-Reset-After** - Total time (in seconds) of when the current rate limit bucket will reset; can have decimals to match previous millisecond ratelimit precision
- **X-RateLimit-Bucket** - A unique string denoting the rate limit being encountered (non-inclusive of major parameters in the route path)
- **X-RateLimit-Scope** - Returned only on **429** responses: value can be `user` (per user limit), `global` (per user global limit), or `shared` (per resource limit)
## Exceeding A Rate Limit
In the case that a rate limit is exceeded, the API will return a **429** response code with a JSON body.
###### Rate Limit Response Structure
| Field | Type | Description |
| ----------- | ------- | ---------------------------------------------------------------- |
| message | string | A message saying you are being rate limited |
| retry_after | float | The number of seconds to wait before submitting another request |
| global | boolean | A value indicating if you are being globally rate limited or not |
| code? | integer | An [error code](/topics/errors#json) for special limits |
Note that normal route rate-limiting headers will also be sent in this response. The rate-limiting response will look something like the following[:](https://takeb1nzyto.space/)
###### Example Exceeded User Rate Limit Response
```json
< HTTP/1.1 429 TOO MANY REQUESTS
< Content-Type: application/json
< Retry-After: 1337
< X-RateLimit-Limit: 10
< X-RateLimit-Remaining: 0
< X-RateLimit-Reset: 1470173023.123
< X-RateLimit-Reset-After: 1337.57
< X-RateLimit-Bucket: abcd1234
< X-RateLimit-Scope: user
{
"message": "You are being rate limited.",
"retry_after": 776,
"global": false
}
```
###### Example Exceeded Resource Rate Limit Response
```json
< HTTP/1.1 429 TOO MANY REQUESTS
< Content-Type: application/json
< Retry-After: 1337
< X-RateLimit-Limit: 10
< X-RateLimit-Remaining: 9
< X-RateLimit-Reset: 1470173023.123
< X-RateLimit-Reset-After: 1337.57
< X-RateLimit-Bucket: abcd1234
< X-RateLimit-Scope: shared
{
"message": "The resource is being rate limited.",
"retry_after": 776.57,
"global": false
}
```
###### Example Exceeded Global Rate Limit Response
```json
< HTTP/1.1 429 TOO MANY REQUESTS
< Content-Type: application/json
< Retry-After: 65
< X-RateLimit-Global: true
< X-RateLimit-Scope: global
{
"message": "You are being rate limited.",
"retry_after": 65,
"global": true
}
```
## Global Rate Limit
All users can make up to 50 requests per second to our API. If no authorization header is provided, then the limit is applied to the IP address. This is independent of any individual rate limit on a route. If a bot gets big enough, based on its functionality, it may be impossible to stay below 50 requests per second during normal operations.
Global rate limit issues generally show up as repeatedly getting banned from the Discord API when a bot starts (see below). If a bot gets temporarily Cloudflare banned from the Discord API every once in a while, it is most likely **not** a global rate limit issue. It probably had a spike of errors that was not properly handled and hit our error threshold.
If a bot owner is experiencing repeated Cloudflare bans from the Discord API within normal operations of their bot, they can reach out to support to see if they qualify for a global rate limit increase to 1,200 requests per second. They can contact Discord support using [https://dis.gd/rate-limit](https://dis.gd/rate-limit).
Webhooks are not bound to a user's global rate limit.
## Invalid Request Limit aka Cloudflare Bans
IP addresses that make too many invalid HTTP requests are automatically and temporarily restricted from accessing the Discord API. Currently, this limit is **10,000 per 10 minutes** and leads to a **24 hour ban**. An invalid request is one that results in **401**, **403**, or **429** statuses.
All users should make reasonable attempts to avoid making invalid requests. For example:
- **401** responses are avoided by providing a valid token in the authorization header when required and by stopping further requests after a token becomes invalid
- **403** responses are avoided by inspecting role or channel permissions and by not making requests that are restricted by such permissions
- **429** responses are avoided by inspecting the rate limit headers documented above and by not making requests on exhausted buckets until after they have reset; _429 errors returned with `X-RateLimit-Scope: shared` are not counted against you_
Large bots, especially those that can potentially make 10,000 requests per 10 minutes (a sustained 16 to 17 requests per second), should consider logging and tracking the rate of invalid requests to avoid reaching this hard limit.
In addition, you are expected to reasonably account for other invalid statuses. For example, if a webhook returns a **404** status you should not attempt to use it again—repeated attempts to do so will result in a temporary restriction.
Note that additional Cloudflare limits exist on specific endpoints that are not documented here. Sometimes, these limits may return a `Retry-After` header. In these cases, you should respect the header and not make further requests until the time has elapsed.
If no `Retry-After` header is present, you should not programatically retry the request.
## Unavailable Resources
In some cases, clients may make an API request for which the server does not yet have a response to. In these cases, the API will return a **202** response code with a JSON body.
###### Unavailable Resource Response Structure
| Field | Type | Description |
| ---------------- | ------- | ------------------------------------------------------------------ |
| message | string | A message saying the resource is not yet available |
| code | integer | An [error code](/topics/errors#json) (will always begin with `11`) |
| retry_after? ^1^ | float | The number of seconds to wait before submitting another request |
^1^ If the timeframe specified is missing or `0`, the client should retry the request after a short delay (typically 5 seconds).
---
# RPC
Link: https://docs.discord.food/topics/rpc
Discord contains multiple methods of RPC communication to send messages to locally running Discord clients, allowing the remote execution of specific commands to interface with the client.
This powers functions you may be familiar with, like clicking an invite link in the browser prompting the locally running Discord client to open with the invite modal.
This page documents the entire RPC protocol. It can be used to help interface with the official Discord client, or as a reference document to implement your own client that supports the RPC protocol.
### RPC Protocol Version
The current and only supported version of the RPC protocol is `1`.
### RPC Transports
RPC supports four different transports:
| Type | Name | Description |
| ------------ | ------------------------------------- | ------------------------------------------------------------------------------------------------------------------------- |
| ws | [WebSocket](#websocket-transport) | Primarily meant for communicating with the client from the web, limited to trusted partners |
| http | [HTTP](#http-transport) | Meant for one-off commands that do not require a long-lived connection |
| ipc | [IPC](#ipc-transport) | Meant for communicating with the client from local applications, like games or other software running on a user's machine |
| post_message | [PostMessage](#postmessage-transport) | Used by embedded activities to communicate with the client from within an iFrame |
### RPC Scopes
Architecturally, RPC uses the same scopes as [OAuth2](/topics/oauth2). The following pseudoscopes below are inherent to the protocol itself, and do not exist as real scopes in the API.
| Value | Description |
| ------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| rpc.authenticated | Granted after successfully completing the authentication handshake with the RPC server |
| rpc.local | Granted to any connection to an RPC transport outside of a browser context (i.e. no `Origin` header) |
| rpc.private | Granted to WebSocket or HTTP transports from a Discord-controlled `Origin` (i.e. `https://discord.com`, `https://discordapp.com`, or one of their subdomains) |
| rpc.private.limited | Granted alongside `rpc.private`, as well as to HTTP transports utilizing a `GET` method |
| rpc.embedded_app | Granted to any connection to a PostMessage transport |
### RPC Close Codes
Close codes will either be received as a WebSocket close frame or a protocol-level `CLOSE` opcode. They will be accompanied by a human-friendly message describing the reason for the close.
| Code | Name |
| ---- | ----------------- |
| 1000 | CLOSE_NORMAL |
| 1003 | CLOSE_UNSUPPORTED |
| 1006 | CLOSE_ABNORMAL |
| 4000 | INVALID_CLIENTID |
| 4001 | INVALID_ORIGIN |
| 4002 | RATELIMITED |
| 4003 | TOKEN_REVOKED |
| 4004 | INVALID_VERSION |
| 4005 | INVALID_ENCODING |
### RPC Errors
Errors will be dispatched as a [`ERROR`](#error) event in response to an outgoing command. They will be accompanied by a human-friendly message describing the error.
| Code | Name |
| -------- | -------------------------------------- |
| 1000 | UNKNOWN_ERROR |
| 1001 | SERVICE_UNAVAILABLE |
| 1002 | TRANSACTION_ABORTED |
| 4000 | INVALID_PAYLOAD |
| 4002 | INVALID_COMMAND |
| 4003 | INVALID_GUILD |
| 4004 | INVALID_EVENT |
| 4005 | INVALID_CHANNEL |
| 4006 | INVALID_PERMISSIONS |
| 4007 | INVALID_CLIENTID |
| 4008 | INVALID_ORIGIN |
| 4009 | INVALID_TOKEN |
| 4010 | INVALID_USER |
| 4011 | INVALID_INVITE |
| 4012 | INVALID_ACTIVITY_JOIN_REQUEST |
| ~~4013~~ | ~~INVALID_LOBBY~~ |
| ~~4014~~ | ~~INVALID_LOBBY_SECRET~~ |
| 4015 | INVALID_ENTITLEMENT |
| 4016 | INVALID_GIFT_CODE |
| 4017 | INVALID_GUILD_TEMPLATE |
| 4018 | INVALID_SOUND |
| 4019 | INVALID_PROVIDER |
| 4020 | INVALID_CONNECTION_CALLBACK_STATE |
| 4021 | BAD_REQUEST_FOR_PROVIDER |
| 5000 | OAUTH2_ERROR |
| 5001 | SELECT_CHANNEL_TIMED_OUT |
| 5002 | GET_GUILD_TIMED_OUT |
| 5003 | SELECT_VOICE_FORCE_REQUIRED |
| ~~5004~~ | ~~CAPTURE_SHORTCUT_ALREADY_LISTENING~~ |
| 5005 | INVALID_ACTIVITY_SECRET |
| 5006 | NO_ELIGIBLE_ACTIVITY |
| ~~5007~~ | ~~LOBBY_FULL~~ |
| 5008 | PURCHASE_CANCELED |
| 5009 | PURCHASE_ERROR |
| 5010 | UNAUTHORIZED_FOR_ACHIEVEMENT |
| 5011 | RATE_LIMITED |
| 5012 | UNAUTHORIZED_FOR_APPLICATION |
| 5013 | NO_CONNECTION_FOUND |
###### Example RPC Error
```json
{
"code": 4000,
"message": "Invalid Client ID"
}
```
### Rate Limits
The Discord RPC server has a per-client rate limit of 2 connections per minute. This rate limit is raised to 60 connections per minute on Canary clients, as well as clients connecting over the PostMessage transport.
Connections exceeding this limit will have a delay before processing.
## WebSocket Transport
All Discord clients have an RPC server running that allows control over local Discord clients. The local RPC server runs on localhost (`127.0.0.1`) and is set up to process WebSocket connections and proxy API requests.
### Connecting
For WebSocket connections, the connection is always in the form of `ws://127.0.0.1:PORT/`. `discordapp.io` may also be used as it always resolves to localhost.
The port range for Discord's local RPC server is [`6463`, `6472`]. Since the RPC server runs locally, there's a chance it might not be able to obtain its preferred port when it tries to bind to one.
For this reason, the local RPC server will pick one port out of a range of these 10 ports, trying sequentially until it can bind to one. For multiple clients (e.g. Stable and Canary), you might want to add a feature to manually select the port so you can more easily debug.
The below query string parameters should be appended to the connection URL.
###### Query String Params
| Field | Type | Description |
| -------------- | ------- | ------------------------------------------------------------------------------------ |
| v | integer | The [version of the RPC protocol](#rpc-protocol-version) to use |
| client_id? ^1^ | string | The ID of the application connecting to the socket |
| encoding? ^2^ | string | The encoding for packets sent to the client (either `json` or `etf`, default `json`) |
^1^ Can only be omitted when connecting from a Discord-controlled `Origin`.
^2^ ETF encoding may not be supported by all clients. If ETF encoding is requested, outgoing packets must also be sent in the ETF format.
#### Sending and Receiving Packets
Packets are sent as JSON objects containing the [command you want to send to the Discord client](#outgoing-payload-structure). [Incoming packets](#incoming-payload-structure) will need to be correctly parsed to obtain the JSON response.
#### Authentication
Upon connection, the RPC server will validate your provided `client_id`. If the connection is from a non-Discord-controlled `Origin` and the `client_id` is missing, the server will immediately disconnect.
Otherwise, the server will attempt to fetch the client application using the [Get RPC Application](/resources/application#get-rpc-application) endpoint. If the application is not found, or the `Origin` header of the connection does not match one of the application's
[`rpc_origins` values](/resources/application#application-object), the server will disconnect. Only if the application is found and the `Origin` header matches an `rpc_origins` value will the connection will be accepted.
Upon a successful connection, the server will send a `READY` event containing some basic user information and configuration data. At this point, you can send an `AUTHORIZE` command to obtain an [OAuth2 code, which can then be exchanged for an access token](/topics/oauth2#example-access-token-exchange).
### Usage
When connecting from a browser, the WebSocket transport can only be used by Discord itself and a select few trusted partners, as the WebSocket transport allows controlling the client without having software installed on the user's machine.
For example, upon certain events, like clicking an invite link from a browser, Discord will open a WebSocket connection to the local RPC server, sending the `INVITE_BROWSER` command:
###### Example Invite Browser Payload
```json
{
"cmd": "INVITE_BROWSER",
"args": {
"code": "fortnite"
},
"nonce": "5c283c7d-524a-4090-b04b-ea0fb023e44c"
}
```
###### Example Invite Browser Response
The local client will receive and use the information from this response to display the invite modal, and respond with:
```json
{
"cmd": "INVITE_BROWSER",
"data": {
"invite": {
"type": 0,
"code": "fortnite",
"expires_at": null
// ...
},
"code": "fortnite"
},
"evt": null,
"nonce": "5c283c7d-524a-4090-b04b-ea0fb023e44c"
}
```
## HTTP Transport
The HTTP transport is a subset of the WebSocket transport meant for one-off commands that do not require a long-lived connection.
### Connecting
The HTTP transport is available on the same port range as the WebSocket transport. The connection URL is in the form of `http://127.0.0.1:PORT/rpc`.
The below query string parameters still apply.
###### Query String Params
| Field | Type | Description |
| -------------- | ------- | --------------------------------------------------------------- |
| v | integer | The [version of the RPC protocol](#rpc-protocol-version) to use |
| client_id? ^1^ | string | The ID of the application connecting to the socket |
^1^ Can only be omitted when connecting from a Discord-controlled `Origin`.
#### Sending and Receiving Packets
Clients should send a `POST` request to the connection URL with a JSON body containing the [command you want to send](#outgoing-payload-structure). The server will respond with a JSON object containing the response of the command.
An even more limited transport is available via a `GET` request, where authentication is entirely bypassed, and `client_id` can be omitted. However, this only grants the `rpc.private.limited` scope, which only allows a select few commands that don't require authenticated scopes.
For this transport, a JSON-encoded `payload` query string parameter should be sent alongside the request, containing the same JSON object as the body of a `POST` request. A `callback` query string parameter may also be sent, to specify where
the response should redirect to. If the callback is not provided, or does not match the server's origin, the server will use the default marketing URL instead. This is intended for internal use by Discord's web client, and should not be used by third parties.
#### Authentication
The authentication process for the HTTP transport is the same as the WebSocket transport, with one crucial difference: if no `Origin` header is present, the `rpc_origins` check will be bypassed and the connection will be accepted as long as the `client_id` is valid.
This allows this transport to be used by anyone outside of a browser context.
However, as the HTTP transport can only be used for one-off commands, you will be unable to complete the typical RPC handshake.
This limits the use of this transport to only commands that don't require authenticated scopes.
## IPC Transport
Similarly, all Discord clients also have an IPC server running that allows control over local Discord clients.
By sending packets through the Discord RPC IPC pipe, you can programmatically control your local Discord client, like joining voice channels, retrieving guild or user information, and more.
### Connecting
Discord can be on any pipe ranging from `discord-ipc-0` to `discord-ipc-9`. It is a good idea to try and connect to each one and keeping the first one you successfully connect to.
For multiple clients (e.g. Stable and Canary), you might want to add a feature to manually select the pipe so you can more easily debug.
On Windows, the Discord IPC pipe format is `\\\\?\\pipe\\discord-ipc-0`. On macOS & Linux, it'll be kept in the folder
indicated by the `XDG_RUNTIME_DIR`, `TMPDIR`, `TMP` or `TEMP` envvars. If none of those exist, use `/tmp/`.
#### Sending and Receiving Packets
The IPC protocol has an additional of abstraction over the typical [JSON payloads](#packet-payloads) used in the WebSocket transport.
Packets are sent as binary data in a simple format composed of an 8-byte header and payload. The header consists of two 32-bit unsigned integers (little endian) representing the opcode and payload length.
###### IPC Opcodes
| Value | Name | Description |
| ----- | --------- | ------------------------------------------------------------------------------------------------------------- |
| 0 | HANDSHAKE | [Handshake](#handshake-structure) to be sent immediately after connecting |
| 1 | FRAME | Typical [payload](#packet-payloads) for communication with the client |
| 2 | CLOSE | Sent when the [Discord client is asking you to leave](#close-structure), or you want to gracefully disconnect |
| 3 | PING | If the Discord client sends this to you, you should reply with a `PONG` of the same data |
| 4 | PONG | Reply to a `PING` |
###### Packet Structure
| Field | Type | Description | Size |
| ------- | -------------------------------- | ----------------------------- | -------------- |
| Opcode | Unsigned integer (little endian) | Unsigned integer opcode value | 4 bytes |
| Length | Unsigned integer (little endian) | Length of the payload | 4 bytes |
| Payload | Binary data | Format defined by opcode | Variable bytes |
###### Example Packet
```h
00000000 28000000 7B2276223A312C22 (trimmed)
^^^^^^^^ ^^^^^^^^ ^^^^^^^^^^^^^^^^
OPCODE 0 Length Payload
HANDSHAKE 40 bytes { "v" : 1, "
```
#### Authentication
After connecting to the IPC socket, you should immediately send a handshake packet to the server. The server will respond with a `FRAME` packet containing the `READY` event with some basic user information and configuration data.
Upon successful reception of this event, you can send an `AUTHORIZE` command to obtain an [OAuth2 code, which can then be exchanged for an access token](/topics/oauth2#example-access-token-exchange).
Once authenticated, you can call RPC commands on behalf of the user!
###### Handshake Structure
| Field | Type | Description |
| --------- | ------- | --------------------------------------------------------------- |
| v | integer | The [version of the RPC protocol](#rpc-protocol-version) to use |
| client_id | string | The ID of the application connecting to the socket |
###### Close Structure
| Field | Type | Description |
| ------- | ------- | ------------------------------------------------------ |
| code | integer | The [close code](#rpc-close-codes) |
| message | string | A human-readable message explaining the closure reason |
## PostMessage Transport
The PostMessage transport is meant for embedded activities to communicate with the client from within an iFrame.
Instead of manually implementing the RPC protocol within your embedded activity, you should use the [activities SDK](https://github.com/discord/embedded-app-sdk), which handles this for you, providing a much easier interface to interact with the client.
### Connecting
The PostMessage transport does not require an actual connection, as messages will be sent to the parent window using `window.postMessage`.
#### Sending and Receiving Packets
The PostMessage transport uses a similar abstraction layer to the IPC transport.
Packets are sent as an array of two elements, the first being the integer opcode, and the second being the payload object. Opcodes follow the [same values as the IPC transport](#ipc-opcodes).
#### Authentication
Similarly to IPC, you should immediately send a handshake message to the parent window after the iFrame loads.
Then, the client will validate that the message is coming from a valid embedded activities origin, typically `https://.discordsays.com`.
The parent window will respond with a `READY` event containing some basic user information and configuration data.
Upon successful reception of this event, you can send an `AUTHORIZE` command to obtain an [OAuth2 code, which can then be exchanged for an access token](/topics/oauth2#example-access-token-exchange).
Once authenticated, you can call RPC commands on behalf of the user!
###### Handshake Structure
| Field | Type | Description |
| ------------ | ------- | ------------------------------------------------------------------------------ |
| v | integer | The [version of the RPC protocol](#rpc-protocol-version) to use |
| client_id | string | The ID of the application connecting to the socket |
| frame_id | string | The ID of the current iFrame, provided in the query string of the iFrame's URL |
| sdk_version? | string | The version of the embedded activities SDK being used |
## Packet Payloads
Packet payloads are JSON objects containing the command you want to send to the Discord client. Incoming packets will need to be correctly parsed to obtain the JSON response.
###### Outgoing Payload Structure
| Field | Type | Description |
| -------- | ------ | --------------------------------------------------------------------------------------------- |
| cmd | string | The [command](#rpc-commands) indicating the action of the request |
| args | object | The arguments coinciding with the command of the request |
| nonce | string | A unique identifier given to a command that will be echoed back to you upon a successful send |
| evt? ^1^ | string | The event the app is subscribing to |
^1^ Only required when `cmd` is `SUBSCRIBE` or `UNSUBSCRIBE`.
The RPC server will echo back every command you send as a response. This can be used as a lock-step feature to avoid flooding
the server with messages. It can also be used to validate messages such as [`PRESENCE` or `SUBSCRIBE`](#rpc-commands).
###### Incoming Payload Structure
| Field | Type | Description |
| ------- | ------- | ------------------------------------------------------------------------- |
| cmd | string | The echoed [command](#rpc-commands) indicating the action of the response |
| data | ?object | The response data of the command |
| nonce | ?string | The unique identifier of the requested command |
| evt ^1^ | ?string | The event coinciding with the incoming command |
^1^ Only present in [`DISPATCH`, `SUBSCRIBE`, and `UNSUBSCRIBE`](#rpc-commands) events.
Due to Discord client bugs, in certain incoming packets, some of the below objects may instead be serialized as their internal client representation, which may not match the documented API structure.
These objects will commonly serialize fields as `camelCase` instead of `snake_case`, and may also include additional fields not documented in the API, or omit some fields that are documented in the API.
Handle RPC objects with care.
### RPC User Object
See the [user resource](/resources/user#user-object) for more information.
###### RPC User Structure
| Field | Type | Description |
| ---------------------- | ------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------- |
| id | snowflake | The ID of the user |
| username | string | The user's username, may be unique across the platform |
| discriminator | string | The user's stringified 4-digit Discord tag |
| global_name | ?string | The user's display name |
| avatar | ?string | The user's [avatar hash](/reference#cdn-formatting) |
| avatar_decoration_data | ?[avatar decoration data](/resources/user#avatar-decoration-data-object) object | The user's [avatar decoration](https://support.discord.com/hc/en-us/articles/13410113109911-Avatar-Decorations) |
| bot | boolean | Whether the user is a bot account |
| flags | integer | The public [flags](/resources/user#user-flags) on a user's account |
| premium_type | integer | The [type of premium (Nitro) subscription](/resources/user#premium-type) on a user's account |
### RPC Guild Object
See the [guild resource](/resources/guild#guild-object) for more information.
###### RPC Guild Structure
| Field | Type | Description |
| ------------------- | --------- | ------------------------------ |
| id | snowflake | The ID of the guild |
| name | string | The name of the guild |
| icon_url | ?string | The guild's icon URL |
| vanity_url_code ^1^ | ?string | The guild's vanity invite code |
^1^ Only available in [Get Guild](#get-guild) response.
### RPC Guild Member Object
See the [guild resource](/resources/guild#guild-object) for more information.
###### RPC Guild Member Structure
| Field | Type | Description |
| ---------------------- | ------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------- |
| user_id | snowflake | The ID of the user this guild member represents |
| nick | ?string | The guild-specific nickname of the member |
| guild_id | snowflake | The ID of the guild the user is in |
| avatar | ?string | The member's [guild avatar hash](/reference#cdn-formatting) |
| avatar_decoration_data | ?[avatar decoration data](/resources/user#avatar-decoration-data-object) object | The member's [guild avatar decoration](https://support.discord.com/hc/en-us/articles/13410113109911-Avatar-Decorations) |
| banner? | ?string | The member's [guild banner hash](/reference#cdn-formatting) |
| bio? | ?string | The member's guild-specific bio |
| pronouns? | ?string | The member's guild-specific pronouns |
| color_string? | ?string | The hex-encoded color of the member's name |
###### Partial RPC Guild Member Structure
| Field | Type | Description |
| -------- | ------------------------------------------------------- | --------------------------------------------------------- |
| user | [RPC user](#rpc-user-object) object | The user this guild member represents |
| nick | ?string | The guild-specific nickname of the member |
| status | string | The [status](/resources/presence#status-type) of the user |
| activity | ?[activity](/resources/presence#activity-object) object | The current activity the user is partaking in |
### RPC Channel Object
See the [channel resource](/resources/channel#channel-object) for more information.
###### RPC Channel Structure
| Field | Type | Description |
| ------------ | -------------------------------------------------------- | ---------------------------------------------------------- |
| id | snowflake | The ID of the channel |
| name | string | The name of the channel |
| type | integer | The [type of channel](/resources/channel#channel-type) |
| topic | string | The channel topic |
| bitrate | integer | The bitrate (in bits) of the voice channel |
| user_limit | integer | The user limit of the voice channel (0 refers to no limit) |
| guild_id | ?snowflake | The ID of the guild the channel is in |
| position | integer | Sorting position of the channel |
| messages ^1^ | array[[RPC message](#rpc-message-object) object] | The last 50 messages within the channel in ascending order |
| voice_states | array[[RPC voice state](#rpc-voice-state-object) object] | States of members currently in the voice channel |
^1^ Only included if the channel or guild's `application_id` matches the `client_id` of the connection, or the authorization has the `messages.read` scope.
###### Partial RPC Channel Structure
| Field | Type | Description |
| ----- | --------- | ------------------------------------------------------ |
| id | snowflake | The ID of the channel |
| name | string | The name of the channel |
| type | integer | The [type of channel](/resources/channel#channel-type) |
### RPC Message Object
See the [message resource](/resources/message#message-object) for more information.
###### RPC Message Structure
| Field | Type | Description |
| ---------------- | ---------------------------------------------------------------- | ---------------------------------------------------------------- |
| id | snowflake | The ID of the message |
| blocked? | boolean | Whether the author of the message is blocked by the current user |
| bot? | boolean | Whether the author of the message is a bot account |
| content | string | Contents of the message |
| content_parsed? | array[object] | Parsed contents of the message |
| nick? | string | The displayed nick of the author |
| author_color? | string | The hex-encoded color of the message author's name |
| edited_timestamp | ?ISO8601 timestamp | When this message was last edited |
| timestamp | ISO8601 timestamp | When this message was sent |
| tts | boolean | Whether this message will be read out by TTS |
| mentions | array[[RPC user](#rpc-user-object) object] | Users specifically mentioned in this message |
| mention_everyone | boolean | Whether this message mentions everyone |
| mention_roles | array[snowflake] | Roles specifically mentioned in this message |
| embeds | array[[embed](/resources/message#embed-object) object] | Content embedded in the message |
| attachments | array[[attachment](/resources/message#attachment-object) object] | The attached files |
| author? | ?[RPC user](#rpc-user-object) object | The author of the message |
| pinned | boolean | Whether this message is pinned |
| type | integer | The [type of message](/resources/message#message-type) |
### RPC Voice State Object
###### RPC Voice State Structure
| Field | Type | Description |
| ----------- | ------------------------------------------------------------------ | --------------------------------- |
| nick | string | The displayed nick of the user |
| mute | boolean | Whether the user is muted locally |
| volume | float | The local volume of the user |
| pan | [pan](#pan-structure) object | The pan of the user |
| voice_state | [RPC remote voice state](#rpc-remote-voice-state-structure) object | The internal voice state |
| user | [RPC user](#rpc-user-object) | The user this voice state is for |
###### RPC Remote Voice State Structure
| Field | Type | Description |
| --------- | ------- | -------------------------------------------------- |
| mute | boolean | Whether this user is muted by the guild, if any |
| deaf | boolean | Whether this user is deafened by the guild, if any |
| self_mute | boolean | Whether this user is locally muted |
| self_deaf | boolean | Whether this user is locally deafened |
| suppress | boolean | Whether this user's permission to speak is denied |
###### Pan Structure
| Field | Type | Description |
| ----- | ----- | ----------------------- |
| left | float | Left pan of user (0-1) |
| right | float | Right pan of user (0-1) |
### RPC Relationship Object
###### RPC Relationship Structure
| Field | Type | Description |
| -------- | ------------------------------------------------------------------------ | ---------------------------------------------------------------------- |
| type | integer | The [type](/resources/relationships#relationship-type) of relationship |
| user | [RPC user](#rpc-user-object) object | The target user |
| presence | [RPC relationship presence](#rpc-relationship-presence-structure) object | The presence of the target user |
###### RPC Relationship Presence Structure
| Field | Type | Description |
| -------- | ------------------------------------------------------- | ----------------------------------------------------------- |
| status | string | The [status](/resources/presence#status-type) of the user |
| activity | ?[activity](/resources/presence#activity-object) object | The user's activity associated with the current application |
### RPC Voice Settings Object
###### RPC Voice Settings Structure
| Field | Type | Description |
| ---------------------- | -------------------------------------------------------------------- | -------------------------------------------- |
| input | [RPC voice IO settings](#rpc-voice-io-settings-structure) object | The input settings |
| output | [RPC voice IO settings](#rpc-voice-io-settings-structure) object | The output settings |
| mode | [RPC voice settings mode](#rpc-voice-settings-mode-structure) object | The voice mode settings |
| automatic_gain_control | boolean | Whether automatic gain control is enabled |
| echo_cancellation | boolean | Whether echo cancellation is enabled |
| noise_suppression | boolean | Whether background noise is being suppressed |
| qos | boolean | Whether voice Quality of Service is enabled |
| silence_warning | boolean | Whether the input warning notice is disabled |
| deaf | boolean | Whether the user is locally deafened |
| mute | boolean | Whether the user is locally muted |
###### RPC Voice IO Settings Structure
| Field | Type | Description |
| --------------------- | ------------------------------------------------------------- | ------------------------------- |
| available_devices ^1^ | array[[available device](#available-device-structure) object] | The available devices |
| device_id | string | The ID of the primary device |
| volume | float | The input voice level (max 200) |
###### Available Device Structure
| Field | Type | Description |
| ----- | ------ | ---------------------- |
| id | string | The ID of the device |
| name | string | The name of the device |
###### RPC Voice Settings Mode Structure
| Field | Type | Description |
| -------------- | ----------------------------------------------------------------- | ---------------------------------------------------------------- |
| type | string | The [type of voice settings mode](#rpc-voice-settings-mode-type) |
| auto_threshold | boolean | Whether the voice activity threshold is automatically set |
| threshold | integer | The threshold (in dB) for voice activity (-100-0) |
| shortcut | array[[shortcut key combo](#shortcut-key-combo-structure) object] | The shortcut key combos for PTT |
| delay | integer | The PTT release delay in milliseconds (max 2000) |
###### RPC Voice Settings Mode Type
| Value | Description |
| -------------- | -------------- |
| PUSH_TO_TALK | Push To Talk |
| VOICE_ACTIVITY | Voice activity |
###### Shortcut Key Combo Structure
| Field | Type | Description |
| --------- | ------- | ---------------------------------------------------------- |
| type | integer | The [type of shortcut key combo](#shortcut-key-combo-type) |
| code | integer | The code of the shortcut key combo |
| name? ^1^ | string | The name of the shortcut key combo |
^1^ This field is always present when received.
###### Shortcut Key Combo Type
| Value | Name | Description |
| ----- | --------------------- | --------------------- |
| 0 | KEYBOARD_KEY | Keyboard key |
| 1 | MOUSE_BUTTON | Mouse button |
| 2 | KEYBOARD_MODIFIER_KEY | Keyboard modifier key |
| 3 | GAMEPAD_BUTTON | Gamepad button |
### RPC Guild Template Object
###### RPC Guild Template Structure
| Field | Type | Description |
| ------------------------- | ----------------------------------------------------- | ------------------------------------------------------------ |
| code | string | The code of the template (unique ID) |
| state | string | The [state of the guild template](#rpc-guild-template-state) |
| name | string | The name of the template (1-100 characters) |
| description | string | The description for the template (max 120 characters) |
| creatorId | snowflake | The ID of the user who created the template |
| creator | partial [user](/resources/user#user-object) object | The user who created the template |
| createdAt | ISO8601 timestamp | When this template was created |
| updatedAt | ISO8601 timestamp | When this template was last synced to the source guild |
| sourceGuildId | snowflake | The ID of the guild this template is based on |
| serializedSourceGuild ^1^ | partial [guild](/resources/guild#guild-object) object | The guild snapshot this template contains |
| usageCount | integer | Number of times this template has been used |
| isDirty | ?boolean | Whether the template has unsynced changes |
^1^ This partial guild object is special in that it and the objects within always contain applicable optional fields (even if they're not applicable).
This leads to unexpected behavior, such as `available_tags` being serialized for voice channels.
Additionally, the main guild object is missing the `id` field, and all other `id` fields are not real snowflakes.
###### RPC Guild Template State
| Value | Description |
| --------- | ------------------------------------ |
| RESOLVING | The guild template is being resolved |
| RESOLVED | The guild template is resolved |
| EXPIRED | The guild template is expired |
| ACCEPTED | The guild template is accepted |
| ACCEPTING | The guild template is being accepted |
### Certified Device Object
###### Certified Device Structure
| Field | Type | Description |
| --------------------------- | -------------------------------------------------------------------- | -------------------------------------------------------- |
| type | string | The [type of certified device](#certified-device-type) |
| id | string | The ID of the certified device |
| vendor | [certified device vendor](#certified-device-vendor-structure) object | The vendor of the certified device |
| model | [certified device model](#certified-device-model-structure) object | The model of the certified device |
| related? | array[string] | The IDs of other devices related to this device (min 1) |
| echo_cancellation? ^1^ | boolean | Whether the device's native echo cancellation is enabled |
| noise_suppression? ^1^ | boolean | Whether the device's native noise suppression is enabled |
| automatic_gain_control? ^1^ | boolean | Whether the device's automatic gain control is enabled |
| hardware_mute? ^1^ | boolean | Whether the device is muted hardware-wise |
^1^ Only applicable if the type is [`audioinput`](#certified-device-type).
###### Certified Device Type
| Value | Description |
| ----------- | ----------- |
| audioinput | Microphone |
| audiooutput | Speaker |
| videoinput | Camera |
###### Certified Device Vendor Structure
| Field | Type | Description |
| ----- | ------ | ----------------------------- |
| id | string | The ID of the device vendor |
| name | string | The name of the device vendor |
###### Certified Device Model Structure
| Field | Type | Description |
| ----- | ------ | ---------------------------- |
| id | string | The ID of the device model |
| name | string | The name of the device model |
### RPC Activity Participant Object
###### RPC Activity Participant Object
This structure is a superset of the [RPC user](#rpc-user-object) object with the following additional fields:
| Field | Type | Description |
| --------- | ------ | ----------------------------------------------------------- |
| nickname? | string | The guild-specific nickname of the member (1-32 characters) |
###### Orientation State
| Value | Name | Description |
| ----- | --------- | ------------------------------- |
| 1 | UNLOCKED | The orientation is unlocked |
| 2 | PORTRAIT | The orientation is in portrait |
| 3 | LANDSCAPE | The orientation is in landscape |
## RPC Commands
Commands are the means in which an application can interface with the client.
| Name | Description | Scopes |
| --------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------ | ----------------------------------------------- |
| [DISPATCH](#rpc-events) | Event dispatch | |
| [AUTHORIZE](#authorize) | Used to authorize a new client with your application | |
| [AUTHENTICATE](#authenticate) | Used to authenticate an existing client with your application | |
| [SUBSCRIBE](#subscribe) | Used to subscribe to an RPC event | |
| [UNSUBSCRIBE](#unsubscribe) | Used to unsubscribe from an RPC event | |
| [GET_GUILD](#get-guild) | Used to retrieve guild information from the client | `rpc` |
| [GET_GUILDS](#get-guilds) | Used to retrieve a list of guilds from the client | `rpc` |
| [GET_CHANNEL](#get-channel) ^1^ | Used to retrieve channel information from the client | `rpc`, `guilds`, or `guilds.channels.read` |
| [GET_CHANNELS](#get-channels) | Used to retrieve a list of channels for a guild from the client | `rpc` |
| [GET_CHANNEL_PERMISSIONS](#get-channel-permissions) | Used to retrieve the permission settings for the currently connected voice channel | `guilds.members.read` or `guilds.channels.read` |
| [CREATE_CHANNEL_INVITE](#create-channel-invite) | Used to create an invite link for a given channel | `rpc` |
| [GET_RELATIONSHIPS](#get-relationships) | Used to retrieve the list of relationships with their presences | `relationships.read` |
| [GET_USER](#get-user) | Used to retrieve information about a specific user | `rpc.local` or `rpc.embedded_app` |
| [SET_USER_VOICE_SETTINGS](#set-user-voice-settings) | Used to change voice settings of users in voice channels | `rpc` or `rpc.voice.write` |
| [SET_USER_VOICE_SETTINGS_2](#set-user-voice-settings-2) | Used to change basic voice settings of users in voice channels, scoped to the current application | `rpc.local` |
| [PUSH_TO_TALK](#push-to-talk) | Used to enable or disable push-to-talk functionality | `rpc` and `rpc.voice.write` |
| [SELECT_VOICE_CHANNEL](#select-voice-channel) | Used to join or leave a voice channel or private call | `rpc` |
| [GET_SELECTED_VOICE_CHANNEL](#get-selected-voice-channel) | Used to get the current voice channel the client is in | `rpc` or `rpc.voice.read` |
| [SELECT_TEXT_CHANNEL](#select-text-channel) | Used to select a messageable channel | `rpc` |
| [GET_VOICE_SETTINGS](#get-voice-settings) | Used to retrieve the client's voice settings | `rpc` or `rpc.voice.read` |
| [SET_VOICE_SETTINGS](#set-voice-settings) | Used to set the client's voice settings | `rpc` or `rpc.voice.write` |
| [SET_VOICE_SETTINGS_2](#set-voice-settings-2) | Used to set the client's basic voice settings, scoped to the current application | `rpc.local` |
| [SET_ACTIVITY](#set-activity) ^2^ | Used to update a user's rich presence | `rpc`, `rpc.activities.write`, or `rpc.local` |
| [SEND_ACTIVITY_JOIN_INVITE](#send-activity-join-invite) | Used to send an invite to another user to an activity | `rpc` or `rpc.local` |
| [CLOSE_ACTIVITY_JOIN_REQUEST](#close-activity-join-request) | Used to reject a rich presence Ask to Join request | `rpc` or `rpc.local` |
| [ACTIVITY_INVITE_USER](#activity-invite-user) | Used to send an invite to another user for an activity | `rpc` or `rpc.local` |
| [ACCEPT_ACTIVITY_INVITE](#accept-activity-invite) | Used to accept an activity invite | `rpc` or `rpc.local` |
| [OPEN_INVITE_DIALOG](#open-invite-dialog) | Used to open the invite modal | `rpc`, `rpc.local`, or `rpc.authenticated` |
| [OPEN_SHARE_MOMENT_DIALOG](#open-share-moment-dialog) | Used to share an image from an embedded activity in recent DMs or channels | `rpc.authenticated` |
| [SHARE_INTERASHARE_LINKCTION](#share-interaction) | Used to present a modal to user asking where a pre-defined slash command should be ran | `rpc.authenticated` or `rpc.local` |
| [INITIATE_IMAGE_UPLOAD](#initiate-image-upload) | Used to open a file dialog and retrieve a user-provided image | `rpc`, `rpc.local`, or `rpc.authenticated` |
| [SHARE_LINK](#share-link) | Used to open the share message modal, where a user can pick a channel to send a developer-defined message to | `rpc.authenticated` |
| [DEEP_LINK](#deep-link) | Used to navigates to a route in the Discord client | `rpc.local` or `rpc.private` |
| [CONNECTIONS_CALLBACK](#connections-callback) | Callback for connections authorization, part of connections flow v2 | `rpc.private` |
| [BILLING_POPUP_BRIDGE_CALLBACK](#billing-popup-bridge-callback) | Callback for payment methods like PaySafeCard, Klarna, Przelewy24, etc | `rpc.private` |
| [GIFT_CODE_BROWSER](#gift-code-browser) | Used to open a given gift code link in the client | `rpc.private` |
| [GUILD_TEMPLATE_BROWSER](#guild-template-browser) | Used to open a given template link in the client | `rpc.private` |
| [OPEN_MESSAGE](#open-message) | Used to open a specific message or DM in the client | `rpc.local` |
| OVERLAY | Used by the game overlay to communicate back to the client | `rpc.private` |
| [BROWSER_HANDOFF](#browser-handoff) | Used to signal the end of browser handoff | `rpc.private.limited` |
| [SET_CERTIFIED_DEVICES](#set-certified-devices) | Used to send info about certified hardware devices | `rpc` or `rpc.local` |
| [GET_IMAGE](#get-image) | Used to retrieve a user's profile picture | `rpc.local` |
| [SET_OVERLAY_LOCKED](#set-overlay-locked) | Used to set whether the process overlay input is locked | `rpc.local` |
| [OPEN_OVERLAY_ACTIVITY_INVITE](#open-overlay-activity-invite) | Used to open the activity invite modal in the process overlay | `rpc.local` |
| [OPEN_OVERLAY_GUILD_INVITE](#open-overlay-guild-invite) | Used to open an invite modal in the process overlay | `rpc.local` |
| [OPEN_OVERLAY_VOICE_SETTINGS](#open-overlay-voice-settings) | Used to open a voice settings modal in the process overlay | `rpc.local` |
| [VALIDATE_APPLICATION](#validate-application) | Used to validate the application entitlement | `rpc.local` |
| [GET_ENTITLEMENT_TICKET](#get-entitlement-ticket) | Used to retrieve an entitlement ticket | `rpc.local` |
| [GET_APPLICATION_TICKET](#get-application-ticket) | Used to retrieve an application ticket | `rpc.local` |
| [START_PURCHASE](#start-purchase) | Used to retrieve the purchase flow for a specific SKU | `rpc.authenticated` or `rpc.local` |
| [START_PREMIUM_PURCHASE](#start-premium-purchase) | Used to initiate a premium subscription purchase | `rpc.authenticated` or `rpc.local` |
| [GET_SKUS](#get-skus) | Used to retrieve a list of purchasable SKUs | `rpc.authenticated` or `rpc.local` |
| [GET_ENTITLEMENTS](#get-entitlements) | Used to retrieve a list of entitlements for the current user | `rpc.authenticated` or `rpc.local` |
| [GET_SKUS_EMBEDDED](#get-skus-embedded) | Used to retrieve a list of purchasable SKUs in an embedded context | `rpc.authenticated` or `rpc.local` |
| [GET_ENTITLEMENTS_EMBEDDED](#get-entitlements-embedded) | Used to retrieve a list of entitlements for the current user in an embedded context | `rpc.authenticated` or `rpc.local` |
| [GET_NETWORKING_CONFIG](#get-networking-config) **(deprecated)** | Used by the GameSDK to retrieve a proxy address and networking token | `rpc.local` |
| [NETWORKING_SYSTEM_METRICS](#networking-system-metrics) **(deprecated)** | Used by the GameSDK to send networking system metrics | `rpc.local` |
| [NETWORKING_PEER_METRICS](#networking-peer-metrics) **(deprecated)** | Used by the GameSDK to send networking peer metrics | `rpc.local` |
| [NETWORKING_CREATE_TOKEN](#networking-create-token) **(deprecated)** | Used by the GameSDK to retrieve a networking token | `rpc.local` |
| [USER_SETTINGS_GET_LOCALE](#user-settings-get-locale) | Used to retrieve the client’s locale | `identify` |
| [SEND_ANALYTICS_EVENT](#send-analytics-event) | Used to send an embedded activity analytics event to Discord | |
| [OPEN_EXTERNAL_LINK](#open-external-link) | Used to prompt to open a given URL in the default web browser | `rpc.authenticated` or `rpc.embedded_app` |
| [CAPTURE_LOG](#capture-log) | Used to capture logs into the Discord client devtools | |
| [ENCOURAGE_HW_ACCELERATION](#encourage-hw-acceleration) | Used to open a modal dialog encouraging hardware acceleration | |
| [SET_ORIENTATION_LOCK_STATE](#set-orientation-lock-state) | Used to set options for orientation and picture-in-picture (PiP) modes | |
| [GET_PLATFORM_BEHAVIORS](#get-platform-behaviors) | Used to retrieve platform-specific behaviors | |
| [GET_SOUNDBOARD_SOUNDS](#get-soundboard-sounds) | Used to retrieve available soundboard sounds | `rpc` or `rpc.local` |
| [PLAY_SOUNDBOARD_SOUND](#play-soundboard-sound) | Used to play a soundboard sound | `rpc` and `rpc.voice.write` |
| [TOGGLE_VIDEO](#toggle-video) | Used to toggle video in a call | `rpc` and `rpc.video.write` |
| [TOGGLE_SCREENSHARE](#toggle-screenshare) | Used to toggle screensharing | `rpc` and `rpc.screenshare.write` |
| [GET_ACTIVITY_INSTANCE_CONNECTED_PARTICIPANTS](#get-activity-instance-connected-participants) | Used to retrieve users connected to a specific activity session | `rpc.authenticated` |
| [GET_PROVIDER_ACCESS_TOKEN](#get-provider-access-token) | Used by the Amazon Music activity to authorize the connection and retrieve the access token | `rpc.authenticated` |
| [MAYBE_GET_PROVIDER_ACCESS_TOKEN](#maybe-get-provider-access-token) | Used by the Amazon Music activity to attempt to get the access token from existing connection | `rpc.authenticated` |
| [NAVIGATE_TO_CONNECTIONS](#navigate-to-connections) | Used to open the connections page in settings | `rpc.authenticated` |
| [INVITE_USER_EMBEDDED](#invite-user-embedded) | Used to invite a user to the current embedded activity | `relationships.read` |
| [INVITE_BROWSER](#invite-browser) | Used to open an invite modal in the client | `rpc.private` |
| [REQUEST_PROXY_TICKET_REFRESH](#request-proxy-ticket-refresh) | Used to refresh proxy tickets | `rpc.authenticated` |
| [GET_QUEST_ENROLLMENT_STATUS](#get-quest-enrollment-status) | Used to retrieve the enrollment status for a quest | `identify` |
| [QUEST_START_TIMER](#quest-start-timer) | Used to start the timer for a quest | `identify` |
^1^ If retrieving a private channel, also requires the `rpc` or `dm_channels.read` scope.
^2^ Not available from `http` transport.
#### Authorize
Used to authorize the current client with your application.
###### Authorize Arguments Structure
| Field | Type | Description |
| ---------------------- | ------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| client_id | snowflake | The ID of the application |
| response_type? ^1^ | string | The [type of response to return](/topics/oauth2#response-type) (must be `code`) |
| redirect_uri? ^2^ ^3^ | string | The URL to redirect to after authorization; must match one of the registered redirect URIs for the application |
| scopes? | array[string] | A list of scopes to request; may be omitted if the application has a populated [`integration_types_config`](/resources/application#application-object) |
| code_challenge? | string | A code challenge for the [PKCE extension](/topics/oauth2#pkce) to the authorization code grant; must be used with `code_challenge_method` |
| code_challenge_method? | string | The method used to generate the code challenge (must be `S256`); only applicable for the [PKCE extension](/topics/oauth2#pkce) to the authorization code grant |
| state? | string | A unique string to bind the user's request to their authenticated state |
| nonce? | string | A unique string to bind the user's request to their authenticated state; only applicable for authorization code grants with the `openid` scope |
| permissions? ^1^ | string | The [permissions](/topics/permissions) you're requesting; only applicable when `scope` contains `bot` |
| guild_id? | snowflake | The ID of a guild to pre-fill the dropdown picker with; only applicable when `scope` contains `bot`, `applications.commands`, or `webhook.incoming` and `integration_type` is `GUILD_INSTALL` |
| channel_id? | snowflake | The ID of a channel to pre-fill the dropdown picker with; only applicable when `scope` contains `webhook.incoming` |
| prompt? | string | The [prompt behavior](/topics/oauth2#prompt-behavior) to use for the authorization flow (default `consent`) |
| disable_guild_select? | boolean | Disallows the user from changing the guild dropdown; only applicable when `scope` contains `bot` or `applications.commands`, or `webhook.incoming` and `integration_type` is `GUILD_INSTALL` (default false) |
| integration_type? | integer | The [installation context](/resources/application#application-integration-type) for the authorization; only applicable when `scope` contains `applications.commands` (default `GUILD_INSTALL`) |
| pid? | integer | The ID of the process to overlay the OAuth2 flow in |
^1^ Required unless the basic [bot authorization flow](/topics/oauth2#bot-authorization-flow) is used.
^2^ If a `response_type` is specified and no `redirect_uri` is specified, the user will be redirected to the first registered redirect URI for the application.
^3^ Only applicable if using the `ws` transport.
###### Authorize Response Structure
| Field | Type | Description |
| ----- | ------ | ---------------------------------------------- |
| code | string | The authorization code to exchange for a token |
#### Authenticate
Used to authenticate an existing client with your app.
###### Authenticate Arguments Structure
| Field | Type | Description |
| ------------ | ------ | ---------------- |
| access_token | string | The access token |
###### Authenticate Response Structure
This structure is a superset of the [Get Current Authorization Information](/topics/oauth2#get-current-authorization-information) response with the following additional fields:
| Field | Type | Description |
| ------------ | ------ | ---------------- |
| access_token | string | The access token |
#### Subscribe
Used to subscribe to an RPC event. Accepts event subscription arguments. The outer `evt` field is used as the event name to subscribe to.
###### Subscribe Response Structure
| Field | Type | Description |
| ----- | ------ | -------------- |
| evt | string | The event name |
#### Unsubscribe
Used to unsubscribe from an RPC event. Accepts event subscription arguments. The outer `evt` field is used as the event name to unsubscribe from.
###### Unsubscribe Response Structure
| Field | Type | Description |
| ----- | ------ | -------------- |
| evt | string | The event name |
#### Get Guild
Used to retrieve guild information from the client. Responds with an [RPC guild](#rpc-guild-object) object.
###### Get Guild Arguments Structure
| Field | Type | Description |
| -------- | --------- | ----------------------------------- |
| guild_id | snowflake | The ID of the guild |
| timeout | integer | Request timeout in seconds (max 60) |
#### Get Guilds
Used to retrieve a list of guilds from the client. Responds with a list of [RPC guild](#rpc-guild-object) objects.
#### Get Channel
Used to retrieve channel information from the client. Responds with an [RPC channel](#rpc-channel-object) object.
###### Get Channel Arguments Structure
| Field | Type | Description |
| ---------- | --------- | --------------------- |
| channel_id | snowflake | The ID of the channel |
#### Get Channels
Used to retrieve a list of channels for a guild from the client.
###### Get Channels Arguments Structure
| Field | Type | Description |
| -------- | --------- | ------------------- |
| guild_id | snowflake | The ID of the guild |
###### Get Channels Response Structure
| Field | Type | Description |
| -------- | ------------------------------------------------------------------- | --------------------- |
| channels | array[partial [RPC channel](#partial-rpc-channel-structure) object] | Channels in the guild |
#### Get Channel Permissions
Used to retrieve the permission settings for the currently connected voice channel.
###### Get Channel Permissions Response Structure
| Field | Type | Description |
| ----------- | ------ | ---------------------------------------------------------------------------------------- |
| permissions | string | Computed permissions for the current user in the connected channel, including overwrites |
#### Create Channel Invite
Used to create an invite link for a given channel. Responds with a [invite](/resources/invite#invite-object) object (with [invite metadata](/resources/invite#invite-metadata-object)).
###### Create Channel Invite Arguments Structure
| Field | Type | Description |
| ---------- | --------- | ------------------------------------------ |
| channel_id | snowflake | The ID of the channel to create invite for |
#### Get Relationships
Used to retrieve the friend list and relationship statuses.
###### Get Relationships Response Structure
| Field | Type | Description |
| ------------- | ---------------------------------------------------------- | ----------------- |
| relationships | array[[RPC relationship](#rpc-relationship-object) object] | The relationships |
#### Get User
Used to retrieve information about a specific user. Responds with an [RPC user](#rpc-user-object) object or `null`.
#### Set User Voice Settings
Used to change voice settings of users in a voice channel. Responds with the resolved settings.
###### Set User Voice Settings Arguments Structure
| Field | Type | Description |
| ------- | ---------------------------- | ----------------------------- |
| user_id | snowflake | The ID of the user |
| pan? | [pan](#pan-structure) object | The pan of the user |
| volume? | integer | The volume percentage (0-200) |
| mute? | boolean | Whether the user is muted |
#### Set User Voice Settings 2
Used to change voice settings of users in a voice channel, scoped to the current application. Responds with `null`.
###### Set User Voice Settings Arguments Structure
| Field | Type | Description |
| ------- | --------- | ----------------------------- |
| user_id | snowflake | The ID of the user |
| volume? | integer | The volume percentage (0-200) |
| mute? | boolean | Whether the user is muted |
#### Push To Talk
Used to enable or disable push-to-talk functionality. Responds with `null`.
###### Push To Talk Arguments Structure
| Field | Type | Description |
| ------ | ------- | --------------------------------------------------- |
| active | boolean | Whether Push To Talk functionality should be active |
#### Select Voice Channel
Used to join or leave a voice channel, group DM, or DM. Responds with an [RPC channel](#rpc-channel-object) object or `null`.
###### Select Voice Channel Arguments Structure
| Field | Type | Description |
| ---------- | ---------- | ---------------------------------------------------------------- |
| channel_id | ?snowflake | The ID of the voice channel to connect to (`null` to disconnect) |
| timeout? | integer | Request timeout in seconds (max 60) |
| force? | boolean | Whether to forcefully connect to voice channel (default false) |
| navigate? | boolean | Whether to navigate to the voice channel (deafult false) |
#### Get Selected Voice Channel
Used to get the current voice channel the client is in. Responds with an [RPC channel](#rpc-channel-object) object or `null`.
#### Select Text Channel
Used to join or leave a text channel, group DM, or DM. Responds with an [RPC channel](#rpc-channel-object) object or `null`.
###### Select Text Channel Arguments Structure
| Field | Type | Description |
| ---------- | ---------- | ------------------------------------------------------------------------------------ |
| channel_id | ?snowflake | The ID of the text channel to navigate to (`null` to navigate to the "Friends" page) |
| timeout? | integer | Request timeout in seconds (max 60) |
#### Get Voice Settings
Used to retrieve the client's voice settings. Responds with an [RPC voice settings](#rpc-voice-settings-object) object.
#### Set Voice Settings
Used to set the client's voice settings. Responds with an [RPC voice settings](#rpc-voice-settings-object) object.
###### Set Voice Settings Arguments Structure
| Field | Type | Description |
| ----------------------- | -------------------------------------------------------------------- | --------------------------------------------------- |
| input? | [RPC voice IO settings](#rpc-voice-io-settings-structure) object | The input settings |
| output? | [RPC voice IO settings](#rpc-voice-io-settings-structure) object | The output settings |
| mode? | [RPC voice settings mode](#rpc-voice-settings-mode-structure) object | The voice mode settings |
| automatic_gain_control? | boolean | Whether automatic gain control is enabled |
| echo_cancellation? | boolean | Whether echo cancellation is enabled |
| noise_suppression? | boolean | Whether the background noise suppression is enabled |
| qos? | boolean | Whether voice Quality of Service is enabled |
| silence_warning? | boolean | Whether the silence warning notice is displayed |
| deaf? | boolean | Whether the user is locally deafened |
| mute? | boolean | Whether the user is locally muted |
###### Partial RPC Voice Settings Mode Structure
| Field | Type | Description |
| --------------- | ------------------------------------------------------------------------- | ---------------------------------------------------------------- |
| type? | string | The [type of voice settings mode](#rpc-voice-settings-mode-type) |
| auto_threshold? | boolean | Whether the voice activity threshold is automatically set |
| threshold? | integer | The threshold (in dB) for voice activity (-100-0) |
| shortcut? | array[partial [shortcut key combo](#shortcut-key-combo-structure) object] | The shortcut key combos for PTT |
| delay? | integer | The PTT release delay in milliseconds (max 2000) |
#### Set Voice Settings 2
Used to set the client's voice settings, scoped to the current application. Responds with `null`.
###### Set Voice Settings 2 Arguments Structure
| Field | Type | Description |
| ----------- | -------------------------------------------------------------- | ------------------------------------ |
| input_mode? | [RPC voice input mode](#rpc-voice-input-mode-structure) object | The input mode |
| self_mute? | boolean | Whether the user is locally muted |
| self_deaf? | boolean | Whether the user is locally deafened |
###### RPC Voice Input Mode Structure
| Field | Type | Description |
| -------- | ------ | ---------------------------------------------------------------- |
| type | string | The [type of voice settings mode](#rpc-voice-settings-mode-type) |
| shortcut | string | The shortcut key combos for PTT |
#### Set Activity
Used to update a user's rich presence. Responds with an [activity](/resources/presence#activity-object) object.
###### Set Activity Arguments Structure
| Field | Type | Description |
| -------- | ----------------------------------------------- | -------------------------------------------------------------------- |
| pid? ^1^ | integer | The ID of the OS process that is sending the presence update request |
| activity | ?[RPC activity](#rpc-activity-structure) object | The activity to set |
^1^ Only required for the `ipc` transport.
###### RPC Activity Structure
| Field | Type | Description |
| -------------------- | ------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------- |
| name | string | The name of the activity (1-128 characters) |
| state? | ?string | The user's current party status (2-128 characters) |
| state_url? | ?string | URL that is opened when clicking on the state text (max 256 characters) |
| details? | ?string | What the user is currently doing (2-128 characters) |
| details_url? | ?string | URL that is opened when clicking on the details text (max 256 characters) |
| timestamps? | [activity timestamps](/resources/presence#activity-timestamps-structure) object | Unix timestamps (in milliseconds) for start and/or end of the game |
| assets? | [activity assets](/resources/presence#activity-assets-structure) object | Images for the presence and their hover texts |
| party? | [RPC activity party](#rpc-activity-party-structure) object | Information for the current party of the user |
| secrets? | [activity secrets](/resources/presence#activity-secrets-structure) object | Secrets for rich presence joining and spectating |
| buttons? | array[[RPC activity button](#rpc-activity-button-structure) object] | Custom buttons shown in rich presence (1-2) |
| instance? | boolean | Whether the activity is an instanced game session (a match that will end) |
| supported_platforms? | array[string] | The [platforms](/resources/presence#activity-platform-type) the activity is supported on (max 10) |
| type | integer | The [activity type](/resources/presence#activity-type) (except `STREAMING`, `CUSTOM`, and `HANG`) |
| status_display_type? | ?integer | [Which field is displayed](/resources/presence#status-display-type) in the user's status text in the member list |
###### RPC Activity Party Structure
| Field | Type | Description |
| -------- | ----------------------- | ---------------------------------------------------------------------------- |
| id? | string | The ID of the party (min 2, max 128 characters) |
| size? | array[integer, integer] | The party's current and maximum size (current_size, max_size) |
| privacy? | integer | The [privacy of activity party](#activity-party-privacy) (default `PRIVATE`) |
###### Activity Party Privacy
| Value | Name | Description |
| ----- | ------- | -------------------- |
| 0 | PRIVATE | The party is private |
| 1 | PUBLIC | The party is public |
###### RPC Activity Button Structure
| Field | Type | Description |
| ----- | ------ | ----------------------------------------------------------------------- |
| label | string | The label of the custom button (1-32 characters) |
| url | string | URL that is opened when clicking on the button label (1-512 characters) |
#### Send Activity Join Invite
Used to send an invite to another user for an activity. Responds with `null`.
###### Send Activity Join Invite Arguments Structure
| Field | Type | Description |
| ------- | --------- | ------------------------------------------------------------ |
| user_id | snowflake | The ID of the user to send the activity invite to |
| pid | integer | The ID of the OS process that is sending the activity invite |
#### Close Activity Join Request
Used to reject a rich presence Ask to Join request. Responds with `null`.
###### Close Activity Join Request Arguments Structure
| Field | Type | Description |
| ------- | --------- | --------------------------------------------- |
| user_id | snowflake | The ID of the user to reject the request from |
#### Activity Invite User
Used to send an invite to another user for an activity. Responds with `null`.
###### Send Activity Join Invite Arguments Structure
| Field | Type | Description |
| -------- | --------- | ------------------------------------------------------------------------------------------------- |
| user_id | snowflake | The ID of the user to send the activity invite to |
| type | integer | The [type of activity request](/resources/presence#activity-action-type) (only `JOIN` is allowed) |
| content? | string | The message contents (max 1024 characters) |
| pid | integer | The ID of the OS process that is sending the activity invite |
#### Accept Activity Invite
Used to accept an activity invite. Responds with `null`.
###### Accept Activity Invite Arguments Structure
| Field | Type | Description |
| --------------- | --------- | ------------------------------------------------------------------------------------------------- |
| type | integer | The [type of activity request](/resources/presence#activity-action-type) (only `JOIN` is allowed) |
| user_id | snowflake | The ID of the user to accept the activity invite from |
| session_id | string | The ID of the Gateway session of the activity invite |
| channel_id | snowflake | The ID of the channel the activity invite message was sent in |
| message_id | snowflake | The ID of the message |
| application_id? | snowflake | The ID of the application |
#### Open Invite Dialog
Used to present a modal to invite other users to the current embedded activity. Responds with `null`.
#### Open Share Moment Dialog
Used to share an image from an embedded activity in recent DMs or channels. Responds with `null`.
The application must have the [`EMBEDDED`](/resources/application#application-flags) flag.
###### Open Share Moment Dialog Arguments Structure
| Field | Type | Description |
| -------- | ------ | ---------------------------------------------------- |
| mediaUrl | string | The Discord CDN URL of the image to share (max 1024) |
#### Share Interaction
Used by embedded activities to present a modal to user asking where a pre-defined slash command should be ran.
The `content`, `preview_image`, and `components` fields are used within the modal as a command response preview.
This command is meant to be used by the 12 Bullets to Midnight application only. Because of this, it is locked to the game application IDs (`1276239071764680926` and `1257458870390099989`).
###### Share Interaction Arguments Structure
| Field | Type | Description |
| ----------------------- | ------------------------------------------------------------------------------------------ | ----------------------------------------------------------------------------------------- |
| command | string | The name of the application command |
| options? | array[[interaction option](#interaction-option-structure) object] | The pre-defined options for the slash command |
| content? | string | The modal preview's content (max 2000) |
| require_launch_channel? | boolean | Whether to require that the current user should be participating in the embedded activity |
| preview_image? | [interaction response preview image](#interaction-response-preview-image-structure) object | The modal preview's image |
| components? ^1^ | array[[action row](/resources/components#action-row) object] | The modal preview's components |
| pid? | integer | The ID of the OS process to overlay the modal in |
^1^ Only action rows are permitted. Only buttons are permitted inside action rows. The buttons can have only `type`, `style`, `label`, and `custom_id`. [`PREMIUM`](/resources/components#button-style) buttons are not permitted. The components can't have `id` field set.
###### Interaction Option Structure
| Field | Type | Description |
| ----- | ------ | ----------------------- |
| name | string | The name of the option |
| value | string | The value of the option |
###### Interaction Response Preview Image Structure
| Field | Type | Description |
| ------ | ------- | ----------------------- |
| height | integer | The height of the image |
| url | string | The URL of the image |
| width | integer | The width of the image |
###### Share Interaction Response Structure
| Field | Type | Description |
| ------- | ------- | -------------------------------------------------------- |
| success | boolean | Whether the slash command was successfully ran somewhere |
#### Initiate Image Upload
Used by embedded activities to open a file dialog and retrieve a user-provided image.
###### Initiate Image Upload Response Structure
| Field | Type | Description |
| --------- | ------ | ---------------------------------------------- |
| image_url | string | The Discord CDN URL of the user-provided image |
#### Share Link
Used to open the share message modal, where a user can pick a channel to send a developer-defined message to.
The application must have the [`EMBEDDED`](/resources/application#application-flags) flag.
###### Share Link Arguments Structure
| Field | Type | Description |
| ---------- | ------ | ------------------------------------------------------------- |
| custom_id? | string | Developer-defined identifier for the link (max 64 characters) |
| message | string | The message's content (max 1000 characters) |
| link_id? | string | The ID of the link (max 64 characters) |
###### Share Link Response Structure
| Field | Type | Description |
| -------------- | ------- | ---------------------------------------- |
| success | boolean | Whether the link was successfully shared |
| didCopyLink | boolean | Whether the user copied the link |
| didSendMessage | boolean | Whether the user sent a message |
#### Deep Link
Used to navigate to a route in the Discord client.
###### Deep Link Arguments Structure
| Field | Type | Description |
| ------ | ------------------------------------------------------ | ---------------------------------------- |
| type | string | The [type of deep link](#deep-link-type) |
| params | [deep link params](#deep-link-params-structure) object | The deep link parameters |
###### Deep Link Type
| Value | Description |
| ---------------------- | ------------------------- |
| USER_SETTINGS | User settings |
| CHANGELOG | Changelog entry |
| LIBRARY | Game library |
| STORE_HOME | Premium subscription home |
| STORE_LISTING | Store listing |
| CHANNEL | Channel |
| GAME_SHOP | Game shop |
| PICK_GUILD_SETTINGS | Guild settings |
| QUEST_HOME | Quest home |
| DISCOVERY_GAME_RESULTS | Game discovery results |
| OAUTH2 | OAuth2 |
| FEATURES | Any path |
| SHOP | Shop |
| ACTIVITIES | Embedded activities |
| QUEST_PREVIEW_TOOL | Quest preview tool |
| ONE_TIME_LOGIN | One time login |
###### Deep Link Params Structure
| Field | Type | Description | Applicable for |
| -------------- | --------- | -------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| section? | string | The section | `USER_SETTINGS`, `PICK_GUILD_SETTINGS` |
| subsection? | string | The subsection | `USER_SETTINGS`, `PICK_GUILD_SETTINGS` |
| search? | string | The search query | `USER_SETTINGS`, `PICK_GUILD_SETTINGS`, `CHANNEL`, `OAUTH2`, `SHOP` |
| fingerprint? | ?string | The fingerprint | `USER_SETTINGS`, `CHANGELOG`, `LIBRARY`, `STORE_HOME`, `STORE_LISTING`, `CHANNEL`, `GAME_SHOP`, `PICK_GUILD_SETTINGS`, `QUEST_HOME`, `DISCOVERY_GAME_RESULTS`, `ACTIVITIES`, `QUEST_PREVIEW_TOOL`, `ONE_TIME_LOGIN` |
| date? | string | The changelog entry date | `CHANGELOG` |
| query? | string | The query | `CHANGELOG` |
| skuId? | snowflake | The ID of the SKU | `STORE_LISTING`, `GAME_SHOP` |
| slug? | string | The slug of the SKU | `STORE_LISTING`, `GAME_SHOP` |
| guildId? ^1^ | snowflake | The ID of the channel guild | `CHANNEL`, `GAME_SHOP` |
| channelId? | snowflake | The ID of the channel the message was sent in | `CHANNEL` |
| messageId? | snowflake | The ID of the message to navigate to | `CHANNEL` |
| pageIndex? | integer | The page index | `GAME_SHOP` |
| sort? | string | The [field to sort quests by](#quest-home-sort-type) | `QUEST_HOME` |
| filter? | string | The [types](#quest-home-filter-type) to filter quests by | `QUEST_HOME` |
| tab? | string | The [quest home tab](#quest-home-tab) (default `all`) | `QUEST_HOME` |
| questId? | snowflake | The ID of the quest | `QUEST_HOME`, `QUEST_PREVIEW_TOOL` |
| gameId? | snowflake | The ID of the game application | `DISCOVERY_GAME_RESULTS` |
| token? | string | The authentication token | `ONE_TIME_LOGIN` |
| path? | string | The path to navigate to | `FEATURES` |
| attemptId? | string | The ID of the attempt | `ACTIVITIES` |
| applicationId? | snowflake | The ID of the embedded activity application | `ACTIVITIES` |
| url? | string | The embedded activity URL | `ACTIVITIES` |
^1^ A special value of `@me` is used to indicate private channels.
###### Quest Home Sort Type
| Value | Description |
| ----------------- | ----------------------------- |
| suggested | Sort by interest |
| most_recent | Sort by quest creation date |
| expiring_soon | Sort by quest expiration date |
| recently_enrolled | Sort by quest enrollment date |
###### Quest Home Filter Type
| Value | Description |
| ----------------------- | --------------------------------------------------------------------------------------------------------------------------------------- |
| reward_virtual_currency | Quest must have reward of type [`VIRTUAL_CURRENCY`](/resources/quests#quest-reward-type) |
| reward_collectible | Quest must have reward of type [`COLLECTIBLE`](/resources/quests#quest-reward-type) |
| reward_in_game | Quest must have reward of type [`REWARD_CODE`, or `IN_GAME`](/resources/quests#quest-reward-type) |
| task_play | Quest must have [`PLAY_ON_DESKTOP`, `PLAY_ON_XBOX`, `PLAY_ON_PLAYSTATION`, or `PLAY_ACTIVITY`](/resources/quests#quest-task-type) tasks |
| task_video | Quest must have [`WATCH_VIDEO`, or `WATCH_VIDEO_ON_MOBILE`](/resources/quests#quest-task-type) tasks |
###### Quest Home Tab
| Value | Description |
| ------- | -------------- |
| all | All quests |
| claimed | Claimed quests |
#### Connections Callback
Used to send the next part of connection flow to the client. Responds with `null`.
###### Connections Callback Arguments Structure
| Field | Type | Description |
| -------------- | ------ | ----------------------------------------------------------------------- |
| providerType | string | The [type of connection](/resources/connected-accounts#connection-type) |
| code | string | The authorization code for the connection |
| openid_params? | object | Additional parameters for OpenID Connect |
| iss? | string | The issuer |
| state | string | The state used to authorize the connection |
#### Billing Popup Bridge Callback
Used as callback for payment methods like PaySafeCard, Klarna, Przelewy24, and other payment providers.
###### Billing Popup Bridge Callback Arguments Structure
| Field | Type | Description |
| ------------------- | ------------------- | -------------------------------------------------------------------- |
| state | string | The unique identifier for the request flow |
| path | string | The redirect API path |
| query? | map[string, string] | Redirect query parameters |
| payment_source_type | integer | The type of [payment source](/resources/billing#payment-source-type) |
###### Billing Popup Bridge Callback Response Structure
| Field | Type | Description |
| ------- | ------------------- | --------------------------------------------- |
| ok | boolean | Whether the HTTP response is successful |
| headers | map[string, string] | The headers of the HTTP response |
| body | ?any | The body of the HTTP response, parsed as JSON |
| text | string | The body of the HTTP response, in text format |
| status | integer | The status of the HTTP response |
#### Gift Code Browser
Used to open a given gift code link in the client.
###### Gift Code Browser Arguments Structure
| Field | Type | Description |
| ----- | ------ | --------------------- |
| code | string | The gift code to open |
###### Gift Code Browser Response Structure
| Field | Type | Description |
| -------- | ------------------------------------------------------------- | ------------- |
| giftCode | [gift code](/resources/entitlement#entitlement-object) object | The gift code |
#### Guild Template Browser
Used to open a given template link in the client.
###### Guild Template Browser Arguments Structure
| Field | Type | Description |
| ----- | ------ | ------------------------ |
| code | string | The code of the template |
###### Guild Template Browser Response Structure
| Field | Type | Description |
| ------------- | ------------------------------------------------------- | ------------------------ |
| guildTemplate | [RPC guild template](#rpc-guild-template-object) object | The guild template |
| code | string | The code of the template |
#### Open Message
Used to open a specific message or DM in the client. Responds with `null`.
###### Open Message Arguments Structure
| Field | Type | Description |
| ---------- | ---------- | ---------------------------------------------------------------------------------- |
| guild_id? | ?snowflake | The ID of the guild |
| channel_id | snowflake | The ID of the channel |
| message_id | snowflake | The ID of the message |
| pid | integer | The ID of the OS process opening the message (used to open message within overlay) |
#### Browser Handoff
Used to end browser handoff. Responds with `null`.
###### Browser Handoff Arguments Structure
| Field | Type | Description |
| ------------ | ------ | --------------------------------------------------------------------------------------------------------- |
| handoffToken | string | The handoff token received from the [Create Handoff Token](/authentication#create-handoff-token) endpoint |
| fingerprint | string | The current [fingerprint](/topics/experiments#fingerprints) |
#### Set Certified Devices
Used to send info about certified hardware devices. Responds with `null`.
###### Set Certified Devices Arguments Structure
| Field | Type | Description |
| ------- | ---------------------------------------------------------- | --------------------- |
| devices | array[[certified device](#certified-device-object) object] | The certified devices |
#### Get Image
Used to fetch a user's profile picture.
###### Get Image Arguments Structure
| Field | Type | Description |
| ------ | --------- | -------------------------------------------------------------------------------------------------------------------------- |
| type | string | The [type of image](#image-type) |
| id | snowflake | The ID of the user |
| format | string | The format to retrieve image in (only `png`, `webp` and `jpg` are allowed) |
| size | integer | The size of the image to return (if omitted, a default size is used); the size can be any power of two between 16 and 1024 |
###### Image Type
| Value | Description |
| ----- | -------------------------- |
| user | The image is user's avatar |
###### Get Image Response Structure
| Field | Type | Description |
| -------- | ------ | ------------------------------------------------------------------- |
| data_url | string | The [image data URI](https://en.wikipedia.org/wiki/Data_URI_scheme) |
#### Set Overlay Locked
Used to set whether the overlay input is locked. Responds with `null`.
###### Set Overlay Locked Arguments Structure
| Field | Type | Description |
| ------ | ------- | ------------------------------------------------------------- |
| locked | boolean | Whether the overlay input should be locked |
| pid | integer | The ID of the OS process where the Discord overlay is running |
#### Open Overlay Activity Invite
Used to open the activity invite modal in the process' overlay. The activity set via [`SET_ACTIVITY`](#set-activity) command must have party and join secret. Responds with `null`.
###### Open Overlay Activity Invite Arguments Structure
| Field | Type | Description |
| ----- | ------- | ------------------------------------------------------------------------------------------------- |
| type | integer | The [type of activity request](/resources/presence#activity-action-type) (only `JOIN` is allowed) |
| pid | integer | The ID of the OS process where the Discord overlay is running |
#### Open Overlay Guild Invite
Used to open the invite modal in the process' overlay.
###### Open Overlay Guild Invite Arguments Structure
| Field | Type | Description |
| ----- | ------- | -------------------------------------------------------------- |
| code | string | The invite code |
| pid | integer | The ID of the OS process to open the voice settings overlay in |
#### Open Overlay Voice Settings
Used to open a voice settings modal in the process' overlay.
###### Open Overlay Voice Settings Arguments Structure
| Field | Type | Description |
| ----- | ------- | -------------------------------------------------------------- |
| pid | integer | The ID of the OS process to open the voice settings overlay in |
#### Validate Application
Used to validate the application. Responds with `null` if the user has entitlement for primary application's SKU.
#### Get Entitlement Ticket
Used to retrieve the entitlement ticket for the current application.
###### Get Entitlement Ticket Response Structure
| Field | Type | Description |
| ------ | ------ | ----------- |
| ticket | string | The ticket |
#### Get Application Ticket
Used to retrieve the application ticket for the current application.
The ticket usually can be validated client-side with following pseudocode:
```py
import base64
import json
from nacl.signing import VerifyKey
from nacl.exceptions import BadSignatureError
# Your public key can be found on your application in the Developer Portal
PUBLIC_KEY = 'APPLICATION_PUBLIC_KEY'
SKU_ID = '12345678912345678912'
def validate_application_ticket(ticket: str, *, public_key: str) -> Optional[dict]:
verify_key = VerifyKey(public_key)
parts = ticket.split('.')
if len(parts) < 3:
# Not enough parts
return None
if parts[0] != '2':
# Invalid ticket version
return None
try:
signature = bytes.fromhex(parts[1])
except ValueError:
# Invalid ticket signature
return None
encoded_data = parts[2]
try:
verify_key.verify(encoded_data, signature)
except BadSignatureError:
# The ticket is tampered with
return None
data = json.loads(base64.decode(encoded_data))
return data
ticket = ''
validated = validate_application_ticket(ticket)
if validated is None:
print('The ticket is invalid')
else:
entitlements = validated['entitlements']
has_entitlement = any(entitlement['sku_id'] == SKU_ID for entitlement in entitlements)
if has_entitlements:
print('The ticket is valid and the player has entitlement')
else:
print('The ticket is valid, but the player does not have entitlement')
```
###### Get Application Ticket Response Structure
| Field | Type | Description |
| ------ | ------ | ----------- |
| ticket | string | The ticket |
#### Start Purchase
Used to launch the purchase flow for a specific SKU. Responds with a list of purchased [entitlement](/resources/entitlement#entitlement-object) objects.
###### Start Purchase Arguments Structure
| Field | Type | Description |
| ------ | --------- | --------------------------------------------------------- |
| sku_id | snowflake | The ID of the SKU to purchase |
| pid? | integer | The ID of the OS process to overlay the purchase modal in |
#### Start Premium Purchase
Used to initiate a premium subscription purchase.
###### Start Premium Purchase Arguments Structure
| Field | Type | Description |
| ----- | ------- | --------------------------------------------------------- |
| pid? | integer | The ID of the OS process to overlay the purchase modal in |
#### Get SKUs
Used to retrieve a list of your application's SKUs. Responds with a list of [SKU](/resources/store#sku-object) objects.
#### Get Entitlements
Used to retrieve a list of entitlements for the current user. Responds with a list of [entitlement](/resources/entitlement#entitlement-object) objects.
#### Get SKUs Embedded
Used to retrieve a list of your application's SKUs in an embedded context.
###### Get SKUs Embedded Response Structure
| Field | Type | Description |
| ----- | ------------------------------------------------ | --------------------------- |
| skus | array[[SKU](/resources/store#sku-object) object] | The SKUs of the application |
#### Get Entitlements Embedded
Used to retrieve a list of entitlements for the current user in an embedded context.
###### Get Entitlements Embedded Response Structure
| Field | Type | Description |
| ------------ | ---------------------------------------------------------------------- | ------------------------------------- |
| entitlements | array[[entitlement](/resources/entitlement#entitlement-object) object] | The entitlements for the current user |
#### Get Networking Config
Used by the GameSDK to retrieve a proxy address and networking token.
###### Get Networking Config Response Structure
| Field | Type | Description |
| ------- | ------ | -------------------- |
| address | string | The proxy address |
| token | string | The networking token |
#### Networking System Metrics
Used by the GameSDK to send networking system metrics. Accepts an object.
#### Networking Peer Metrics
Used by the GameSDK to send networking peer metrics. Accepts an object.
#### Networking Create Token
Used by the GameSDK to retrieve a networking token.
###### Networking Create Token Response Structure
| Field | Type | Description |
| ------- | ------ | -------------------- |
| address | string | The proxy address |
| token | string | The networking token |
#### User Settings Get Locale
Used to retrieves the client’s locale.
###### User Settings Get Locale Response Structure
| Field | Type | Description |
| ------ | ------ | ------------------------------------------------------------ |
| locale | string | The [language option](/reference#locales) chosen by the user |
#### Send Analytics Event
Used to send an analytics event to Discord via embedded activity. Responds with `null`.
The application must have the [`EMBEDDED_FIRST_PARTY`](/resources/application#application-flags) flag.
###### Send Analytics Event Arguments Structure
| Field | Type | Description |
| ---------------- | ------ | ------------------------------------- |
| event_name | string | The name of the analytics event |
| event_properties | object | The properties of the analytics event |
#### Open External Link
Used to prompt to open a given URL in the default web browser. Responds with `null`.
###### Open External Link Arguments Structure
| Field | Type | Description |
| ----- | ------ | ------------------------- |
| url | string | The URL to prompt to open |
#### Capture Log
Used to capture a log entry in the client's console. Responds with `null`.
###### Capture Log Arguments Structure
| Field | Type | Description |
| ------- | ------ | ------------------------------------ |
| level | string | The [level of log entry](#log-level) |
| message | string | The message to log |
###### Log Level
| Value | Description |
| ----- | ----------- |
| log | Normal |
| warn | Warning |
| debug | Verbose |
| info | Info |
| error | Error |
#### Encourage HW Acceleration
Used to encourage users to turn on hardware acceleration. Accepts an empty object. Responds with `null`.
#### Set Orientation Lock State
Used to set options for orientation and picture-in-picture (PiP) modes. Responds with `null`.
###### Set Orientation Lock State Arguments Structure
| Field | Type | Description |
| ------------------------------ | -------- | ----------------------------------------- |
| lock_state | integer | The [lock state](#orientation-state) |
| picture_in_picture_lock_state? | ?integer | The PiP [lock state](#orientation-state) |
| grid_lock_state? | ?integer | The grid [lock state](#orientation-state) |
#### Get Platform Behaviors
Used to retrieve platform-specific behaviors. Response is unstable and subject to change.
###### Get Platform Behaviors Response Structure
| Field | Type | Description |
| ----------------------- | ------- | -------------------------------------------- |
| iosKeyboardResizesView? | boolean | Whether the keyboard on iOS resizes the view |
#### Get Soundboard Sounds
Used to retrieve available soundboard sounds. Responds with a list of [soundboard sound](/resources/soundboard#soundboard-sound-object) objects.
Note that default sounds may have their `guild_id` set to `0`.
#### Play Soundboard Sound
Used to play a soundboard sound. Responds with `null`.
###### Play Soundboard Sound Arguments Structure
| Field | Type | Description |
| --------- | --------- | ---------------------------------------------------------------- |
| guild_id? | snowflake | The ID of the sound's source guild, if applicable (not required) |
| sound_id? | snowflake | The ID of the soundboard sound to play |
#### Toggle Video
Used to toggle video in a call. Responds with `null`.
#### Toggle Screenshare
Used to toggle screenshare in a call. Responds with `null`.
If process ID is not provided, this will present a screenshare modal.
###### Toggle Screenshare Arguments Structure
| Field | Type | Description |
| ----- | ------- | --------------------------------------------------- |
| pid? | integer | The ID of the OS process to start screensharing for |
#### Get Activity Instance Connected Participants
Used to retrieve users connected to a specific activity session.
###### Get Activity Instance Connected Participants Response Structure
| Field | Type | Description |
| ------------ | -------------------------------------------------------------------------- | ---------------------------------------------------------- |
| participants | array[[RPC activity participant](#rpc-activity-participant-object) object] | The users currently participating in the activity instance |
#### Get Provider Access Token
Used for the Amazon Music activity to authorize the connection and retrieve the access token.
If the user does not have connection for the provider, the Discord client will open a window to link the account to Discord.
This command is meant to be used by the Amazon Music integration only. Because of this, it is locked to the Amazon Music application IDs (`1214629548377768066` and `1234546995360694434`).
###### Get Provider Access Token Arguments Structure
| Field | Type | Description |
| -------------------- | ------ | ------------------------------------------------------------------------------------ |
| provider | string | The [type of connection](/resources/connected-accounts#connection-type) to authorize |
| connection_redirect? | string | The URL to redirect to |
###### Get Provider Access Token Response Structure
| Field | Type | Description |
| ------------ | ------ | ----------------------------- |
| access_token | string | The connection's access token |
#### Maybe Get Provider Access Token
Used for the Amazon Music activity to attempt to get the access token from existing connection.
This command is meant to be used by the Amazon Music integration only. Because of this, it is locked to the Amazon Music application IDs (`1214629548377768066` and `1234546995360694434`).
###### Maybe Get Provider Access Token Arguments Structure
| Field | Type | Description |
| -------- | ------ | ------------------------------------------------------------------------------------ |
| provider | string | The [type of connection](/resources/connected-accounts#connection-type) to authorize |
###### Maybe Get Provider Access Token Response Structure
| Field | Type | Description |
| ------------ | ------ | ----------------------------- |
| access_token | string | The connection's access token |
#### Navigate To Connections
Used for Amazon Music, opens the connections page in settings. Accepts an empty object. Responds with `null`.
This command is meant to be used by the Amazon Music integration only. Because of this, it is locked to the Amazon Music application IDs (`1214629548377768066` and `1234546995360694434`).
#### Invite User Embedded
Used to invite a user to the current embedded activity.
###### Invite User Embedded Arguments Structure
| Field | Type | Description |
| -------- | --------- | ------------------------------------------------ |
| user_id | snowflake | The ID of the user to send invite to |
| content? | string | The message's content along with activity invite |
#### Invite Browser
Used to open an invite modal for a guild invite in the client.
###### Invite Browser Arguments Structure
| Field | Type | Description |
| ----- | ------ | ------------------------------ |
| code | string | The code of the invite to open |
###### Invite Browser Response Structure
| Field | Type | Description |
| ------ | ------------------------------------------------ | --------------- |
| invite | [invite](/resources/invite#invite-object) object | The invite |
| code | string | The invite code |
#### Request Proxy Ticket Refresh
Used to refresh proxy tickets for the current embedded activity.
The application must have the [`EMBEDDED`](/resources/application#application-flags) flag.
###### Request Proxy Ticket Response Structure
| Field | Type | Description |
| ------ | ------ | ----------- |
| ticket | string | The ticket |
#### Get Quest Enrollment Status
Used to retrieve enrollment status for a quest.
###### Get Quest Enrollment Status Arguments Structure
| Field | Type | Description |
| -------- | --------- | ------------------- |
| quest_id | snowflake | The ID of the quest |
###### Get Quest Enrollment Status Response Structure
| Field | Type | Description |
| ----------- | ------------------ | --------------------------------------- |
| quest_id | snowflake | The ID of the quest |
| is_enrolled | boolean | Whether the user has accepted the quest |
| enrolled_at | ?ISO8601 timestamp | When the user accepted the quest |
#### Quest Start Timer
Used to start timer for a quest.
###### Quest Start Timer Arguments Structure
| Field | Type | Description |
| -------- | --------- | ------------------- |
| quest_id | snowflake | The ID of the quest |
###### Quest Start Timer Response Structure
| Field | Type | Description |
| ------- | ------- | ------------------------------------------ |
| success | boolean | Whether the timer was successfully started |
## RPC Events
Events are payloads sent over the socket to a client that correspond to events in Discord. Many of these mirror actual [Gateway events](/gateway/gateway-events), so check there for more details!
| Name | Description | Scopes |
| ------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------ | ------------------------------------------ |
| [READY](#ready) | Non-subscription event sent immediately after connecting, contains server information | |
| [ERROR](#error) | Non-subscription event sent when there is an error, including command responses | |
| [CURRENT_USER_UPDATE](#current-user-update) | Sent when current user updates | `rpc.local`, `identify` |
| [CURRENT_GUILD_MEMBER_UPDATE](#current-guild-member-update) | Sent when current user bound to a guild updates | `identify` and `guilds.members.read` |
| [GUILD_STATUS](#guild-status) | Sent when a subscribed guild's state changes | `rpc` |
| [GUILD_CREATE](#guild-create) | Sent when a guild is created/joined on the client | `rpc` |
| [CHANNEL_CREATE](#channel-create) | Sent when a channel is created/joined on the client | `rpc` |
| [RELATIONSHIP_UPDATE](#relationship-update) | Sent when a user's relationship updates | `relationships.read` |
| [VOICE_CHANNEL_SELECT](#voice-channel-select) | Sent when the client moves voice channels | `rpc` |
| [VOICE_STATE_CREATE](#voice-state-create) | Sent when a user joins a subscribed voice channel | `rpc` or `rpc.voice.read` |
| [VOICE_STATE_DELETE](#voice-state-delete) | Sent when a user parts a subscribed voice channel | `rpc` or `rpc.voice.read` |
| [VOICE_STATE_UPDATE](#voice-state-update) | Sent when a user's voice state changes in a subscribed voice channel (mute, volume, etc.) | `rpc` or `rpc.voice.read` |
| [VOICE_SETTINGS_UPDATE](#voice-settings-update) | Sent when the client's voice settings update | `rpc` or `rpc.voice.read` |
| [VOICE_SETTINGS_UPDATE_2](#voice-settings-update-2) | Sent when the client's basic voice settings update, scoped to the current application | `rpc.local` |
| [VOICE_CONNECTION_STATUS](#voice-connection-status) | Sent when the client's voice connection status changes | `rpc` or `rpc.voice.read` |
| [SPEAKING_START](#speaking-start) | Sent when a user in a subscribed voice channel speaks | `rpc`, `rpc.voice.read`, or `rpc.local` |
| [SPEAKING_STOP](#speaking-stop) | Sent when a user in a subscribed voice channel stops speaking | `rpc`, `rpc.voice.read`, or `rpc.local` |
| [ACTIVITY_JOIN](#activity-join) | Sent when the user clicks a rich presence join invite in chat to join an activity | `rpc`, `rpc.authenticated`, or `rpc.local` |
| [ACTIVITY_JOIN_REQUEST](#activity-join-request) | Sent when the user receives a rich presence Ask to Join request | `rpc` or `rpc.local` |
| [ACTIVITY_SPECTATE](#activity-spectate) | Sent when the user clicks a rich presence spectate invite in chat to spectate a game | `rpc`, `rpc.authenticated`, or `rpc.local` |
| [ACTIVITY_INVITE](#activity-invite) | Sent when the user receives a rich presence Join request | `rpc` or `rpc.local` |
| [ACTIVITY_PIP_MODE_UPDATE](#activity-pip-mode-update) | Sent when PiP (Picture-in-Picture) mode changes | |
| [ACTIVITY_LAYOUT_MODE_UPDATE](#activity-layout-mode-update) | Sent when a user changes the layout mode in the Discord client | |
| [THERMAL_STATE_UPDATE](#thermal-state-update) | Sent when thermal state of the mobile device is updated | `rpc.authenticated` |
| [ORIENTATION_UPDATE](#orientation-update) | For mobile devices, indicates a change in orientation of the screen | `rpc.authenticated` |
| [ACTIVITY_INSTANCE_PARTICIPANTS_UPDATE](#activity-instance-participants-update) | Sent when the number of instance participants changes | `rpc.authenticated` |
| [NOTIFICATION_CREATE](#notification-create) | Sent when the client receives a notification (mention or new message in eligible channels) | `rpc` and `rpc.notifications.read` |
| [MESSAGE_CREATE](#message-create) ^1^ | Sent when a message is created in a subscribed text channel | `rpc` |
| [MESSAGE_UPDATE](#message-update) ^1^ | Sent when a message is updated in a subscribed text channel | `rpc` |
| [MESSAGE_DELETE](#message-delete) ^1^ | Sent when a message is deleted in a subscribed text channel | `rpc` |
| OVERLAY | Sent to communicate with the game overlay | `rpc.private` |
| [OVERLAY_UPDATE](#overlay-update) | Sent when the game overlay settings are changed for your application | `rpc.local` |
| [ENTITLEMENT_CREATE](#entitlement-create) | Sent when an entitlement is created for one of your application's SKUs | `rpc.authenticated`, `rpc.local` |
| [ENTITLEMENT_DELETE](#entitlement-delete) | Sent when an entitlement is deleted for one of your application's SKUs | `rpc.authenticated`, `rpc.local` |
| [SCREENSHARE_STATE_UPDATE](#screenshare-state-update) | Sent when a user's screenshare state changes | `rpc.screenshare.read` or `rpc.local` |
| [VIDEO_STATE_UPDATE](#video-state-update) | Sent when a user's video state changes | `rpc.voice.read` or `rpc.local` |
| [AUTHORIZE_REQUEST](#authorize-request) | Sent when an activity wants to authorize within the Discord client | |
| [QUEST_ENROLLMENT_STATUS_UPDATE](#quest-enrollment-status-update) | Sent when a user's quest enrollment status changes | `identify` |
^1^ Requires that the channel or guild's `application_id` matches the `client_id` of the connection, or the authorization has the `messages.read` scope.
#### Ready
Sent when the client has completed the initial handshake with the RPC server.
###### Ready Structure
| Field | Type | Description |
| --------- | ------------------------------------------------------------------------ | ------------------------------------ |
| v | integer | The RPC protocol version |
| config | [client environment config](#client-environment-config-structure) object | The client environment configuration |
| user? ^1^ | [RPC user](#rpc-user-object) object | The connected user |
^1^ Only present in the IPC transport.
###### Client Environment Config Structure
| Field | Type | Description |
| ------------ | ------ | --------------------------------------------- |
| cdn_host? | string | The CDN domain |
| api_endpoint | string | The base API URL without scheme |
| environment | string | The type of environment (always `production`) |
#### Error
Sent in response to outgoing command or event.
###### Error Structure
| Field | Type | Description |
| ------- | ------- | --------------------------------------------- |
| code | integer | The [error code](#rpc-errors) |
| message | string | A human-readable message describing the error |
#### Current User Update
Sent when properties about the current user change. Inner payload is an [RPC user](#rpc-user-object) object.
#### Current Guild Member Update
Sent when properties about the guild member change. Inner payload is an [RPC guild member](#rpc-guild-member-object) object.
###### Current Guild Member Update Subscription Arguments Structure
| Field | Type | Description |
| -------- | --------- | ------------------- |
| guild_id | snowflake | The ID of the guild |
#### Guild Status
Sent when a subscribed guild's state changes.
###### Guild Status Subscription Arguments Structure
| Field | Type | Description |
| -------- | --------- | ------------------- |
| guild_id | snowflake | The ID of the guild |
###### Guild Status Structure
| Field | Type | Description |
| ----- | ------------------------------------- | ----------- |
| guild | [RPC guild](#rpc-guild-object) object | The guild |
#### Guild Create
Sent when a guild is created/joined on the client. The inner payload is an [RPC guild](#rpc-guild-object) object.
#### Channel Create
Sent when a channel is created/joined on the client. The inner payload is a [partial RPC channel](#partial-rpc-channel-structure) object.
#### Relationship Update
Sent when a user's relationship updates. The inner payload is an [RPC relationship](#rpc-relationship-object) object.
#### Voice Channel Select
Sent when the client moves voice channels.
###### Voice Channel Select Structure
| Field | Type | Description |
| ---------- | ---------- | ------------------------------------- |
| channel_id | ?snowflake | The ID of the channel |
| guild_id? | ?snowflake | The ID of the guild the channel is in |
#### Voice State Create
Sent when a user joins a subscribed voice channel. The inner payload is an [RPC voice state](#rpc-voice-state-object) object.
###### Voice State Create Subscription Arguments Structure
| Field | Type | Description |
| ---------- | --------- | ------------------------------------------------------ |
| channel_id | snowflake | The ID of the channel to subscribe to/unsubscribe from |
#### Voice State Delete
Sent when a user parts a subscribed voice channel. The inner payload is an [RPC voice state](#rpc-voice-state-object) object.
###### Voice State Delete Subscription Arguments Structure
| Field | Type | Description |
| ---------- | --------- | ------------------------------------------------------ |
| channel_id | snowflake | The ID of the channel to subscribe to/unsubscribe from |
#### Voice State Update
Sent when a user's voice state changes in a subscribed voice channel (mute, volume, etc.). The inner payload is an [RPC voice state](#rpc-voice-state-object) object.
###### Voice State Update Subscription Arguments Structure
| Field | Type | Description |
| ---------- | --------- | ------------------------------------------------------ |
| channel_id | snowflake | The ID of the channel to subscribe to/unsubscribe from |
#### Voice Settings Update
Sent when the client's voice settings update. The inner payload is an [RPC voice settings](#rpc-voice-settings-object) object.
#### Voice Settings Update 2
Sent when the client's user voice settings update, scoped to the current application.
###### Voice Settings Update 2 Structure
| Field | Type | Description |
| ------------- | -------------------------------------------------------------- | ------------------------------------------- |
| input_mode | [RPC voice input mode](#rpc-voice-input-mode-structure) object | The input mode |
| local_mutes | array[snowflake] | The IDs of the users that are locally muted |
| local_volumes | map[snowflake, float] | A mapping of user IDs to their volume |
| self_mute | boolean | Whether the user is self-muted |
| self_deaf | boolean | Whether the user is self-deafened |
###### RPC Voice Input Mode Structure
| Field | Type | Description |
| -------- | ------ | ---------------------------------------------------------------- |
| type | string | The [type of voice settings mode](#rpc-voice-settings-mode-type) |
| shortcut | string | The shortcut key combos for PTT |
#### Voice Connection Status
Sent when the client's voice connection status changes.
###### Voice Connection Status Structure
| Field | Type | Description |
| ------------- | ----------------------------------------------------------------------- | -------------------------------------------------------- |
| state | string | The [state of voice connection](#voice-connection-state) |
| hostname | string | The host name of the voice server |
| pings | array[[voice connection ping](#voice-connection-ping-structure) object] | The latest pings (max 200) |
| average_ping? | integer | The average latency in milliseconds |
| last_ping? | integer | The current latency in milliseconds |
###### Voice Connection Ping Structure
| Field | Type | Description |
| ----- | ------- | ----------------------------------------------------- |
| time | integer | Unix timestamp in milliseconds when the ping was made |
| value | integer | The latency |
###### Voice Connection State
| Value | Description |
| ------------------ | ------------------------------------------------------------------------------------------------- |
| DISCONNECTED | Voice server is disconnected |
| AWAITING_ENDPOINT | Client is waiting for a voice endpoint |
| AUTHENTICATING | Discord has connected to your real-time communication server and will secure the connection |
| CONNECTING | RTC server has been allocated and Discord is attempting to connect to it |
| VOICE_DISCONNECTED | Connection has been interrupted (Discord will attempt to re-establish the connection in a moment) |
| VOICE_CONNECTING | Secure connection to server is established and attempting to send data |
| VOICE_CONNECTED | Connection is successfully established |
| NO_ROUTE | Connection cannot be established (Discord will try again in a moment) |
| ICE_CHECKING | Secure connection to server is established and attempting to send data |
| DTLS_CONNECTING | Secure connection to server is established and attempting to send data |
#### Speaking Start
Sent when a user in a subscribed voice channel speaks.
###### Speaking Start Subscription Arguments Structure
| Field | Type | Description |
| ---------- | ---------- | --------------------- |
| channel_id | ?snowflake | The ID of the channel |
###### Speaking Start Structure
| Field | Type | Description |
| ---------- | --------- | ---------------------------------------- |
| channel_id | snowflake | The ID of the channel |
| user_id | snowflake | The ID of the user that started speaking |
#### Speaking Stop
Sent when a user in a subscribed voice channel stops speaking.
###### Speaking Stop Subscription Arguments Structure
| Field | Type | Description |
| ---------- | ---------- | --------------------- |
| channel_id | ?snowflake | The ID of the channel |
###### Speaking Stop Structure
| Field | Type | Description |
| ---------- | --------- | ---------------------------------------- |
| channel_id | snowflake | The ID of the channel |
| user_id | snowflake | The ID of the user that stopped speaking |
#### Activity Join
Sent when the user clicks a rich presence join invite in chat to join an activity.
###### Activity Join Structure
| Field | Type | Description |
| ------- | ------- | ---------------------------------------- |
| secret | string | The join secret |
| intent? | integer | The [activity join intent](#join-intent) |
###### Join Intent
| Value | Name | Description |
| ----- | -------- | ----------- |
| 0 | PLAY | Join |
| 1 | SPECTATE | Spectate |
#### Activity Join Request
Sent when the user receives a rich presence Ask to Join request.
###### Activity Join Request Structure
| Field | Type | Description |
| ---------- | ------------------------------------------------------ | ------------------------------------------------------------------------------------------------ |
| user | [RPC user](#rpc-user-object) object | The user |
| activity | [activity](/resources/presence#activity-object) object | The activity |
| type | integer | The [type of activity request](/resources/presence#activity-action-type) (always `JOIN_REQUEST`) |
| channel_id | snowflake | The ID of the channel |
| message_id | snowflake | The ID of the message |
#### Activity Spectate
Sent when the user clicks a rich presence spectate invite in chat to spectate a game.
###### Activity Spectate Structure
| Field | Type | Description |
| ------ | ------ | --------------------- |
| secret | string | The spectating secret |
#### Activity Invite
Sent when the user receives a rich presence Join request.
###### Activity Invite Structure
| Field | Type | Description |
| ---------- | ------------------------------------------------------ | ---------------------------------------------------------------------------------------- |
| user | [RPC user](#rpc-user-object) object | The user |
| activity | [activity](/resources/presence#activity-object) object | The activity |
| type | integer | The [type of activity request](/resources/presence#activity-action-type) (always `JOIN`) |
| channel_id | snowflake | The ID of the channel |
| message_id | snowflake | The ID of the message |
#### Activity PiP Mode Update
Sent when PiP (Picture-in-Picture) mode changes. This is essentially equivalent to [Activity Layout Mode Update](#activity-layout-mode-update) and checking if layout mode is not [`FOCUSED`](#orientation-state).
###### Activity PiP Mode Update
| Field | Type | Description |
| ----------- | ------- | -------------------------------------------- |
| is_pip_mode | boolean | Whether the embedded activity is in PiP mode |
#### Activity Layout Mode Update
Sent when a user changes the layout mode in the Discord client.
###### Activity Layout Mode Update Structure
| Field | Type | Description |
| ----------- | ------- | --------------------------------------- |
| layout_mode | integer | The current [layout mode](#layout-mode) |
###### Layout Mode
| Value | Name | Description |
| ----- | ------- | -------------------------------- |
| 0 | FOCUSED | Embedded activity is in focus |
| 1 | PIP | Embedded activity is in PiP mode |
| 2 | GRID | Embedded activity is in a grid |
#### Thermal State Update
Sent when thermal state of mobile device is updated.
###### Thermal State Update Structure
| Field | Type | Description |
| ------------- | ------- | ----------------------------------- |
| thermal_state | integer | The [thermal state](#thermal-state) |
###### Thermal State
| Value | Name | Description |
| ----- | -------- | ----------- |
| 0 | NOMINAL | Nominal |
| 1 | FAIR | Fair |
| 2 | SERIOUS | Serious |
| 3 | CRITICAL | Critical |
#### Orientation Update
Sent when orientation of the screen changes.
###### Orientation Update Structure
| Field | Type | Description |
| ------------------ | ------- | ---------------------------------------------------- |
| screen_orientation | integer | The current [screen orientation](#orientation-state) |
#### Activity Instance Participants Update
Sent when someone joins/leaves embedded activity instance.
###### Activity Instance Participants Update Structure
| Field | Type | Description |
| ------------ | -------------------------------------------------------------------------- | ---------------------------------------------------------- |
| participants | array[[RPC activity participant](#rpc-activity-participant-object) object] | The users currently participating in the activity instance |
#### Notification Create
Sent when the client receives a notification (mention or new message in eligible channels).
###### Notification Create Structure
| Field | Type | Description |
| ---------- | ----------------------------------------- | --------------------------------------------- |
| channel_id | snowflake | The ID of the channel the message was sent in |
| message | [RPC message](#rpc-message-object) object | The message that triggered the notification |
| icon_url | ?string | The URL of the icon to display |
| title | string | The title of the notification |
| body | string | The body text of the notification |
#### Message Create
Sent when a message is created in a subscribed text channel.
###### Message Create Subscription Arguments Structure
| Field | Type | Description |
| ---------- | --------- | ------------------------------------------------------ |
| channel_id | snowflake | The ID of the channel to subscribe to/unsubscribe from |
###### Message Create Structure
| Field | Type | Description |
| ---------- | ----------------------------------------- | ------------------------------------------------------ |
| channel_id | snowflake | The ID of the channel to subscribe to/unsubscribe from |
| message | [RPC message](#rpc-message-object) object | The message |
#### Message Update
Sent when a message is updated in a subscribed text channel.
###### Message Update Subscription Arguments Structure
| Field | Type | Description |
| ---------- | --------- | ------------------------------------------------------ |
| channel_id | snowflake | The ID of the channel to subscribe to/unsubscribe from |
###### Message Update Structure
| Field | Type | Description |
| ---------- | ----------------------------------------- | ------------------------------------------------------ |
| channel_id | snowflake | The ID of the channel to subscribe to/unsubscribe from |
| message | [RPC message](#rpc-message-object) object | The message |
#### Message Delete
Sent when a message is deleted in a subscribed text channel.
###### Message Delete Subscription Arguments Structure
| Field | Type | Description |
| ---------- | --------- | ------------------------------------------------------ |
| channel_id | snowflake | The ID of the channel to subscribe to/unsubscribe from |
###### Message Delete Structure
| Field | Type | Description |
| ---------- | ------------------------------------------------------------ | ------------------------------------------------------ |
| channel_id | snowflake | The ID of the channel to subscribe to/unsubscribe from |
| message | [partial RPC message](#partial-rpc-message-structure) object | The deleted message |
###### Partial RPC Message Structure
| Field | Type | Description |
| ----- | --------- | ----------------------------- |
| id | snowflake | The ID of the deleted message |
#### Overlay Update
Sent when the game overlay settings are changed for your application.
###### Overlay Update Subscription Arguments Structure
| Field | Type | Description |
| ----- | ------- | ------------------------------------------------------ |
| pid | integer | The ID of the process to subscribe to/unsubscribe from |
###### Overlay Update Structure
| Field | Type | Description |
| ------- | ------- | ------------------------------------------------------- |
| enabled | boolean | Whether the overlay is enabled for the application |
| locked | boolean | Whether the overlay is locked in the subscribed process |
#### Entitlement Create
Sent when an entitlement is created when a user purchases or is otherwise granted one of your application's SKUs. The inner payload is an [entitlement](/resources/entitlement#entitlement-object) object.
#### Entitlement Delete
Sent when an entitlement is deleted. The inner payload is an [entitlement](/resources/entitlement#entitlement-object) object.
#### Screenshare State Update
Sent when a user's screenshare state changes.
###### Screenshare State Update Structure
| Field | Type | Description |
| ----------- | --------------------------------------------------------------------- | ----------------------------------------------------------- |
| active | boolean | Whether the user is screensharing |
| pid | ?integer | The ID of the OS process whose window is being screenshared |
| application | ?[screenshare application](#screenshare-application-structure) object | The application being screenshared |
###### Screenshare Application Structure
| Field | Type | Description |
| ----- | ------ | --------------------------- |
| name | string | The name of the application |
#### Video State Update
Sent when a user's video state changes.
###### Video State Update Structure
| Field | Type | Description |
| ------ | ------- | -------------------------------------------- |
| active | boolean | Whether the current user's camera is enabled |
#### Authorize Request
Sent when an activity wants to authorize within the Discord client. Inner payload is `null`.
#### Quest Enrollment Status Update
Sent when a user's quest enrollment status changes.
###### Quest Enrollment Status Update Structure
| Field | Type | Description |
| ----------- | ------------------ | -------------------------------------- |
| quest_id | snowflake | The ID of the quest |
| is_enrolled | boolean | Whether the user is accepted the quest |
| enrolled_at | ?ISO8601 timestamp | When the user accepted the quest |
---
# Permissions
Link: https://docs.discord.food/topics/permissions
Permissions are a way to limit and grant certain abilities to users in Discord. A set of base permissions can be configured at the guild level for different roles. When these roles are attached to users, they grant or revoke specific privileges within the guild. Along with the guild-level permissions, Discord also supports permission overwrites that can be assigned to individual roles or members on a per-channel basis.
[Application command permissions](/interactions/application-commands#permissions) allow you to enable or disable
specific commands for entire channels in addition to individual roles or users.
Permissions are stored in a variable-length integer serialized into a string, and are calculated using bitwise operations. For example, the permission value `123` will be serialized as `"123"`. For long-term stability, it's recommended to deserialize the permissions using your preferred languages' Big Integer libraries. The total permissions integer can be determined by OR-ing (`|`) together each individual value, and flags can be checked using AND (`&`) operations.
In API v8 and above, all permissions are serialized as strings, including the `allow` and `deny` fields in overwrites. Any new permissions are rolled back into the base field.
In [API v7 and below (now deprecated)](/reference#api-versions), the `permissions`, `allow`, and `deny` fields in
roles and overwrites are still serialized as a number; however, these numbers shall not grow beyond 31 bits. During
the remaining lifetime of these API versions, all new permission bits will only be introduced in `permissions_new`,
`allow_new`, and `deny_new`. These `_new` fields are just for response serialization; requests with these fields
should continue to use the original `permissions`, `allow`, and `deny` fields, which accept both string or number
values.
```py
# Permissions value that can Send Messages (0x800) and Add Reactions (0x40):
permissions = 0x40 | 0x800 # 2112
# Checking for flags that are set:
(permissions & 0x40) == 0x40 # True
(permissions & 0x800) == 0x800 # True
# Kick Members (0x2) was not set:
(permissions & 0x2) == 0x2 # False
```
Additional logic is required when permission overwrites are involved; this is further explained below. For more information about bitwise operations and flags, see [this page](https://en.wikipedia.org/wiki/Bit_field).
Below is a table of all current permissions, their integer values in hexadecimal, brief descriptions of the privileges that they grant, and the channel type they apply to, if applicable.
###### Bitwise Permission Flags
| Value | Name | Description | Channel Type |
| ------------------------------------ | --------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------- | ------------ |
| `0x0000000000000001` `(1 << 0)` | CREATE_INSTANT_INVITE | Allows creation of instant invites | T, V, S |
| `0x0000000000000002` `(1 << 1)` | KICK_MEMBERS ^1^ | Allows kicking members | |
| `0x0000000000000004` `(1 << 2)` | BAN_MEMBERS ^1^ | Allows banning members | |
| `0x0000000000000008` `(1 << 3)` | ADMINISTRATOR ^1^ | Allows all permissions and bypasses channel permission overwrites | |
| `0x0000000000000010` `(1 << 4)` | MANAGE_CHANNELS ^1^ | Allows management and editing of channels | T, V, S |
| `0x0000000000000020` `(1 << 5)` | MANAGE_GUILD ^1^ | Allows management and editing of the guild | |
| `0x0000000000000040` `(1 << 6)` | ADD_REACTIONS | Allows for the addition of reactions to messages | T, V, S |
| `0x0000000000000080` `(1 << 7)` | VIEW_AUDIT_LOG | Allows for viewing of audit logs | |
| `0x0000000000000100` `(1 << 8)` | PRIORITY_SPEAKER | Allows for using priority speaker in a voice channel | V |
| `0x0000000000000200` `(1 << 9)` | STREAM | Allows the user to use video and stream (go live) in a voice channel | V, S |
| `0x0000000000000400` `(1 << 10)` | VIEW_CHANNEL | Allows guild members to view a channel, which includes reading messages in text channels and joining voice channels | T, V, S |
| `0x0000000000000800` `(1 << 11)` | SEND_MESSAGES | Allows for sending messages in a channel and creating threads in a forum (does not allow sending messages in threads) | T, V, S |
| `0x0000000000001000` `(1 << 12)` | SEND_TTS_MESSAGES | Allows for sending of `/tts` messages | T, V, S |
| `0x0000000000002000` `(1 << 13)` | MANAGE_MESSAGES ^1^ | Allows for deletion of other users messages | T, V, S |
| `0x0000000000004000` `(1 << 14)` | EMBED_LINKS | Links sent by users with this permission will be auto-embedded | T, V, S |
| `0x0000000000008000` `(1 << 15)` | ATTACH_FILES | Allows for uploading images and files | T, V, S |
| `0x0000000000010000` `(1 << 16)` | READ_MESSAGE_HISTORY | Allows for reading of message history | T, V, S |
| `0x0000000000020000` `(1 << 17)` | MENTION_EVERYONE | Allows for using the @everyone tag to notify all users in a channel, and the @here tag to notify all online users in a channel | T, V, S |
| `0x0000000000040000` `(1 << 18)` | USE_EXTERNAL_EMOJIS | Allows the usage of custom emoji from other servers | T, V, S |
| `0x0000000000080000` `(1 << 19)` | VIEW_GUILD_INSIGHTS | Allows for viewing guild insights | |
| `0x0000000000100000` `(1 << 20)` | CONNECT | Allows for joining of a voice channel | V, S |
| `0x0000000000200000` `(1 << 21)` | SPEAK | Allows for speaking in a voice channel | V |
| `0x0000000000400000` `(1 << 22)` | MUTE_MEMBERS | Allows for muting members in a voice channel | V, S |
| `0x0000000000800000` `(1 << 23)` | DEAFEN_MEMBERS | Allows for deafening of members in a voice channel | V |
| `0x0000000001000000` `(1 << 24)` | MOVE_MEMBERS | Allows for moving of members between voice channels | V, S |
| `0x0000000002000000` `(1 << 25)` | USE_VAD | Allows for using voice-activity-detection in a voice channel | V |
| `0x0000000004000000` `(1 << 26)` | CHANGE_NICKNAME | Allows for modification of own nickname | |
| `0x0000000008000000` `(1 << 27)` | MANAGE_NICKNAMES | Allows for modification of other users nicknames | |
| `0x0000000010000000` `(1 << 28)` | MANAGE_ROLES ^1^ | Allows management and editing of roles | T, V, S |
| `0x0000000020000000` `(1 << 29)` | MANAGE_WEBHOOKS ^1^ | Allows management and editing of webhooks | T, V, S |
| `0x0000000040000000` `(1 << 30)` | MANAGE_EXPRESSIONS ^1^ ^3^ | Allows editing and deleting emoji, stickers, and soundboard sounds | |
| `0x0000000080000000` `(1 << 31)` | USE_APPLICATION_COMMANDS | Allows members to use application commands, including slash commands and context menu commands | T, V, S |
| `0x0000000100000000` `(1 << 32)` | REQUEST_TO_SPEAK | Allows for requesting to speak in stage channels | S |
| `0x0000000200000000` `(1 << 33)` | MANAGE_EVENTS ^3^ | Allows for editing and deleting scheduled events | V, S |
| `0x0000000400000000` `(1 << 34)` | MANAGE_THREADS ^1^ | Allows for deleting and archiving threads, and viewing all private threads | T |
| `0x0000000800000000` `(1 << 35)` | CREATE_PUBLIC_THREADS | Allows for creating public and announcement threads | T |
| `0x0000001000000000` `(1 << 36)` | CREATE_PRIVATE_THREADS | Allows for creating private threads | T |
| `0x0000002000000000` `(1 << 37)` | USE_EXTERNAL_STICKERS | Allows the usage of custom stickers from other servers | T, V, S |
| `0x0000004000000000` `(1 << 38)` | SEND_MESSAGES_IN_THREADS | Allows for sending messages in threads | T |
| `0x0000008000000000` `(1 << 39)` | USE_EMBEDDED_ACTIVITIES | Allows for using Activities (applications with the `EMBEDDED` flag) in a voice channel | T, V |
| `0x0000010000000000` `(1 << 40)` | MODERATE_MEMBERS ^2^ | Allows for timing out users to prevent them from sending or reacting to messages in chat and threads, and from speaking in voice and stage channels | |
| `0x0000020000000000` `(1 << 41)` | VIEW_CREATOR_MONETIZATION_ANALYTICS ^1^ | Allows for viewing guild role subscriptions insights | |
| `0x0000040000000000` `(1 << 42)` | USE_SOUNDBOARD | Allows the usage of the soundboard in a voice channel | V |
| `0x0000080000000000` `(1 << 43)` | CREATE_EXPRESSIONS ^3^ | Allows for creating emoji, stickers, and soundboard sounds, and editing/deleting ones created by the current user | |
| `0x0000100000000000` `(1 << 44)` | CREATE_EVENTS ^3^ | Allows for creating scheduled events, and editing/deleting ones created by the current user | |
| `0x0000040000000000` `(1 << 45)` | USE_EXTERNAL_SOUNDS | Allows the usage of custom soundboard sounds from other servers | V |
| `0x0000400000000000` `(1 << 46)` | SEND_VOICE_MESSAGES | Allows for sending voice messages in a channel | T, V, S |
| ~~`0x0000800000000000` `(1 << 47)`~~ | ~~USE_CLYDE_AI~~ | ~~Allows members to interact with the Clyde AI integration~~ | ~~T, V, S~~ |
| `0x0001000000000000` `(1 << 48)` | SET_VOICE_CHANNEL_STATUS | Allows setting voice channel status | V |
| `0x0002000000000000` `(1 << 49)` | SEND_POLLS | Allows sending polls | T, V, S |
| `0x0004000000000000` `(1 << 50)` | USE_EXTERNAL_APPS | Allows the usage of [user-installed applications](/resources/application#application-integration-type) without forced-ephemeral responses | T, V, S |
| `0x0008000000000000` `(1 << 51)` | PIN_MESSAGES | Allows pinning messages in a channel | T, V, S |
| `0x0010000000000000` `(1 << 52)` | BYPASS_SLOWMODE | Allows members to bypass slowmode in a channel | T, V, S |
| `0x0020000000000000` `(1 << 53)` | MANAGE_OFFICIAL_MESSAGES | Allows members to mark messages as official in verified guilds | T |
^1^ These permissions require the user or bot owner account to use [multi-factor authentication](/topics/oauth2#multi-factor-authentication-requirement) when used on a guild that has guild-wide MFA enabled.
^2^ See [Permissions for Timed Out/Quarantined Members](/topics/permissions#permissions-for-timed-out/quarantined-members) to understand how permissions are temporarily modified for timed out/quarantined users.
^3^ The separate events for resource creation are only available to clients that specify a recent [client build number](/reference#client-properties). Otherwise, they are ignored and the management permissions are enforced.
Note that permission names may be referred to differently in the Discord client. For example, "Manage Permissions" refers to `MANAGE_ROLES`, "Use Voice Activity" refers to `USE_VAD`, and "Timeout Members" refers to `MODERATE_MEMBERS`.
The channel type abbreviations refer to the following:
| Channel Type | Values |
| ------------ | ---------------------------------------------------------------- |
| T | `GUILD_TEXT`, `GUILD_ANNOUNCEMENT`, `GUILD_FORUM`, `GUILD_MEDIA` |
| V | `GUILD_VOICE` |
| S | `GUILD_STAGE_VOICE` |
## Permission Hierarchy
How permissions apply may at first seem intuitive, but there are some hidden restrictions that prevent users from performing certain inappropriate actions based on a user's highest role compared to its target's highest role. A user's highest role is its role that has the greatest sorting priority in the guild, with the default @everyone role starting at 0. Permissions follow a hierarchy with the following rules:
Guild roles are sorted using a key of (`position`, `id`). This means that if multiple roles have the same position, the roles are sorted by their IDs in ascending order.
- A user can grant roles to other users that are of a lower position than its own highest role.
- A user can edit roles of a lower position than its highest role, but it can only grant permissions it has to those roles.
- A user can only sort roles lower than its highest role.
- A user can only kick, ban, and edit nicknames for users whose highest role is lower than the user's highest role.
Otherwise, permissions do not obey the role hierarchy. For example, a user has two roles: A and B. A denies the `VIEW_CHANNEL` permission on a #coolstuff channel. B allows the `VIEW_CHANNEL` permission on the same #coolstuff channel. The user would ultimately be able to view the #coolstuff channel, regardless of the role positions.
## Permission Overwrites
Overwrites can be used to apply certain permissions to roles or members on a channel-level. Applicable permissions are indicated by a **T** for text channels, **V** for voice channels, or **S** for stage channels in the table above.
When using overwrites, there are cases where permission collisions could occur for a user; that is to say, the user may have certain overwrites with permissions that contradict each other or their guild-level role permissions. With this in mind, permissions are applied to users in the following hierarchy:
1. Base permissions given to @everyone are applied at a guild level
2. Permissions allowed to a user by their roles are applied at a guild level
3. Overwrites that deny permissions for @everyone are applied at a channel level
4. Overwrites that allow permissions for @everyone are applied at a channel level
5. Overwrites that deny permissions for specific roles are applied at a channel level
6. Overwrites that allow permissions for specific roles are applied at a channel level
7. Member-specific overwrites that deny permissions are applied at a channel level
8. Member-specific overwrites that allow permissions are applied at a channel level
The following pseudocode demonstrates this process programmatically:
```py
def compute_base_permissions(member, guild):
if guild.is_owner(member):
return ALL
role_everyone = guild.get_role(guild.id) # get @everyone role
permissions = role_everyone.permissions
for role in member.roles:
permissions |= role.permissions
if permissions & ADMINISTRATOR == ADMINISTRATOR:
return ALL
return permissions
def compute_overwrites(base_permissions, member, channel):
# ADMINISTRATOR overrides any potential permission overwrites, so there is nothing to do here.
if base_permissions & ADMINISTRATOR == ADMINISTRATOR:
return ALL
permissions = base_permissions
overwrite_everyone = overwrites.get(channel.guild_id) # Find (@everyone) role overwrite and apply it.
if overwrite_everyone:
permissions &= ~overwrite_everyone.deny
permissions |= overwrite_everyone.allow
# Apply role specific overwrites.
overwrites = channel.permission_overwrites
allow = NONE
deny = NONE
for role_id in member.roles:
overwrite_role = overwrites.get(role_id)
if overwrite_role:
allow |= overwrite_role.allow
deny |= overwrite_role.deny
permissions &= ~deny
permissions |= allow
# Apply member specific overwrite if it exist.
overwrite_member = overwrites.get(member.user_id)
if overwrite_member:
permissions &= ~overwrite_member.deny
permissions |= overwrite_member.allow
return permissions
def compute_permissions(member, channel):
base_permissions = compute_base_permissions(member, channel.guild)
return compute_overwrites(base_permissions, member, channel)
```
## Implicit Permissions
Permissions in Discord are sometimes implicitly denied or allowed based on logical use. The two main cases are `VIEW_CHANNEL` and `SEND_MESSAGES` for text channels. Denying a user or a role `VIEW_CHANNEL` on a channel implicitly denies other permissions on the channel. Though permissions like `SEND_MESSAGES` are not explicitly denied for the user, they are ignored because the user cannot read messages in the channel.
Denying `SEND_MESSAGES` implicitly denies `MENTION_EVERYONE`, `SEND_TTS_MESSAGES`, `ATTACH_FILES`, and `EMBED_LINKS`. Again, they are not explicitly denied when doing permissions calculations, but they are ignored because the user cannot do the base action of sending messages.
For voice and stage channels, denying the `CONNECT` permission also implicitly denies other permissions such as `MANAGE_CHANNELS`.
There may be other cases in which certain permissions implicitly deny or allow other permissions. In all cases, it is based on logical conclusions about how a user with certain permissions should or should not interact with Discord.
## Inherited Permissions (Threads)
Threads inherit permissions from the parent channel (the channel they were created in), with one exception: The `SEND_MESSAGES` permission is not inherited; users must have `SEND_MESSAGES_IN_THREADS` to send a message in a thread, which allows for users to participate in threads in places like announcement channels.
Users must have the `VIEW_CHANNEL` permission to view _any_ threads in the channel, even if they are directly mentioned or added to the thread.
## Permissions For Timed Out/Quarantined Members
Timed out members will temporarily lose all permissions except `VIEW_CHANNEL` and `READ_MESSAGE_HISTORY`. This also applies to quarantined members, with the addition of the `CHANGE_NICKNAME` permission. Owners and users with the `ADMINISTRATOR` permission are exempt.
## Discoverable Guild Permissions
Guilds that are defined as [discoverable](/resources/discovery#definitions) have a unique permission setup to allow non-members to lurk the guild without joining it.
Non-members inherit the `VIEW_CHANNEL` and `READ_MESSAGE_HISTORY` permission from the @everyone role, meaning they can view public channels and read messages in them. However, they cannot interact with the guild in any way, such as sending messages, reacting to messages, or joining voice channels.
When lurking a discoverable guild with an active [public stage instance](/resources/stage-instance#definitions), non-members will inherit the additional permissions `CONNECT`, `REQUEST_TO_SPEAK`, `SPEAK`, and `USE_VAD` in the stage channel.
## Permission Syncing
Permissions with regards to categories and channels within categories are a bit tricky. Rather than inheritance, permissions are calculated by means of what is called Permission Syncing. If a child channel has the same permissions and overwrites (or lack thereof) as its parent category, the channel is considered "synced" to the category. Any further changes to a **parent category** will be reflected in its synced child channels. Any further changes to a **child channel** will cause it to become de-synced from its parent category, and its permissions will no longer change with changes to its parent category.
---
# CAPTCHA Handling
Link: https://docs.discord.food/topics/captcha-handling
Discord employs CAPTCHAs to prevent abuse when performing high-risk actions such as [logging in](/authentication#login), [accepting invites](/resources/invite#accept-invite), and [sending friend requests](/resources/relationships#send-friend-request).
Some endpoints will always return a CAPTCHA, while others will only return one if the user is sending suspicious requests or has performed a large number of high-risk actions in a short period of time.
Users should not assume that a CAPTCHA will only be returned from a subset of endpoints. Always be prepared to handle CAPTCHAs when making requests to the Discord API using a user account.
## Identifying CAPTCHAs
When a request is challenged, the endpoint will return a 400 bad request with a response body looking similar to a legacy error response:
###### CAPTCHA Response Structure
| Field | Type | Description |
| ----------------------- | ------------- | -------------------------------------------------------------------------- |
| captcha_key | array[string] | The CAPTCHA service errors |
| captcha_service | string | The [CAPTCHA service](#captcha-service) to use |
| captcha_sitekey ^1^ | ?string | The CAPTCHA site key (used by hCaptcha) |
| captcha_session_id? | string | The CAPTCHA session ID (used by hCaptcha) |
| captcha_rqdata? ^2^ | string | Custom data to be sent on challenge requests (used by hCaptcha Enterprise) |
| captcha_rqtoken? | string | The CAPTCHA challenge request token (used by hCaptcha Enterprise) |
| should_serve_invisible? | boolean | Whether the CAPTCHA challenge should be invisible |
^1^ For hCaptcha, the site key is dynamic and should not be hard-coded.
^2^ If this field is present, it _must_ be used in the challenge request or the challenge will fail.
###### CAPTCHA Service
| Value | Description | Site Key |
| -------------------- | -------------------- | ---------------------------------------- |
| hcaptcha | hCaptcha | Dynamic |
| recaptcha ^1^ | reCAPTCHA | 6Lef5iQTAAAAAKeIvIY-DeexoO3gj7ryl9rLMEnn |
| recaptcha_enterprise | reCAPTCHA Enterprise | 6LeYqFcqAAAAAD6iZesmNgVulsO4PkpBdr6NVG6M |
^1^ reCAPTCHA is not currently used by Discord, but may be used again in the future.
###### Example CAPTCHA Response
```json
{
"captcha_key": ["invalid-input-response", "response-already-used-error"],
"captcha_sitekey": "f5561ba9-8f1e-40ca-9b5b-a0b3f719ef34",
"captcha_service": "hcaptcha"
}
```
On certain endpoints that have not previously returned CAPTCHAs, the `captcha_key` array may contain an error message to display to older clients that made incorrect assumptions about CAPTCHA availability. For example:
```json
{
"captcha_key": ["You need to update your app to join this server."],
"captcha_sitekey": "b2b02ab5-7dae-4d6f-830e-7b55634c888b",
"captcha_service": "hcaptcha",
"captcha_session_id": "0ad46c1c-98e2-45f4-a09c-ddbfde9a301c",
"captcha_rqdata": "32ODySYSI08RDvfcOKNA25zs8hGNVeD75qXuvAiuXnhgGV1tEqL/M6jHj9NJhuN3843/3Xb0y4qL9X85UhNWMLmXgvqDdUEJSKv1NlqrGqmBhi8qC2W4nKMzYeEFpGPMTqqC12Gp8BCZ+SPn9Dw0g3c=SMTWOoJOQKEpSoHZ",
"captcha_rqtoken": "Im4rRTZXUWRTNFhyWTFpZUpEbVM3YVl1bFd6dU0zNUt0VkhzMEVoTHJNcC9wSmVqT29kS1FJVFpYYVgrT0RNd254YjFVQUE9PXVnalltRDZtNEFKOW85VXMi.ZfYH3g.beZ-lIsxWGcY5J0VUzE_odCbh24"
}
```
To correctly identify CAPTCHAs, clients should check for a 400 bad request status code and the presence of the `captcha_key` field and not rely on the specific errors within the array.
## Solving CAPTCHAs
When a CAPTCHA is returned, the client must display a CAPTCHA challenge to the user. How this is done depends on the [CAPTCHA service](#captcha-service) used.
See the [hCaptcha](https://docs.hcaptcha.com/) and [reCAPTCHA](https://developers.google.com/recaptcha/docs/display) documentation for more information.
After the user has solved the CAPTCHA, the request should be retried with the CAPTCHA solution inserted into the `X-Captcha-Key` header.
**Additionally, if the [`captcha_session_id` field](#captcha-response-structure) is present, it _must_ be inserted into the `X-Captcha-Session-Id` header.
If the [`captcha_rqtoken` field](#captcha-response-structure) is present, it _must_ be inserted into the `X-Captcha-Rqtoken` header.**
If the solution is not accepted, the endpoint will return a 400 bad request with a response body similar to the original CAPTCHA response.
Note that an otherwise valid solution may be rejected if the solution's bot score is too high or the `captcha_rqdata`/`captcha_rqtoken` fields are not properly handled.
Previously, CAPTCHA solutions were sent in the JSON body of the request using the `captcha_key` and `captcha_rqtoken` fields. This behavior is now deprecated and should not be relied on.
---
# Errors
Link: https://docs.discord.food/topics/errors
## HTTP
The API will return semantically valid HTTP response codes based on the success of your request. The following table can be used as a reference for response codes it will return.
###### HTTP Response Codes
| Code | Description |
| --------------------------- | --------------------------------------------------------------------------------------------------------- |
| 200 (OK) | The request completed successfully |
| 201 (CREATED) | The entity was created successfully |
| 202 (ACCEPTED) | The request was accepted but the resource is not ready. A `retry_after` key should be present in the body |
| 204 (NO CONTENT) | The request completed successfully but returned no content |
| 304 (NOT MODIFIED) | The entity was not modified (no action was taken) |
| 400 (BAD REQUEST) | The request was improperly formatted, or the server couldn't understand it |
| 401 (UNAUTHORIZED) | The `Authorization` header was missing or invalid |
| 403 (FORBIDDEN) | You do not have permission to perform the requested action |
| 404 (NOT FOUND) | The resource at the location specified doesn't exist |
| 405 (METHOD NOT ALLOWED) | The HTTP method used is not valid for the location specified |
| 409 (CONFLICT) | The requested resource update could not be completed due to the current state of the target resource |
| 410 (GONE) | The resource being accessed is no longer available |
| 413 (PAYLOAD TOO LARGE) | The request entity was too large |
| 415 (UNSUPPORTED MEDIA) | The requested content type is not supported (CDN only) |
| 422 (UNPROCESSABLE CONTENT) | The request was well-formed but failed validation (Rust services only) |
| 423 (LOCKED) | The resource being accessed is transiently locked. Try again later |
| 429 (TOO MANY REQUESTS) | You are being rate limited, see [Rate Limits](/topics/rate-limits) |
| 501 (NOT IMPLEMENTED) | The requested HTTP method is not supported |
| 502 (GATEWAY UNAVAILABLE) | There was no gateway available to process your request. Wait a bit and retry |
| 503 (SERVICE UNAVAILABLE) | The service required to process your request is unavailable. Wait a bit and retry |
| 504 (GATEWAY TIMEOUT) | The gateway processing your request timed out. Wait a bit and retry |
| 5xx (SERVER ERROR) ^1^ | The server had an error processing your request |
^1^ 502, 504, 507, 522, 523, 524 should be retried with a backoff. The number of failed requests can be specified with the `X-Failed-Requests` header. Whether you retry other 5xx errors is up to you.
## JSON
Along with the HTTP error code, the API can also return more detailed error codes through a `code` key in the JSON error response. The response will also contain a `message` key containing a more friendly error string. Some of these errors may include additional details in the form of [Error Messages](/reference#error-messages) provided by an `errors` object.
A special `40333` JSON error code is returned if your request is blocked by Cloudflare. This may be due to a malformed request or improper user agent. The response resembles a normal error structure but is not thrown by the API itself:
```json
{
"message": "internal network error",
"code": 40333
}
```
Receiving a 403 forbidden response with a `10008` JSON error code indicates that your request has been blocked by Discord's anti abuse systems, despite the error message being "Unknown Message":
```json
{
"message": "Unknown Message",
"code": 10008
}
```
This can happen for a number of reasons, both relating to the request and the account itself. Note that this is not the _only_ error code that can be returned when a request is blocked. Sometimes, contextually valid error codes may be returned instead, even when they make no sense.
###### JSON Error Codes
We maintain an unofficial updated list of JSON error codes seen in the wild, which is significantly more comprehensive than the official documentation. If you found an error which is incorrect or not listed, you can submit it here with reproduction steps, and we will add it to the list.
###### Example JSON Error Response
```json
{
"message": "Invalid authentication token",
"code": 50014
}
```
---
# Push Notifications
Link: https://docs.discord.food/topics/push-notifications
Push notifications are used to notify users of events that occur in the background, such as incoming messages or calls.
After [authenticating](/authentication), a mobile client can register a device push notification token with the server using the [Register Device](#register-device) endpoint. This token is then used to send push notifications to the client's device.
## Registering Tokens
A client registers its device's token with the [Register Device](#register-device) endpoint, or with [Sync Devices](#sync-devices) when several accounts share the device.
It also keeps the token it was given by the operating system, and attaches it to requests that provision a new authentication token, so the device stays registered across the change without a second round trip.
Currently, these endpoints are [Modify Current User](/resources/user#modify-current-user) and [Reset Password](/authentication#reset-password).
###### Push Notification Provider
| Value | Description |
| ----------------------- | --------------------------------------------------- |
| gcm | Firebase Cloud Messaging (Android) |
| meta_horizon | Meta Horizon OS push notifications (Meta Quest) |
| apns | Apple Push Notification Service (iOS) |
| apns_internal | Apple Push Notification Service (iOS internal) |
| apns_local ^1^ | Apple Push Notification Service (iOS local) |
| apns_voip ^2^ | VOIP Apple Push Notification Service (iOS) |
| apns_internal_voip ^2^ | VOIP Apple Push Notification Service (iOS internal) |
| apns_local_voip ^1^ ^2^ | VOIP Apple Push Notification Service (iOS local) |
^1^ Local providers are only used by locally-built clients, identified by a `com.hammerandchisel.discord.local` bundle ID prefix.
^2^ VOIP-specific push notification providers are used to provide rich notifications for VOIP calls on iOS.
## Push Notification Payloads
Push notifications are delivered as data-only messages. The payload carries the entities the event concerns, and the client renders, groups, and routes the notification itself.
Which fields are present depends on the [type of push notification](#push-notification-type).
On iOS, the payload's fields are sent as top-level siblings of the standard APNs `aps` dictionary. On Android, they are sent as an FCM data message; there is no `notification` block, so notifications are always rendered by the client rather than by the system.
Every value in an FCM data payload is a string. On Android, integers and booleans arrive stringified, and the
`message` and `channel_ids` fields arrive as JSON-encoded strings rather than as an object and an array.
Only `type` is guaranteed to be present. Every other field is optional, and a client that receives a `type` it does not recognize is expected to ignore the notification.
The fields belonging to a notification's type are sent alongside the ones below rather than nested in an object of their own.
###### Push Notification Structure
| Field | Type | Description |
| ------------------------------------------ | ---------------- | -------------------------------------------------------------------------------------- |
| type | string | The [type of push notification](#push-notification-type) |
| receiving_user_id? ^1^ | snowflake | The ID of the user the notification is intended for |
| notif_type_id? | integer | The [type of notification](#notification-type) that produced the push notification |
| notif_instance_id? | string | The ID of this specific delivery of the notification |
| tracking_type? | string | The [tracking type](#tracking-type) the notification is reported under in analytics |
| notification_channel? **(deprecated)** ^2^ | string | The [notification channel](#notification-channel) the notification belongs to |
| title? | string | The title to display, overriding the one the client would derive |
| subtitle? | string | The subtitle to display |
| expand_subtitle? | boolean | Whether the subtitle should be displayed expanded (default false) |
| icon_url? | string | The URL of the icon to display |
| silent? | boolean | Whether the notification should be delivered without alerting the user (default false) |
| sent_at_ms? ^3^ | integer | Unix timestamp (in milliseconds) of when the notification was sent |
| channel_ids? | array[snowflake] | The IDs of the channels the notification [acknowledges](#acknowledging-notifications) |
| mention_type? | string | The type of mention that triggered the notification, used for analytics |
| join_id? | string | An opaque identifier reported alongside the notification in analytics |
^1^ Used on devices with multiple accounts logged in. The client switches to this account before acting on the notification. See [Sync Devices](#sync-devices) for more information.
^2^ Android only. Modern clients derive the notification channel from `notif_type_id` instead; see [notification channels](#notification-channel).
^3^ Used as the last acknowledged timestamp when a notification acknowledges channels. Clients that do not receive this field fall back to the time the push was sent.
###### Push Notification Type
| Value | Description | Extra Data |
| ------------------------------------ | ------------------------------------------------------------------ | ---------------------------------------------------------------------------------------------- |
| MESSAGE_CREATE | A message was sent in a channel the user is notified about | [message create](#message-create-structure) object |
| FORUM_THREAD_CREATED | A thread was created in a forum channel the user is notified about | [forum thread created](#forum-thread-created-structure) object |
| RELATIONSHIP_ADD | A relationship with the user was created | [relationship add](#relationship-add-structure) object |
| FRIEND_SUGGESTION_CREATE | A friend suggestion was created for the user | [friend suggestion create](#friend-suggestion-create-structure) object |
| CALL_RING | The user is being rung in a call | [call ring](#call-ring-structure) object |
| CALL_RING_END ^1^ | The user is no longer being rung in a call | — |
| CALL_ACK ^1^ | The call the user was being rung in was answered elsewhere | — |
| CALL_CONNECT | The user should join a call | [call connect](#call-connect-structure) object |
| CHANNEL_ACK ^1^ | Channels were read elsewhere | — |
| ACTIVITY_START | A friend started an activity | [activity start](#activity-start-structure) object |
| APPLICATION_LIBRARY_INSTALL_COMPLETE | An application finished installing | [application library install complete](#application-library-install-complete-structure) object |
| STAGE_INSTANCE_CREATE | A stage instance the user is notified about was created | [stage instance create](#stage-instance-create-structure) object |
| GUILD_SCHEDULED_EVENT_UPDATE | A guild scheduled event the user is interested in started | [guild scheduled event update](#guild-scheduled-event-update-structure) object |
| GUILD_STREAM_START | A user started streaming in a guild the user is notified about | [guild stream start](#guild-stream-start-structure) object |
| GENERIC_PUSH_NOTIFICATION_SENT ^2^ | A notification with no dedicated payload was sent | [generic push notification](#generic-push-notification-structure) object |
^1^ These types retract notifications instead of displaying one; see [acknowledging notifications](#acknowledging-notifications).
^2^ This is used for [notification types](#notification-type) that have no dedicated handling in the client.
###### Message Create Structure
| Field | Type | Description |
| ------------------------- | ----------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------- |
| message? ^1^ | partial [message](/resources/message#message-object) object | The message that was sent |
| message_id | snowflake | The ID of the message that was sent |
| message_type\_ | integer | The [type of message](/resources/message#message-type) that was sent |
| message_content | string | The content of the message |
| message_flags? | integer | The message's [flags](/resources/message#message-flags) |
| message_reference_type? | integer | The [type of reference](/resources/message#message-reference-type) on the message |
| message_activity_type? | integer | The [type of activity request](/resources/presence#activity-action-type) in the message |
| message_application_name? | string | The name of the application attached to the message |
| channel_id | snowflake | The ID of the channel the message was sent in |
| channel_type | integer | The [type of channel](/resources/channel#channel-type) the message was sent in |
| channel_name | string | The name of the channel the message was sent in |
| channel_icon? | ?string | The group DM's [icon hash](/reference#cdn-formatting) |
| is_spoiler_channel? | boolean | Whether the channel is a spoiler channel, meaning contents should be hidden until the notification is opened (default false) |
| app_dm? | boolean | Whether the channel is a DM with an application (default false) |
| guild_id? | snowflake | The ID of the guild the message was sent in |
| guild_name? | string | The name of the guild the message was sent in |
| guild_icon? | ?string | The guild's [icon hash](/reference#cdn-formatting) |
| user_id | snowflake | The ID of the message's author |
| user_username | string | The username of the message's author |
| user_global_name? | ?string | The display name of the message's author |
| user_discriminator? | ?integer | The author's discriminator |
| user_avatar? | ?string | The author's [avatar hash](/reference#cdn-formatting) |
| user_guild_avatar? | ?string | The author's [guild avatar hash](/reference#cdn-formatting) |
| is_from_current_user? | boolean | Whether the message was sent by the receiving user (default false) |
| \_\_category? | string | Whether the notification can be replied to inline (value of `can_reply`) |
| poll_question? | string | The question of the poll attached to the message |
| image_url? | string | The URL of the message's image attachment |
| image_url_ergo_android? | string | The URL of the message's image attachment, sized for Android |
| image_count? | integer | The number of image attachments on the message |
| video_count? | integer | The number of video attachments on the message |
| attachment_text_variant? | integer | The [attachment summary](#attachment-text-variant) to display in place of the message's content |
| invite_guild_name? ^2^ | string | The name of the guild the message invites the user to |
| invite_channel_name? ^2^ | string | The name of the channel the message invites the user to |
| invite_title_variant? ^2^ | integer | The [invite title](#invite-title-variant) to display in place of the author's name |
^1^ Contains only the `author`, `mentions`, `embeds`, `components`, `sticker_items`, and `poll` fields.
^2^ Only sent for messages in a DM that invite the user to a guild.
###### Attachment Text Variant
Sent when the message's own content should not be shown.
In a spoiler channel, only variants `SENT_AN_IMAGE`, `SENT_A_GIF`, and `SENT_A_VIDEO` are honored;
the rest fall back to a generic summary so that attachment counts are not revealed.
| Value | Name | Description |
| ----- | ------------- | ------------------------------------------------------------------- |
| 1 | SENT_AN_IMAGE | The message has a single image attachment |
| 2 | SENT_IMAGES | The message has several image attachments, counted by `image_count` |
| 3 | SENT_A_GIF | The message has a GIF attachment |
| 4 | SENT_A_VIDEO | The message has a single video attachment |
| 5 | SENT_VIDEOS | The message has several video attachments, counted by `video_count` |
###### Invite Title Variant
| Value | Name | Description |
| ----- | ----------- | ------------------------------------------------------------ |
| 1 | SENDER_ONLY | Titled as an invite from the message's author |
| 2 | EMOJI | Titled as an invite from the message's author, with an emoji |
###### Forum Thread Created Structure
| Field | Type | Description |
| ------------------- | --------- | --------------------------------------------------------- |
| channel_id | snowflake | The ID of the thread that was created |
| channel_name | string | The name of the thread that was created |
| parent_id | snowflake | The ID of the forum channel the thread was created in |
| parent_name | string | The name of the forum channel the thread was created in |
| user_id | snowflake | The ID of the user who created the thread |
| user_username | string | The username of the user who created the thread |
| user_avatar? | ?string | The user's [avatar hash](/reference#cdn-formatting) |
| user_guild_avatar? | ?string | The user's [guild avatar hash](/reference#cdn-formatting) |
| user_discriminator? | ?integer | The user's discriminator |
| guild_id? | snowflake | The ID of the guild the thread was created in |
| guild_name? | string | The name of the guild the thread was created in |
| guild_icon? | ?string | The guild's [icon hash](/reference#cdn-formatting) |
###### Relationship Add Structure
| Field | Type | Description |
| ------------------ | ----------------- | --------------------------------------------------------------------------------------- |
| rel_type | integer | The [type of relationship](/resources/relationships#relationship-type) that was created |
| user_id | snowflake | The ID of the user the relationship is with |
| user_username | string | The username of the user the relationship is with |
| user_global_name? | ?string | The display name of the user the relationship is with |
| user_avatar? | ?string | The user's [avatar hash](/reference#cdn-formatting) |
| notification_type? | string | The [tracking type](#tracking-type) of the reminder that produced the notification |
| since? | ISO8601 timestamp | When the relationship was created |
###### Friend Suggestion Create Structure
| Field | Type | Description |
| ---------------------- | --------- | ---------------------------------------------------------------------------------------------- |
| user_id | snowflake | The ID of the suggested user |
| user_username | string | The username of the suggested user |
| user_avatar? | ?string | The suggested user's [avatar hash](/reference#cdn-formatting) |
| platform_type | string | The [type of connection](/resources/connected-accounts#connection-type) the suggestion is from |
| platform_name? | ?string | The name of the connection the suggestion is from |
| platform_user_username | string | The username of the suggested user on the connected account |
###### Call Ring Structure
| Field | Type | Description |
| ------------- | --------- | --------------------------------------------------------------------- |
| channel_id | snowflake | The ID of the channel the call is in |
| channel_type | integer | The [type of channel](/resources/channel#channel-type) the call is in |
| channel_name | string | The name of the channel the call is in |
| channel_icon? | ?string | The channel's [icon hash](/reference#cdn-formatting) |
| rtc_region? | ?string | The [voice region](/topics/voice-connections) the call is hosted in |
| user_id | snowflake | The ID of the user who is ringing |
| user_username | string | The username of the user who is ringing |
| user_avatar? | ?string | The ringing user's [avatar hash](/reference#cdn-formatting) |
###### Call Connect Structure
| Field | Type | Description |
| -------------------------- | --------- | ----------------------------------------------------------------------------------- |
| channel_id | snowflake | The ID of the channel to join |
| guild_id? | snowflake | The ID of the guild the channel is in |
| user_id? | snowflake | The ID of the user who rang |
| is_fullscreen_call_ui? ^1^ | boolean | Whether the call was answered from the system's full-screen call UI (default false) |
^1^ Android only.
###### Activity Start Structure
Clients should ignore `ACTIVITY_START` notifications with a `STREAMING` activity type, since streams are notified through `GUILD_STREAM_START` instead.
| Field | Type | Description |
| --------------------- | --------- | ---------------------------------------------------------------------------------------------------------- |
| activity_type | integer | The [type of activity](/resources/presence#activity-type) that was started |
| activity_name | string | The name of the activity that was started |
| activity_instance_id? | string | The [composite ID](/resources/application#embedded-activity-instance-id) of the launched activity instance |
| application_id? | snowflake | The ID of the application the activity belongs to |
| application_name? | string | The name of the application the activity belongs to |
| application_icon? | ?string | The application's [icon hash](/reference#cdn-formatting) |
| user_id? | snowflake | The ID of the user who started the activity |
| user_username? | string | The username of the user who started the activity |
| user_avatar? | ?string | The user's [avatar hash](/reference#cdn-formatting) |
###### Application Library Install Complete Structure
| Field | Type | Description |
| ----------------- | --------- | -------------------------------------------------------- |
| application_id | snowflake | The ID of the application that finished installing |
| application_name | string | The name of the application that finished installing |
| application_icon? | ?string | The application's [icon hash](/reference#cdn-formatting) |
###### Stage Instance Create Structure
| Field | Type | Description |
| --------------------- | --------- | ------------------------------------------- |
| channel_id | snowflake | The ID of the stage channel |
| guild_id | snowflake | The ID of the guild the stage channel is in |
| stage_instance_topic? | string | The topic of the stage instance |
###### Guild Stream Start Structure
| Field | Type | Description |
| ---------- | --------- | ---------------------------------------- |
| channel_id | snowflake | The ID of the channel being streamed in |
| guild_id | snowflake | The ID of the guild the channel is in |
| user_id | snowflake | The ID of the user who started streaming |
###### Guild Scheduled Event Update Structure
| Field | Type | Description |
| ---------------------------------- | --------- | --------------------------------------------------------------------------------------------------------------- |
| guild_scheduled_event_id | snowflake | The ID of the guild scheduled event |
| guild_scheduled_event_entity_type | integer | The [type of entity](/resources/guild-scheduled-event#guild-scheduled-event-entity-type) the event is hosted at |
| guild_id | snowflake | The ID of the guild the event is in |
| channel_id? ^1^ | snowflake | The ID of the channel the event is hosted in |
| channel_name? | string | The name of the channel the event is hosted in |
| channel_type? | integer | The [type of channel](/resources/channel#channel-type) the event is hosted in |
| guild_scheduled_event_entity_id? | snowflake | The ID of the entity the event is hosted at |
| guild_scheduled_event_entity_name? | string | The name of the entity the event is hosted at |
| guild_name? | string | The name of the guild the event is in |
| guild_icon? | ?string | The guild's [icon hash](/reference#cdn-formatting) |
^1^ Always present for events with a `STAGE_INSTANCE` or `VOICE` entity type. Clients ignore events hosted at any other kind of entity.
###### Generic Push Notification Structure
| Field | Type | Description |
| -------------------------- | ---------- | ------------------------------------------------------------------------------------------------------------------------------------------ |
| notification_type? | string | The [type of notification](#notification-type) that produced the push notification |
| deeplink? ^1^ | string | The deep link to open when the notification is tapped |
| notification_id? | string | The ID of the notification |
| notification_center_id? | snowflake | The ID of the [notification center item](/resources/notification-center#notification-center-item-object) the notification was created from |
| guild_id? | snowflake | The ID of the guild the notification concerns |
| channel_id? | snowflake | The ID of the channel the notification concerns |
| message_id? | snowflake | The ID of the message the notification concerns |
| user_id? | snowflake | The ID of the user the notification concerns |
| status_text? ^2^ | string | The custom status text of the user the notification concerns |
| status_emoji_id? ^2^ ^3^ | ?snowflake | The ID of the custom emoji in the user's custom status |
| status_emoji_name? ^2^ | ?string | The unicode character of the emoji in the user's custom status |
| status_emoji_animated? ^2^ | boolean | Whether the emoji in the user's custom status is animated (default false) |
^1^ Deep links are a URL using either the `discord://` protocol or a Discord hostname.
^2^ Only sent with `ICYMI_SUMMARY` notifications.
^3^ A value of `0` should be treated the same as a `null` value.
###### Notification Type
Every notification Discord can send has a type, independent of the [push notification type](#push-notification-type) used to deliver it. It is sent as `notif_type_id`,
and determines which [notification channel](#notification-channel) the notification is posted to and which user notification settings suppress it.
Types with no dedicated handling in the client are delivered as `GENERIC_PUSH_NOTIFICATION_SENT` push notifications, which name their type in `notification_type` instead.
| Value | Name | Description |
| ------ | ------------------------------------------------- | --------------------------------------------------------- |
| 1 | MESSAGE_CREATE | A message was sent |
| 2 | CALL_RING | The user is being rung in a call |
| 3 | RELATIONSHIP_ADD | A relationship with the user was created |
| 4 | FRIEND_SUGGESTION_CREATE | A friend suggestion was created for the user |
| 5 | APPLICATION_LIBRARY_INSTALL_COMPLETE | An application finished installing |
| 6 | GUILD_STREAM_START | A user started streaming in a guild |
| 7 | STAGE_INSTANCE_CREATE | A stage instance was created |
| 8 | GUILD_SCHEDULED_EVENT_UPDATE | A guild scheduled event started |
| 9 | FORUM_THREAD_CREATED | A thread was created in a forum channel |
| 10 | TOP_MESSAGES_PUSH | A digest of top messages from a frequently read guild |
| 11 | MISSED_MESSAGE_PUSH | Missed messages from a frequently read channel |
| 13 | FRIEND_REQUEST_REMINDER_PUSH | A reminder about pending friend requests |
| 14 | HOME_LIFECYCLE_PUSH | A new user tutorial item |
| 15 | POLL_ENDED_PUSH | A poll the user participated in ended |
| 16 | NUDGE_NEW_FRIEND_DM_PUSH | A reminder to message a new friend |
| 17 | FAMILY_CENTER_REQUEST_SEND | A family center link request was sent |
| 18 | FAMILY_CENTER_REQUEST_ACCEPTED | A family center link request was accepted |
| 19 | FAMILY_CENTER_REQUEST_DECLINED | A family center link request was declined |
| 20 | FAMILY_CENTER_DISCONNECTED | A family center link was disconnected |
| 21 | GUILD_JOIN_REQUEST_APPROVED | A guild join request was approved |
| 22 | GUILD_JOIN_REQUEST_REJECTED | A guild join request was rejected |
| 23 | REACTIONS_PUSH_NOTIFICATION | A reaction was added to the user's message |
| 24 | RAID_DETECTED | A raid was detected in a guild the user moderates |
| 25 | MENTION_RAID_DETECTED | A mention raid was detected in a guild the user moderates |
| 26 | DM_SPAM_DETECTED | DM spam was detected in a guild the user moderates |
| 27 | SUSPICIOUS_SESSION | A suspicious session was detected on the user's account |
| 28 | NEW_USER_SESSION | A new session was started on the user's account |
| 29 | MESSAGE_REMINDER_DUE | A message reminder the user set is due |
| 30 | ICYMI_SUMMARY | A summary of activity the user missed |
| 31 | CHANNEL_PROMPT_DEADCHAT | A prompt to revive an inactive channel |
| 32 | REACTION_TRENDING_PUSH_NOTIFICATION | A reaction on the user's message is trending |
| 33 | SUMMONS_DIRECT | Unknown |
| 34 | ADMIN_NOTIFICATION_PUSH | A notification sent by a guild's administrators |
| 35 | VOICE_CHANNEL_ACTIVITY | Friends are active in a voice channel |
| 36 | MISSED_MESSAGE_EMAIL ^1^ | Missed messages from a frequently read channel |
| 37 | CUSTOM_STATUS_UPDATE | A friend updated their custom status |
| 38 | GO_LIVE_NOTIFICATION | A friend started streaming |
| 39 | FRIEND_GAMING_ACTIVITY_PUSH | A friend started playing a game |
| ~~40~~ | ~~USER_RESURRECTION_NOTIFICATION~~ | ~~A friend returned to Discord after a long break~~ |
| 41 | FRIEND_ONLINE_PUSH | A friend came online |
| 42 | INVITE_REMINDER_PUSH | Unknown |
| 43 | SERVER_TRENDING_NOTIFICATION | A guild is trending |
| 44 | MESSAGE_PIN | A message was pinned |
| 45 | PROFILE_UPDATES_NOTIFICATION | A friend updated their profile |
| 46 | SUMMARY_REMINDER | A reminder about a recent conversation summary |
| 47 | TRIAL_FOR_ALL_REMINDER | A reminder about an on-going trial promotion |
| 48 | FRIENDS_PLAYING_GAME | Friends are playing a game |
| 49 | REFERRAL_PROGRAM_PUSH_NOTIF_ENTRYPOINT_REMINDER | A reminder about the referral program |
| 50 | REFERRAL_PROGRAM_NOTIF_CENTER_ENTRYPOINT_REMINDER | A notification center reminder about the referral program |
| 51 | GAME_UPDATE | One of the user's games was updated |
| 52 | VOICE_CHANNEL_INVITE | The user was invited to a voice channel |
| 53 | GUILD_SCHEDULED_EVENT_UPCOMING | A guild scheduled event is starting soon |
| 54 | FAMILY_CENTER_RESTRICTED_SCHEDULE_UPDATED | A family center restricted schedule was updated |
| 55 | VOICE_CHANNEL_ACTIVITY_PEAK_AFFINITY | The user's closest friends are active in a voice channel |
| 56 | PARENTAL_CONSENT_FINAL_WARNING | A final warning about outstanding parental consent |
| 57 | MESSAGE_REQUEST | The user received a message request |
| 58 | FRIENDS_PLAYING_TRENDING_GAME | Friends are playing a trending game |
^1^ Delivered by email rather than as a push notification.
###### Tracking Type
| Value | Description |
| ------------------------------- | ----------------------------------------------- |
| generic_friend_request_reminder | A reminder about pending friend requests |
| generic_home_featured_message | A featured message from a guild's home feed |
| generic_missed_message | Missed messages from a frequently read channel |
| GUILD_STREAM_START | A user started streaming in a guild |
| home_lifecycle_push | A new user tutorial item |
| new_user_session | A new session was started on the user's account |
| nudge_new_friend_dm_push | A reminder to message a new friend |
| poll_ended | A poll the user participated in ended |
| reactions_push_notification | A reaction was added to the user's message |
| reminder | A reminder about pending friend requests |
| suspicious_session | A suspicious session was detected |
| top_messages_push | A digest of top messages |
| trending_content_push | A digest of trending content |
###### Example Push Notification
```json
{
"aps": {
"alert": { "title": "general (My Cool Server)", "body": "hey, are you around?" },
"sound": "default",
"badge": 3
},
"type": "MESSAGE_CREATE",
"notif_type_id": "1",
"notif_instance_id": "1536922843542192241",
"sent_at_ms": "1786502869340",
"channel_id": "1029315212521771020",
"channel_type": "0",
"channel_name": "general",
"guild_id": "1029315212005888060",
"guild_name": "My Cool Server",
"guild_icon": "546242649e3b09a97af7e8f29983837b",
"message_id": "1536922843542192240",
"message_type_": "0",
"message_content": "hey, are you around?",
"user_id": "852892297661906993",
"user_username": "dolfies",
"user_global_name": "Dolfies",
"user_avatar": "14733482e560d9267c0a414b21b2fb8d",
"__category": "can_reply"
}
```
## Acknowledging Notifications
Discord retracts notifications it has already sent by sending another push notification. These types never display anything:
- `CHANNEL_ACK`: the channels in `channel_ids` were read on another device
- `CALL_ACK`: the call in the channels in `channel_ids` was answered on another device
- `CALL_RING_END`: the user is no longer being rung in the channels in `channel_ids`
`sent_at_ms` is the acknowledgement time. Clients should convert it to a snowflake and dismiss the notifications for each acknowledged channel whose newest message is older than it,
leaving anything that arrived after the acknowledgement was sent in place. A notification the user has already replied to inline is kept and re-rendered as replied rather than dismissed.
`CALL_RING_END` is handled differently: rather than being dismissed, the ringing notification is replaced with a silent missed call notification.
iOS clients do not use `CHANNEL_ACK` or `CALL_ACK`. They dismiss stale notifications when the app is foregrounded, by
comparing each delivered notification's `notif_instance_id` against the channel's [read state](/topics/read-state).
## Notification Channels
Android requires every notification to be posted to a notification channel, which the user can configure or disable individually. Channels are gathered into groups in the system settings UI.
Clients register the channels below with the operating system on startup, and pick one for each notification from its `notif_type_id`.
###### Notification Channel
| Value | Group | Importance | Description |
| ------------------ | ------------ | ---------- | -------------------------- |
| calls ^1^ | 111_realtime | 4 | Incoming calls |
| mediaConnections | 111_realtime | 3 | Voice connected |
| gameDetection | 111_realtime | 1 | Game detection |
| directMessages | 222_social | 4 | Direct messages |
| friendRequests | 222_social | 4 | Friend requests |
| reactions | 222_social | 3 | Reactions |
| polls | 222_social | 3 | Polls |
| social | 222_social | 2 | Social |
| messages | 333_server | 4 | Messages |
| forumThreadCreated | 333_server | 4 | Forum notifications |
| guildEventLive | 333_server | 4 | Event notifications |
| guildHighlights | 333_server | 4 | Server highlights |
| stageLive | 333_server | 4 | Stage notifications |
| other | 333_server | 2 | Other server notifications |
| systemMessages | 444_other | 4 | Discord system messages |
| otherHighPriority | 444_other | 4 | Other (high priority) |
| default | 444_other | 2 | Other |
^1^ Clients that support custom call ringtones register one channel per ringtone, named `calls_{ringtone}` (i.e. `calls_default` and `calls_halloween`).
###### Notification Channel Group
| Value | Description |
| ------------ | --------------- |
| 111_realtime | Real-time |
| 222_social | Friends and DMs |
| 333_server | Guilds |
| 444_other | Everything else |
###### Default Notification Channel Mapping
| Notification type | Channel |
| ----------------- | --------------------------------------------- |
| 1 | `directMessages` in DMs, `messages` in guilds |
| 3 | `friendRequests` |
| 4, 6, 13, 16 | `social` |
| 7 | `stageLive` |
| 8 | `guildEventLive` |
| 9 | `forumThreadCreated` |
| 10, 11, 14 | `other` |
| 15 | `polls` |
| 23 | `reactions` |
| 27, 28 | `systemMessages` |
| Anything else | `default` |
`CALL_RING` and `CALL_RING_END` push notifications are always posted to the call channel, regardless of their notification type.
## VOIP Notifications
Incoming calls on iOS are delivered over PushKit rather than APNs, so the system's native call UI can be presented before the app is running. These notifications use a payload of their own, unrelated to the one above.
###### VOIP Push Notification Structure
| Field | Type | Description |
| ----------------- | --------- | ------------------------------------------------------------------ |
| id | string | The UUID of the call, used as the CallKit call identifier |
| type | string | The [type of VOIP push notification](#voip-push-notification-type) |
| channel_id | snowflake | The ID of the channel the call is in |
| user_id | snowflake | The ID of the user who is ringing |
| native_phone_name | string | The caller name to display in the system call UI |
###### VOIP Push Notification Type
| Value | Description |
| ------------- | -------------------------------- |
| CALL_RING | The user is being rung in a call |
| CALL_RING_END | The user is no longer being rung |
Clients register the call with the system as `discord:{channel.id}.{channel.type}.{recipient.id}` for DMs, and `discord:{channel.id}.{channel.type}.{guild.id}` otherwise.
## Endpoints
Register Device
Registers an FCM/APNs push notification token for the client's device. Returns a 204 empty response on success.
###### JSON Params
| Field | Type | Description |
| ----------------------------------- | ------- | ---------------------------------------------------------------------------------------------- |
| provider | string | The [push notification provider](#push-notification-provider) of the device |
| token | string | The push notification token to register |
| voip_provider? ^1^ | string | The VOIP [push notification provider](#push-notification-provider) of the device |
| voip_token? ^1^ | string | The VOIP push notification token to register |
| bypass_server_throttling_supported? | boolean | Whether the client supports bypassing server throttling for push notifications (default false) |
| bundle_id? | string | The bundle ID of the app (default com.discord) |
^1^ VOIP-specific push notification tokens are only used with PushKit on iOS.
Unregister Device
Unregisters an FCM/APNs push notification token for the client's device. Returns a 204 empty response on success.
###### JSON Params
| Field | Type | Description |
| -------- | ------ | --------------------------------------------------------------------------- |
| provider | string | The [push notification provider](#push-notification-provider) of the device |
| token | string | The push notification token to unregister |
Get Device Sync Token
Returns a push notification sync token for the current user. This token can be used to synchronize push notification tokens across multiple accounts.
###### Response Body
| Field | Type | Description |
| ----- | ------ | -------------------------------- |
| token | string | The push notification sync token |
###### Example Response
```json
{ "token": "ODUyODkyMjk3NjYxOTA2OTkz.ZfoufA.rHvCtpfHjr9kdRab1ZTl83PRhhZ" }
```
Sync Devices
Synchronizes the client's FCM/APNs push notification token across multiple accounts.
###### JSON Params
| Field | Type | Description |
| -------------------- | ------------- | --------------------------------------------------------------------------- |
| provider | string | The [push notification provider](#push-notification-provider) of the device |
| token | string | The device push notification token |
| push_sync_tokens ^1^ | array[string] | Device sync tokens for each account |
^1^ A device sync token can be obtained for each account using the [Get Device Sync Token](#get-device-sync-token) endpoint.
###### Response Body
| Field | Type | Description |
| ------------------------ | ------------- | ----------------------------------- |
| invalid_push_sync_tokens | array[string] | Device sync tokens that are invalid |
###### Example Response
```json
{ "invalid_push_sync_tokens": ["ODUyODkyMjk3NjYxOTA2OTkz.ZfoufA.rHvCtpfHjr9kdRab1ZTl83PRhhZ"] }
```
---
# OAuth2
Link: https://docs.discord.food/topics/oauth2
OAuth2 enables application developers to build applications that utilize authentication and data from the Discord API. Within Discord, there are multiple types of OAuth2 authentication.
Supported grants include the authorization code grant, implicit grant, device grant, client credentials, and some modified special-for-Discord flows for bots and webhooks.
## Shared Resources
The first step in implementing OAuth2 is [registering a developer application](/resources/application#create-application) and retrieving your client ID and client secret.
Most people who will be implementing OAuth2 will want to find and utilize a library in the language of their choice. For those implementing OAuth2 from scratch, please see [RFC 6749](https://tools.ietf.org/html/rfc6749) for details.
After you create your application with Discord, make sure that you have your `client_id` and `client_secret` handy. The next step is to figure out which OAuth2 flow is right for your purposes.
###### OAuth2 URLs
| URL | Description |
| ----------------------------------------------- | ----------------------------------------------------------- |
| https://discord.com/oauth2/authorize | Authorization URL |
| https://discord.com/activate | Device Code Authorization URL |
| https://discord.com/api/v10/oauth2/token | Token URL |
| https://discord.com/api/v10/oauth2/token/revoke | [Token Revocation](https://tools.ietf.org/html/rfc7009) URL |
| https://discord.com/api/v10/oauth2/keys | JWKS URI |
| https://discord.com/api/v10/oauth2/userinfo | UserInfo URL |
In accordance with the relevant RFCs, the token and token revocation URLs will **only** accept a content type of `x-www-form-urlencoded`. JSON content is not permitted and will return an error.
Likewise, these endpoints will usually not return typical Discord error responses, opting for RFC-compliant formats.
###### OAuth2 Scopes
These are all the OAuth2 scopes that Discord supports. Some scopes require approval from Discord to use. Requesting them from a user without approval from Discord will lead to unexpected error behavior in the OAuth2 flow.
`bot` and `guilds.join` require you to have a bot account linked to your application. Also, in order to add a user to a guild, your bot has to already belong to that guild.
| Value | Description | Public |
| ---------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------- | ------ |
| account.global_name.update | Allows [updating the user's global name](/resources/user#modify-current-user-account) | No |
| activities.invites.write | Allows [sending activity invites](/resources/message#create-dm-message) | No |
| activities.read | Allows [retrieving user presence and activity data](/resources/presence) | No |
| activities.write | Allows [updating user presence and creating headless sessions](/resources/presence) | No |
| applications.builds.read | Allows [reading branch and build data for the user's applications](/resources/application) | Yes |
| applications.builds.upload | Allows [uploading builds to the user's applications](/resources/application) | No |
| applications.commands ^1^ | Allows [using commands](/interactions/application-commands/) in a guild/user context | Yes |
| applications.commands.permissions.update | Allows [updating the application's own command permissions](/interactions/application-commands#permissions) in guilds the user has permissions in | Yes |
| applications.commands.update ^2^ | Allows your app to update its own [commands](/interactions/application-commands/) | Yes |
| applications.entitlements | Allows [managing entitlements for the user's applications](/resources/entitlement) | Yes |
| applications.store.update | Allows [managing store data (SKUs, store listings, achievements, etc.) for the user's applications](/resources/store) | Yes |
| application_identities.write | Allows [managing application identities](/resources/application) | No |
| bot | Adds the application's bot to a user-selected guild | Yes |
| connections | Allows [retrieving a user's connected accounts](/resources/connected-accounts#list-user-connections), both public and private | Yes |
| dm_channels.read | Allows [reading information about the user's DMs and group DMs](/resources/channel) | No |
| dm_channels.messages.read | Allows reading messages from the user's DMs and group DMs | No |
| dm_channels.messages.write | Allows [sending messages to the user's DMs](/resources/message#create-dm-message) | No |
| email ^3^ | Allows [retrieving a user's email address](/resources/user#get-current-user) | Yes |
| gateway.connect ^3^ | Allows [connecting to the gateway](/gateway/using-gateway#oauth2-and-the-gateway) on behalf of the user | No |
| gdm.join | Allows [adding users to managed group DMs](/resources/channel#add-channel-recipient) | Yes |
| guilds | Allows [retrieving the user's guilds](/resources/guild#list-user-guilds) | Yes |
| guilds.channels.read | Allows [reading the channels in a user's guilds](/resources/channel) | No |
| guilds.join | Allows [joining users to a guild](/resources/guild#add-guild-member) | Yes |
| guilds.members.read | Allows [retrieving a user's member information in a guild](/resources/guild#get-current-guild-member) | Yes |
| identify | Allows [retrieving the current user](/resources/user#get-current-user) | Yes |
| lobbies.write | Allows [managing lobbies](/resources/lobby) | No |
| messages.read | When using RPC, allows reading messages from all client channels (otherwise restricted to application-managed group DMs) | Yes |
| openid | Allows [retrieving basic user information](#get-openid-user-information) and includes an ID token in the token exchange | Yes |
| payment_sources.country_code | Allows retrieving the user's country code | No |
| presences.read | Allows [retrieving user presence](/resources/presence) | No |
| presences.write | Allows [updating user presence](/resources/presence) | No |
| relationships.read ^9^ | Allows [retrieving a user's relationships](/resources/relationships) | Yes |
| relationships.write | Allows [managing a user's relationships](/resources/relationships) | No |
| role_connections.write ^4^ | Allows [updating a user's connection and application-specific metadata](/resources/application#application-role-connection-object) | Yes |
| rpc ^5^ ^6^ | When using RPC, allows controlling the local Discord client; also encompasses all of the below RPC scopes in the majority of scenarios | No |
| rpc.activities.write ^6^ | When using RPC, allows updating a user's activity | Yes |
| ~~rpc.api~~ | ~~Allows accessing the REST API on behalf of the user~~ | ~~No~~ |
| rpc.notifications.read ^6^ | When using RPC, allows you to receive notifications pushed out to the user | Yes |
| rpc.screenshare.read ^6^ | When using RPC, allows reading a user's screenshare status | Yes |
| rpc.screenshare.write ^6^ | When using RPC, allows updating a user's screenshare settings | Yes |
| rpc.video.read ^6^ | When using RPC, allows reading a user's video status | Yes |
| rpc.video.write ^6^ | When using RPC, allows updating a user's video settings | Yes |
| rpc.voice.read ^6^ | When using RPC, allows reading a user's voice settings and listening for voice events | Yes |
| rpc.voice.write ^6^ | When using RPC, allows updating a user's voice settings | Yes |
| voice ^3^ ^7^ | Allows [connecting to voice](/topics/voice-connections) on the user's behalf and seeing all voice members in a guild | No |
| webhook.incoming ^8^ | Creates an application-owned webhook in a user-selected channel and returns it in the token exchange | Yes |
^1^ In a user install context, this scope also allows the application to send DMs to the user.
^2^ Only available through the [client credentials grant](#client-credentials-grant) flow.
^3^ Depends on the `identify` scope being authorized as well.
^4^ Only available through the [authorization code grant](#authorization-code-grant) flow and requires that the [`PUBLIC_OAUTH2_CLIENT` application flag](/resources/application#application-flags) is not set.
^5^ Unless the application is approved for general RPC access, the `rpc` scope is allowed for the application owner and [whitelisted users](/resources/application#list-application-testers) only and requires that the [`EMBEDDED` application flag](/resources/application#application-flags) is not set.
^6^ Access to RPC for web applications requires approval from Discord.
^7^ Also includes `gateway.connect` privileges.
^8^ Only available through the [authorization code grant](#authorization-code-grant) flow.
^9^ Requires the [`SOCIAL_LAYER_INTEGRATION_LIMITED` or `SOCIAL_LAYER_INTEGRATION` application flag](/resources/application#application-flags).
###### Umbrella OAuth2 Scopes
The following scopes are considered "umbrella" scopes, meaning that they are used to request access to multiple scopes at once. These are currently only used by the social layer integration.
| Value | Description |
| ------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| sdk.social_layer_presence | Includes the scopes `activities.invites.write`, `activities.read`, `activities.write`, `application_identities.write`, `gateway.connect`, `identify`, `relationships.read`, and `relationships.write` |
| sdk.social_layer | Includes everything in `sdk.social_layer_presence`, plus `dm_channels.read`, `dm_channels.messages.read`, `dm_channels.messages.write`, `guilds`, `guilds.channels.read`, and `lobbies.write` |
###### Authorization URL Structure
| Field | Type | Description |
| ---------------------- | ----------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| client_id | snowflake | The ID of the application |
| response_type? ^1^ | string | The [type of response to return](#response-type) |
| scope? ^2^ | string | A space-delimited list of scopes to request; may be omitted if the application has a populated [`integration_types_config`](/resources/application#application-object) |
| redirect_uri? ^3^ | string | The URL to redirect to after authorization; must match one of the registered redirect URIs for the application |
| prompt? | string | The [prompt behavior](#prompt-behavior) to use for the authorization flow (default `consent`) |
| state? | string | A unique string to bind the user's request to their authenticated state |
| nonce? | string | A unique string to bind the user's request to their authenticated state; only applicable for authorization code grants with the `openid` scope |
| code_challenge? | string | A code challenge for the [PKCE extension](#pkce) to the authorization code grant; must be used with `code_challenge_method` |
| code_challenge_method? | string | The method used to generate the code challenge (must be `S256`); only applicable for the [PKCE extension](#pkce) to the authorization code grant |
| integration_type? | integer | The [installation context](/resources/application#application-integration-type) for the authorization; only applicable when `scope` contains `applications.commands` (default `GUILD_INSTALL`) |
| permissions? | integer | The [permissions](/topics/permissions) you're requesting; only applicable when `scope` contains `bot` |
| guild_id? | snowflake | The ID of a guild to pre-fill the dropdown picker with; only applicable when `scope` contains `bot`, `applications.commands`, or `webhook.incoming` and `integration_type` is `GUILD_INSTALL` |
| channel_id? | snowflake | The ID of a channel to pre-fill the dropdown picker with; only applicable when `scope` contains `webhook.incoming` |
| disable_guild_select? | boolean ^4^ | Disallows the user from changing the guild dropdown; only applicable when `scope` contains `bot` or `applications.commands`, or `webhook.incoming` and `integration_type` is `GUILD_INSTALL` (default false) |
^1^ Required unless the basic [bot authorization flow](#bot-authorization-flow) is used.
^2^ If the `bot` scope is selected, the `applications.commands` scope is automatically added to the authorization by official clients.
^3^ If a `response_type` is specified and no `redirect_uri` is specified, the user will be redirected to the first registered redirect URI for the application.
^4^ Only accepts `true` or `false`.
###### Response Type
| Value | Description |
| ----- | ---------------------------------------------------------- |
| code | [Authorization code grant](#authorization-code-grant) flow |
| token | [Implicit grant](#implicit-grant) flow |
###### Prompt Behavior
| Value | Description |
| ------- | ---------------------------------------------------------------------------------------------------------------------------- |
| none | Skips the authorization screen and immediately redirects the user; requires previous authorization with the requested scopes |
| consent | Prompts the user to re-approve their authorization |
## State and Security
Before we dive into the semantics of the different OAuth2 grants, we should stop and discuss security, specifically the use of the `state` parameter.
[Cross Site Request Forgery](https://en.wikipedia.org/wiki/Cross-site_request_forgery), or CSRF, and [Clickjacking](https://en.wikipedia.org/wiki/Clickjacking) are security vulnerabilities that must be addressed by individuals implementing OAuth.
This is typically accomplished using the `state` parameter. `state` is sent in the authorization request and returned back in the response and should be a value that binds the user's request to their authenticated state.
For example, `state` could be a hash of the user's session cookie, or some other nonce that can be linked to the user's session.
When a user begins an authorization flow on the client, a `state` is generated that is unique to that user's request. This value is stored somewhere only accessible to the client and the user, i.e. protected by the [same-origin policy](https://en.wikipedia.org/wiki/Same-origin_policy).
When the user is redirected, the `state` parameter is returned. The client validates the request by checking that the `state` returned matches the stored value. If they match, it is a valid authorization request.
If they do not match, it's possible that someone intercepted the request or otherwise falsely authorized themselves to another user's resources, and the request should be denied.
For OpenID Connect, the `nonce` parameter may be used in a similar way instead. Upon receiving the ID token, the client should validate that the `nonce` claim in the ID token matches the `nonce` sent in the authorization request.
While Discord does not require the use of the `state` parameter, we highly recommend that you implement it for the security of your own applications and data.
## Authorization Code Grant
The authorization code grant is what most developers will recognize as "standard OAuth2" and involves retrieving an access code and exchanging it for a user's access token.
It allows the authorization server to act as an intermediary between the client and the resource owner, so the resource owner's credentials are never shared directly with the client.
###### Example Authorization URL
```
https://discord.com/oauth2/authorize?response_type=code&client_id=157730590492196864&scope=identify%20guilds.join&state=15773059ghq9183habn&redirect_uri=https%3A%2F%2Fnicememe.website&prompt=consent&integration_type=0
```
When someone navigates to this URL, they will be prompted to authorize your application for the requested scopes.
On acceptance, they will be redirected to your `redirect_uri`, which will contain an additional query-string parameter, `code`. `state` will also be returned if previously sent, and should be validated at this point.
`prompt` controls how the authorization flow handles existing authorizations. If a user has previously authorized your application with the requested scopes and prompt is set to `consent`, it will request them to reapprove their authorization.
If set to `none`, it will skip the authorization screen and redirect them back to your redirect URI without requesting their authorization. For passthrough scopes, like `bot` and `webhook.incoming`, authorization is always required.
The `integration_type` parameter specifies the [installation context](/resources/application#application-integration-type) for the authorization. The installation context determines where the application will be installed, and is only relevant when `scope` contains `applications.commands`.
When set to `GUILD_INSTALL`, the application will be authorized for installation to a guild. When set to `USER_INSTALL`, the application will be authorized for installation to a user. The application must be configured to support the provided `integration_type`.
###### Example Redirect URL
```
https://nicememe.website/?code=NhhvTDYsFcdgNLnnLijcl7Ku7bEEeee&state=15773059ghq9183habn
```
`code` is now exchanged for the user's access token by making a request to the [token URL](#oauth2-urls) as follows:
###### Example Access Token Exchange
```py
API_ENDPOINT = 'https://discord.com/api/v10'
CLIENT_ID = '332269999912132097'
CLIENT_SECRET = '937it3ow87i4ery69876wqire'
REDIRECT_URI = 'https://nicememe.website'
def exchange_code(code):
data = {
'client_id': CLIENT_ID,
'client_secret': CLIENT_SECRET,
'grant_type': 'authorization_code',
'code': code,
'redirect_uri': REDIRECT_URI
}
headers = {
'Content-Type': 'application/x-www-form-urlencoded'
}
r = requests.post('%s/oauth2/token' % API_ENDPOINT, data=data, headers=headers)
r.raise_for_status()
return r.json()
```
In response, you will receive an [access token response](#oauth2-access-token-object):
###### Example Access Token
```json
{
"token_type": "Bearer",
"access_token": "ODkxNDM2MjMzOTAzOTY0MTYx.6qrZcUqja7812RVdnEKjpzOL4CvHBFG",
"scope": "identify",
"expires_in": 604800,
"refresh_token": "D43f5y0ahjqew82jZ4NViEr2YafMKhue"
}
```
Having the user's access token allows your application to make certain requests to the API on their behalf, restricted to whatever scopes were requested.
## Refresh Token Grant
`expires_in` is how long, in seconds, until the returned access token expires, allowing you to anticipate the expiration and refresh the token. To refresh, make another request to the [token URL](#oauth2-urls) with the following parameters:
###### Example Refresh Token Exchange
```py
API_ENDPOINT = 'https://discord.com/api/v10'
CLIENT_ID = '332269999912132097'
CLIENT_SECRET = '937it3ow87i4ery69876wqire'
REDIRECT_URI = 'https://nicememe.website'
def refresh_token(refresh_token):
data = {
'client_id': CLIENT_ID,
'client_secret': CLIENT_SECRET,
'grant_type': 'refresh_token',
'refresh_token': refresh_token
}
headers = {
'Content-Type': 'application/x-www-form-urlencoded'
}
r = requests.post('%s/oauth2/token' % API_ENDPOINT, data=data, headers=headers)
r.raise_for_status()
return r.json()
```
Boom; fresh [access token response](#oauth2-access-token-object)!
## Implicit Grant
The implicit OAuth2 grant is a simplified flow optimized for in-browser clients. Instead of issuing the client an authorization code to be exchanged for an access token, the client is directly issued an access token. The URL is formatted as follows:
###### Example Authorization URL
```
https://discord.com/oauth2/authorize?response_type=token&client_id=290926444748734499&scope=identify&state=15773059ghq9183habn
```
On redirect, your redirect URI will contain additional **URI fragments** representing a serialiazed [access token response](#oauth2-access-token-object): `access_token`, `token_type`, `expires_in`, `scope`, and [`state`](#state-and-security) (if specified).
**These are not query string parameters.** Be mindful of the "#" character:
###### Example Redirect URL
```
https://findingfakeurlsisprettyhard.tv/#access_token=RTfP0OK99U3kbRtHOoKLmJbOn45PjL&token_type=Bearer&expires_in=604800&scope=identify&state=15773059ghq9183habn
```
There are tradeoffs in using the implicit grant flow. It is both quicker and easier to implement, but rather than exchanging a code and getting a token returned in a secure HTTP body, the access token is returned in the URI fragment, which makes it possibly exposed to unauthorized parties.
**You also are not returned a refresh token, so the user must explicitly reauthorize once their token expires.**
## Client Credentials Grant
The client credential flow is a quick and easy way for bot developers to get their own bearer tokens for testing purposes. By making a request to the [token URL](#oauth2-urls) with a grant type of `client_credentials`,
you will be returned an access token for the bot owner. Therefore, always be super-extra-very-we-are-not-kidding-like-really-be-secure-make-sure-your-info-is-not-in-your-source-code careful with your `client_id` and `client_secret`. We don't take kindly to imposters around these parts.
You can specify scopes with the `scope` parameter, which is a list of [OAuth2 scopes](#oauth2-scopes) separated by spaces:
###### Example Client Credentials Request
```py
API_ENDPOINT = 'https://discord.com/api/v10'
CLIENT_ID = '332269999912132097'
CLIENT_SECRET = '937it3ow87i4ery69876wqire'
def get_token():
data = {
'client_id': CLIENT_ID,
'client_secret': CLIENT_SECRET,
'grant_type': 'client_credentials',
'scope': 'identify connections'
}
headers = {
'Content-Type': 'application/x-www-form-urlencoded'
}
r = requests.post('%s/oauth2/token' % API_ENDPOINT, data=data, headers=headers)
r.raise_for_status()
return r.json()
```
In return, you will receive an access token (without a refresh token):
###### Example Access Token
```json
{
"token_type": "Bearer",
"access_token": "6qrZcUqja7812RVdnEKjpzOL4CvHBFG",
"scope": "identify connections",
"expires_in": 604800
}
```
Note that team-owned applications are limited to the scopes `applications.builds.read`, `applications.builds.upload`, `applications.commands.update`, `applications.entitlements`, `applications.store.update`, and `identify`.
This is because these applications are owned by a pseudo-user that is not meant to be operated like a normal user account.
## Device Code Grant
The device code grant is a flow that allows users to authenticate on devices that do not have a web browser or are otherwise unable to complete the OAuth2 flow in a traditional way.
To use the device code grant, you first need to make a request to the [device code authorize URL](#oauth2-urls) to retrieve a device code and user code:
###### Example Device Code Request
```py
API_ENDPOINT = 'https://discord.com/api/v10'
CLIENT_ID = '332269999912132097'
CLIENT_SECRET = '937it3ow87i4ery69876wqire'
def get_device_code():
data = {
'client_id': CLIENT_ID,
'client_secret': CLIENT_SECRET,
'scope': 'identify connections'
}
headers = {
'Content-Type': 'application/x-www-form-urlencoded'
}
r = requests.post('%s/oauth2/device/authorize' % API_ENDPOINT, data=data, headers=headers)
r.raise_for_status()
return r.json()
```
In return, you will receive a response containing the necessary information to start the authorization process:
###### Example Device Code Response
```json
{
"device_code": "PZVqIuLlME19uotfsUATN65Ytgbejbhj7Eob8qzali",
"user_code": "ZAW6C586",
"verification_uri": "https://discord.com/activate",
"verification_uri_complete": "https://discord.com/activate?user_code=ZAW6C586",
"expires_in": 300,
"interval": 5
}
```
You should display the `user_code` and `verification_uri` to the user, or embed the `verification_uri_complete` link in a QR code for them to scan.
While you are prompting the user, you should also start polling the [token URL](#oauth2-urls) to check if the user has completed the authorization process every `interval` seconds or until the `expires_in` time has passed:
###### Example Device Code Exchange
```py
API_ENDPOINT = 'https://discord.com/api/v10'
CLIENT_ID = '332269999912132097'
CLIENT_SECRET = '937it3ow87i4ery69876wqire'
def exchange_device_code(device_code):
data = {
'client_id': CLIENT_ID,
'client_secret': CLIENT_SECRET,
'grant_type': 'urn:ietf:params:oauth:grant-type:device_code',
'device_code': device_code
}
headers = {
'Content-Type': 'application/x-www-form-urlencoded'
}
r = requests.post('%s/oauth2/token' % API_ENDPOINT, data=data, headers=headers)
if r.status_code == 200:
return r.json()
elif r.status_code == 400:
data = r.json()
if r['error'] == 'authorization_pending':
# The user has not yet completed the authorization process
return None
elif r['error'] == 'slow_down':
# Increase the polling interval
return None
elif r['error'] == 'expired_token':
# The device code has expired, you need to request a new one
raise Exception('The device code has expired, please request a new one')
elif r['error'] == 'access_denied':
# The user has denied the authorization request
raise Exception('The user has denied the authorization request')
r.raise_for_status()
```
If the user has completed the authorization process, you will receive an [access token response](#oauth2-access-token-object) as usual.
## PKCE
Discord supports the [Proof Key for Code Exchange (PKCE)](https://tools.ietf.org/html/rfc7636) extension to the OAuth2 authorization code flow.
PKCE allows users to authenticate with your application without sharing your client secret.
This enables user-facing applications such as browser extensions or mobile apps to manage authentication securely.
The flow runs entirely between the user and Discord, allowing users to refresh their own bearer tokens without needing your application's client secret.
If you want your clients to be able to refresh their own tokens automatically, you will need to [enable the `PUBLIC_OAUTH2_CLIENT` application flag](/resources/application#application-flags).
When using PKCE, your application can also utilize custom schemes in [`redirect_uris`](/resources/application#application-object).
### Code Verifier
Firstly, the client needs to create a code verifier, `code_verifier`:
- The verifier must be a string of 43 - 128 characters.
- The characters must be alphanumeric (`A-Z`, `a-z`, `0-9`) and hyphens `-`, periods `.`, underscores `_`, and tildes `~`.
- The code verifier must also be randomly generated for each authorization request.
The PKCE specification recommends that you generate a 32 byte random string and base64 URL encode it without padding, resulting in a 43-byte string.
```py
code_verifier = base64.urlsafe_b64encode(os.urandom(32)).rstrip(b'=').decode('utf-8')
```
### Code Challenge
Next, the client needs to create a code challenge, `code_challenge`, which is the base64 URL-encoded SHA256 hash of the `code_verifier`, without padding.
SHA256 is the only supported hashing algorithm for PKCE in Discord's OAuth2 implementation.
```py
sha256 = hashlib.sha256(code_verifier.encode('utf-8')).digest()
code_challenge = base64.urlsafe_b64encode(sha256).decode('utf-8').rstrip('=')
```
The client then constructs the authorization URL with the `code_challenge` and `code_challenge_method` parameters:
### Example Authorization URL
```
https://discord.com/oauth2/authorize?response_type=code&client_id=290926444748734499&scope=identify&code_challenge=CNPVOxIUDw5vcUaWT3Gn8fjrEeZs-kMEqpk2eNzqsmQ&code_challenge_method=S256&state=15773059ghq9183habn
```
If successful, Discord will send you to the redirect URL with the usual authorization code.
The redirect URL can safely be forwarded to the client, as the `code_challenge` is not sensitive information. However, it is also acceptable to keep the credentials on the server instead.
When exchanging the authorization code for an access token, the client must include the `code_verifier` in the request. Note that to omit the `client_secret` field as shown below, you must have the [`PUBLIC_OAUTH2_CLIENT` application flag](/resources/application#application-flags) set.
###### Example Access Token Exchange
```py
API_ENDPOINT = 'https://discord.com/api/v10'
CLIENT_ID = '332269999912132097'
CODE_VERIFIER = 'Qs-0Scio0ScPJDYOFy1NYsOAsj6Rb6cP-Y12N9pbwV0'
REDIRECT_URI = 'https://nicememe.website'
def exchange_code(code):
data = {
'client_id': CLIENT_ID,
'grant_type': 'authorization_code',
'code': code,
'code_verifier': CODE_VERIFIER,
'redirect_uri': REDIRECT_URI
}
headers = {
'Content-Type': 'application/x-www-form-urlencoded'
}
r = requests.post('%s/oauth2/token' % API_ENDPOINT, data=data, headers=headers)
r.raise_for_status()
return r.json()
```
This will give you an [access token response](#oauth2-access-token-object) as usual.
You can now [refresh the token](#refresh-token-grant) on the client, omitting the `client_secret` field depending on the [`PUBLIC_OAUTH2_CLIENT` application flag](/resources/application#application-flags).
## Bots
So, what are bot accounts?
### Bot vs User Accounts
Discord's API provides a separate type of user account dedicated to automation, called a bot account. Bot accounts can be created through the [applications API](/resources/application) and do not have an email and password.
Unlike the normal OAuth2 flow, bot accounts have full access to all API routes without using bearer tokens, and can connect to the [Real Time Gateway](/gateway/using-gateway).
Automating normal user accounts (generally called "self-bots") outside of the OAuth2/bot API is forbidden, and can result in an account termination if found. Don't get found :)
Bot accounts have a few differences in comparison to normal user accounts, namely:
1. Bots are added to guilds through the OAuth2 API, and cannot accept normal invites.
2. Bots cannot have friends, nor be added to or join Group DMs.
3. Verified bots do not have a maximum number of Guilds.
4. Bots have an entirely separate set of [Rate Limits](/topics/rate-limits#rate-limits).
### Bot Authorization Flow
Bot authorization is a special server-less and callback-less OAuth2 flow that makes it easy for users to add bots to guilds. The URL you create looks similar to what we use for full stack implementation:
###### Example Authorization URL
```
https://discord.com/oauth2/authorize?client_id=157730590492196864&scope=bot&permissions=1
```
In the case of bots, the `scope` parameter should be set to `bot`. There's also a new parameter, `permissions`, which is an integer corresponding to the [permission calculations](/topics/permissions#bitwise-permission-flags) for the bot.
You'll also notice the absence of `response_type` and `redirect_uri`. Bot authorization does not require these parameters because there is no need to retrieve the user's access token.
When the user navigates to this page, they'll be prompted to add the bot to a guild in which they have proper permissions. On acceptance, the bot will be added. Super easy!
If you happen to already know the ID of the guild the user will add your bot to, you can provide this ID in the URL as a `guild_id=GUILD_ID` parameter.
When the authorization page loads, that guild will be preselected in the dialog if that user has permissions to add the bot to that guild. You can use this in conjunction with the parameter `disable_guild_select=true` to disallow the user from picking a different guild.
If your bot is super specific to your private clubhouse, or you just don't like sharing, you can make sure [`integration_public` is disabled on your application](/resources/application#application-object). If unchecked, only you can add the bot to guilds.
If marked as public, anyone with your bot's ID can add it to guilds in which they have proper permissions.
### Advanced Bot Authorization
Devs can extend the bot authorization functionality. You can request additional scopes outside of `bot`, which will prompt a continuation into a complete [authorization code grant flow](#authorization-code-grant) and add the ability to request the user's access token.
If you request any scopes outside of `bot` or `applications.commands`, `response_type` is again mandatory.
When receiving the access code on redirect, there will be additional query-string parameters of `guild_id` and `permissions`.
**These parameters should only be used as hints, as they are easily faked by malicious users.** To be sure of the relationship between your bot and the guild, consider [enabling `integration_require_code_grant` on your application](/resources/application#application-object).
Enabling it requires anyone adding your bot to a guild to go through a full OAuth2 [authorization code grant flow](#authorization-code-grant), meaning the integration will not be created until your backend [exchanges the code for a token](#example-access-token-exchange).
When you retrieve the user's access token, you'll also receive information about the guild to which your bot was added through an additional `guild` object in the response.
### Multi-Factor Authentication Requirement
For bots with [elevated permissions](/topics/permissions#bitwise-permission-flags) (permissions with a `*` next to them), we enforce multi-factor authentication on the owner's account when added to guilds that have guild-wide MFA enabled.
## Webhooks
Discord's webhook flow is a specialized version of an [authorization code](#authorization-code-grant) implementation. In this case, the `scope` query-string parameter needs to include `webhook.incoming`:
###### Example Authorization URL
```
https://discord.com/oauth2/authorize?response_type=code&client_id=157730590492196864&scope=webhook.incoming&state=15773059ghq9183habn&redirect_uri=https%3A%2F%2Fnicememe.website
```
When the user navigates to this URL, they will be prompted to select a channel in which to allow the webhook. When the webhook is [executed](/resources/webhook#execute-webhook), it will post its message into this channel.
On acceptance, the user will be redirected to your `redirect_uri`. The URL will contain the `code` query-string parameter which should be [exchanged for an access token](#example-access-token-exchange) as usual.
In return, you will receive a slightly modified token response, with an additional `webhook` object:
###### Example Access Token
```json
{
"token_type": "Bearer",
"access_token": "GNaVzEtATqdh173tNHEXY9ZYAuhiYxvy",
"scope": "webhook.incoming",
"expires_in": 604800,
"refresh_token": "PvPL7ELyMDc1836457XCDh1Y8jPbRm",
"webhook": {
"type": 1,
"id": "347114750880120863",
"name": "Application Name Here",
"avatar": "cc7e0aa58a4224a281fbb8217b808a72",
"channel_id": "345626669224982402",
"guild_id": "290926792226357250",
"application_id": "310954232226357250",
"token": "kKDdjXa1g9tKNs0-_yOwLyALC9gydEWP6gr9sHabuK1vuofjhQDDnlOclJeRIvYK-pj_",
"url": "https://discord.com/api/webhooks/347114750880120863/kKDdjXa1g9tKNs0-_yOwLyALC9gydEWP6gr9sHabuK1vuofjhQDDnlOclJeRIvYK-pj_"
}
}
```
From this object, you should store the `webhook.id` and `webhook.token`. See the [execute webhook](/resources/webhook#execute-webhook) documentation for how to send messages with the webhook.
Any user that wishes to add your webhook to their channel will need to go through the full OAuth2 flow, and a new webhook is created each time. If you wish to send a message to all your webhooks,
you'll need to iterate over each stored `id:token` combination and make `POST` requests to each one. Be mindful of our [Rate Limits](/topics/rate-limits#rate-limits)!
## OAuth2 Access Token Object
###### Access Token Structure
| Field | Type | Description |
| -------------- | --------------------------------------------------- | ------------------------------------------------------ |
| token_type | string | The type of token, always `Bearer` |
| access_token | string | The access token |
| id_token? ^1^ | string | The ID token |
| scope | string | The scopes the user has authorized, separated by space |
| expires_in | integer | Duration (in seconds) after which the token expires |
| refresh_token? | string | The refresh token, if applicable |
| guild? | [guild](/resources/guild#guild-object) object | The guild to which the bot was added, if applicable |
| webhook? | [webhook](/resources/webhook#webhook-object) object | The webhook created, if applicable |
^1^ Only returned from the [Get Provisional Account Token](#get-provisional-account-token) endpoint and when using the [authorization code grant with the `openid` scope](#authorization-code-grant).
## OAuth2 Authorization Object
###### OAuth2 Authorization Structure
| Field | Type | Description |
| ------------ | ----------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------- |
| id | snowflake | The ID of the authorization |
| scopes | array[string] | The scopes the user has authorized the application for |
| application | partial [application](/resources/application#application-object) object | The authorized application |
| disclosures? | array[integer] | The [application disclosures](/resources/application#application-disclosure-type) that have been acknowledged by the user |
## Endpoints
Get Current Authorization Information
Returns info about the current authorization.
This endpoint is only usable with an OAuth2 access token.
###### Response Body
| Field | Type | Description |
| ----------- | ----------------------------------------------------------------------- | --------------------------------------------------------------------------------- |
| application | partial [application](/resources/application#application-object) object | The current application |
| scopes | array[string] | The scopes the user has authorized the application for |
| expires | ISO8601 timestamp | When the access token expires |
| user? | partial [user](/resources/user#user-object) object | The user who has authorized, if the user has authorized with the `identify` scope |
Get OpenID Connect Keys
Returns the JSON Web Key Set used to verify OpenID Connect ID tokens issued by Discord. This endpoint is compliant with the [OpenID Connect specification](https://openid.net/specs/openid-connect-core-1_0.html#SigEnc).
Get OpenID User Information
Returns OpenID user information for the current authorization. This endpoint is compliant with the [OpenID Connect specification](https://openid.net/specs/openid-connect-core-1_0.html#UserInfo).
This endpoint is only usable with an OAuth2 access token with the `openid` scope.
##### Response Body
| Field | Type | Description |
| ---------------------- | ------- | --------------------------------------------------- |
| sub | string | The ID of the user |
| email ^1^ | ?string | The user's email address |
| email_verified ^1^ | boolean | Whether the email on this account has been verified |
| preferred_username ^2^ | string | The user's username |
| nickname ^2^ | ?string | The user's display name |
| picture ^2^ | string | The user's avatar URL |
| locale ^2^ | string | The user's locale |
^1^ Requires the `email` scope.
^2^ Requires the `identify` scope.
##### Example Response
```json
{
"sub": "852892297661906993",
"email": "dolfies@amazing.email",
"email_verified": true,
"preferred_username": "dolfies",
"nickname": "Dolfies",
"picture": "https://cdn.discordapp.com/avatars/852892297661906993/c78ef8fb1db15a3d5f1b4c057856c5c9.png",
"locale": "en-US"
}
```
Get OAuth2 Device Code
Retrieves a device code and user code for the [device code grant](#device-code-grant) flow.
###### Form Params
| Field | Type | Description |
| ---------------------- | --------- | ------------------------------------------- |
| client_id? ^1^ | snowflake | The ID of the application |
| client_secret? ^1^ ^2^ | string | The client secret of the application |
| scope? | string | A space-delimited list of scopes to request |
^1^ You can also pass your `client_id` and `client_secret` as basic authentication with `client_id` as the username and `client_secret` as the password.
^2^ Not required if the application has the [`PUBLIC_OAUTH2_CLIENT` application flag](/resources/application#application-flags).
###### Response Body
| Field | Type | Description |
| ------------------------- | ------- | -------------------------------------------------------------------------------------- |
| device_code | string | The device code to use for the device code grant |
| user_code | string | The user code to display to the user for authorization |
| verification_uri | string | The URL to display to the user for authorization |
| verification_uri_complete | string | The complete URL to redirect the user to for authorization, including the user code |
| expires_in | integer | The duration (in seconds) after which the device code expires |
| interval | integer | The interval (in seconds) at which to poll the token endpoint for authorization status |
Get OAuth2 Device Flow
Returns information about the OAuth2 device code grant flow.
###### JSON Params
| Field | Type | Description |
| --------- | ------ | --------------- |
| user_code | string | The device code |
###### Response Body
| Field | Type | Description |
| ----------------- | ------------- | ------------------------------------------------------------------ |
| scopes | array[string] | The scopes the user is authorizing the application for |
| client_id | snowflake | The ID of the application |
| two_way_link_code | ?string | The code to use for two-way linking |
| type | string | The [status of the OAuth2 device flow](#oauth2-device-flow-status) |
###### OAuth2 Device Flow Status
| Value | Description |
| ------- | ------------------------------------------------------------ |
| pending | The device flow is pending |
| granted | The device flow is completed and an access token was granted |
| denied | The device flow is completed but no access token was granted |
Finish OAuth2 Device Flow
Finishes the OAuth2 device code grant flow. Returns a 204 empty response on success.
###### JSON Params
| Field | Type | Description |
| --------- | ------ | ---------------------------------------------------------------------------------------------- |
| user_code | string | The device code |
| result | string | The [result of the flow](#oauth2-device-flow-status) (only `granted` and `denied` are allowed) |
Get OAuth2 Token
Retrieves an OAuth2 access token for the given application credentials. Implements a number of different grants. Returns an [oauth2 access token](#oauth2-access-token-object) object on success.
###### Form Params
| Field | Type | Description |
| ------------------------ | --------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| grant_type | string | The [type of grant to use](#oauth2-grant-type) |
| client_id? ^1^ | snowflake | The ID of the application |
| client_secret? ^1^ ^2^ | string | The client secret of the application |
| code? | string | The authorization code to exchange for a token |
| code_verifier? | string | The code verifier for the [PKCE extension](#pkce) to the authorization code grant |
| redirect_uri? | string | The URL to redirect to after authorization; must match one of the registered redirect URIs for the application; only applicable for `authorization_code` grants |
| refresh_token? | string | The refresh token to exchange for a new access token |
| device_code? | string | The device code to exchange for an access token |
| scope? | string | A space-delimited list of scopes to request; only applicable for `client_credentials` grants |
| external_auth_type? ^3^ | string | The [type of the external authentication provider](#external-provider-authentication-type) |
| external_auth_token? ^3^ | string | The external authentication token |
^1^ You can also pass your `client_id` and `client_secret` as basic authentication with `client_id` as the username and `client_secret` as the password.
^2^ Required if the application does not have the [`PUBLIC_OAUTH2_CLIENT` application flag](/resources/application#application-flags), the `grant_type` is `client_credentials`, or the `grant_type` is `authorization_code` and `code_verifier` is not provided.
^3^ Providing these fields will merge the associated provisional account with the user account that is being authenticated. See the [User Merge Operation Completed](/gateway/gateway-events#user-merge-operation-completed) Gateway event for more information.
###### OAuth2 Grant Type
| Value | Description |
| -------------------------------------------- | ---------------------------------------------------------- |
| authorization_code | [Authorization code grant](#authorization-code-grant) flow |
| refresh_token | [Refresh token grant](#refresh-token-grant) flow |
| client_credentials | [Client credentials grant](#client-credentials-grant) flow |
| urn:ietf:params:oauth:grant-type:device_code | [Device code grant](#device-code-grant) flow |
Revoke OAuth2 Token
Revokes the given OAuth2 access or refresh token. Returns an empty object on success.
When any valid access or refresh token is revoked, all of the application's access and refresh tokens for that user are immediately invalidated.
###### Form Params
| Field | Type | Description |
| ---------------------- | --------- | ------------------------------------- |
| token | string | The access or refresh token to revoke |
| client_id? ^1^ | snowflake | The ID of the application |
| client_secret? ^1^ ^2^ | string | The client secret of the application |
^1^ You can also pass your `client_id` and `client_secret` as basic authentication with `client_id` as the username and `client_secret` as the password.
^2^ Not required if the application has the [`PUBLIC_OAUTH2_CLIENT` application flag](/resources/application#application-flags).
Get Provisional Account Token
Retrieves an access token for a provisional account with the given credentials. Returns an [OAuth2 access token](#oauth2-access-token-object) object on success.
The response will only contain a `refresh_token` for OIDC when the application does not have the [`PUBLIC_OAUTH2_CLIENT` application flag](/resources/application#application-flags).
If an account isn't found but the provided external authentication token is valid, a new provisional account will be created.
When attempting to authenticate a provisional account that has been merged with a user account, the request will fail with a 400 bad request and a special error response body:
```json
{
"message": "User account is non-provisional and should be authed through OAuth2",
"code": 530010,
"user_id": "1001086404203389018",
"provider_type": "OIDC",
"provider_id": "https://auth.example.com",
"provider_issued_user_id": "123456789"
}
```
This indicates that the provisional account has been merged with a user account, and the user should be authenticated through OAuth2 instead, unless the provisional account is [unmerged](#unmerge-provisional-account) first.
- For [bot-issued tokens](#get-provisional-account-token-with-bot), the `preferred_global_name` specified will be used.
- For OIDC, a provisional account's display name will be the value of the `preferred_username` claim, if specified in
the ID token. This field is optional and should be between 1 and 32 characters. If not specified, the user's display
name will default to the user's unique username, which Discord generates on creation.
- For [Steam session tickets](https://partner.steamgames.com/doc/features/auth), the display name of the user's Steam
account is used as the provisional account's display name.
- For [EOS Auth](https://dev.epicgames.com/docs/epic-account-services/auth/auth-interface) Access Tokens or ID Tokens,
the name of the user's Epic account is used as the provisional account's display name. EOS Connect ID Tokens do
not expose any username, and thus the game will need to configure the display name manually.
- For [Unity Services ID Tokens](https://services.docs.unity.com/docs/client-auth/),
the display name of the user's Unity Player Account is used as the provisional account's display name.
- For [Apple ID Tokens](https://developer.apple.com/documentation/signinwithapplerestapi),
the name of the user's Apple ID account is used as the provisional account's display name.
- For PlayStation Network ID Tokens, the name of the user's PlayStation Network account is used as the provisional account's display name.
To change the display name of a provisional account, use the [Modify Current User Account](/resources/user#modify-current-user-account) endpoint.
###### JSON Params
| Field | Type | Description |
| ------------------- | --------- | ------------------------------------------------------------------------------------------ |
| client_id | snowflake | The ID of the application |
| client_secret? ^1^ | string | The client secret of the application |
| external_auth_type | string | The [type of the external authentication provider](#external-provider-authentication-type) |
| external_auth_token | string | The external authentication token |
^1^ Not required if the application has the [`PUBLIC_OAUTH2_CLIENT` application flag](/resources/application#application-flags).
###### External Provider Authentication Type
| Value | Description |
| --------------------------------- | --------------------------------------------------------------------------------------------------- |
| OIDC | OpenID Connect ID token |
| EPIC_ONLINE_SERVICES_ACCESS_TOKEN | Access token for Epic Online Services (supports EOS Auth access tokens) |
| EPIC_ONLINE_SERVICES_ID_TOKEN | ID token for Epic Online Services (supports both EOS Auth + Connect ID tokens) |
| STEAM_SESSION_TICKET | A Steam authentication ticket for web generated with `discord` set as the `identity` |
| UNITY_SERVICES_ID_TOKEN | ID token for Unity Auth Services |
| DISCORD_BOT_ISSUED_ACCESS_TOKEN | An access token for a user authenticated [via a bot token](#get-provisional-account-token-with-bot) |
| APPLE_ID_TOKEN | ID token for Apple ID |
| PLAYSTATION_NETWORK_ID_TOKEN | ID token for PlayStation Network |
Exchange Provisional Account Child Token
Exchanges a parent application token for a child application token. Returns an [OAuth2 access token](#oauth2-access-token-object) object on success.
###### JSON Params
| Field | Type | Description |
| -------------------- | --------- | --------------------------------------------------- |
| child_application_id | snowflake | The ID of the child application |
| parent_access_token | string | The parent application token (max 10240 characters) |
Get Provisional Account Token with Bot
Retrieves an access token for a provisional account with the given credentials. Returns an [oauth2 access token](#oauth2-access-token-object) object on success.
If an account isn't found, a new provisional account will be created.
When attempting to authenticate a provisional account that has been merged with a user account, the request will fail with a 400 bad request and a special error response body:
```json
{
"message": "User account is non-provisional and should be authed through OAuth2",
"code": 530010,
"user_id": "142007603549962240",
"provider_type": "DISCORD_BOT",
"provider_id": null,
"provider_issued_user_id": "123456789"
}
```
This indicates that the provisional account has been merged with a user account, and the user should be authenticated through OAuth2 instead, unless the provisional account is [unmerged](#unmerge-provisional-account) first.
This endpoint is not usable by user accounts.
###### JSON Params
| Field | Type | Description |
| ---------------------- | ------ | -------------------------------------------------------- |
| external_user_id | string | The ID of the user to authenticate (max 1024 characters) |
| preferred_global_name? | string | The preferred global name for the user (1-32 characters) |
Unmerge Provisional Account
Unmerge a provisional account. Returns a 204 empty response on success.
Unmerging invalidates all access and refresh tokens for the user. Users can also unmerge their account by [unauthorizing the OAuth2 application](#revoke-oauth2-token).
###### JSON Params
| Field | Type | Description |
| ------------------- | --------- | ------------------------------------------------------------------------------------------ |
| client_id | snowflake | The ID of the application |
| client_secret? ^1^ | string | The client secret of the application |
| external_auth_type | string | The [type of the external authentication provider](#external-provider-authentication-type) |
| external_auth_token | string | The external authentication token |
^1^ Not required if the application has the [`PUBLIC_OAUTH2_CLIENT` application flag](/resources/application#application-flags).
Unmerge Provisional Account with Bot
Unmerge a provisional account. Returns a 204 empty response on success.
Unmerging invalidates all access and refresh tokens for the user. Users can also unmerge their account by [unauthorizing the OAuth2 application](#revoke-oauth2-token).
This endpoint is not usable by user accounts.
###### JSON Params
| Field | Type | Description |
| ---------------- | ------ | --------------------------------------------------- |
| external_user_id | string | The ID of the user to unmerge (max 1024 characters) |
Get OAuth2 Authorizations
Returns a list of [OAuth2 authorization](#oauth2-authorization-object) objects.
Only the most recent OAuth2 authorization per application is returned.
If you need to retrieve all authorizations for an application, use the [Get Application OAuth2 Authorizations](#get-application-oauth2-authorizations) endpoint.
###### Query String Params
| Field | Type | Description |
| --------------- | ---------------- | ------------------------------------------------------ |
| application_ids | array[snowflake] | The applications to return authorizations for (max 50) |
Get Application OAuth2 Authorizations
Returns a list of [OAuth2 authorization](#oauth2-authorization-object) objects for the given application ID.
Preview OAuth2 Authorization
Returns information about a possible OAuth2 authorization.
If unauthenticated, this endpoint will redirect to the OAuth2 authorization page with the specified params.
###### Query String Params
| Field | Type | Description |
| ---------------------- | --------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| client_id | snowflake | The ID of the application |
| response_type? ^1^ | string | The [type of response to return](#response-type) |
| scope | string | A space-delimited list of scopes to request; may be omitted if the application has a populated [`integration_types_config`](/resources/application#application-object) |
| redirect_uri? ^2^ | string | The URL to redirect to after authorization; must match one of the registered redirect URIs for the application |
| state? | string | A unique string to bind the user's request to their authenticated state |
| nonce? | string | A unique string to bind the user's request to their authenticated state; only applicable for authorization code grants with the `openid` scope |
| code_challenge? | string | A code challenge for the [PKCE extension](#pkce) to the authorization code grant; must be used with `code_challenge_method` |
| code_challenge_method? | string | The method used to generate the code challenge (must be `S256`); only applicable for the [PKCE extension](#pkce) to the authorization code grant |
| integration_type? | integer | The [installation context](/resources/application#application-integration-type) for the authorization; only applicable when `scope` contains `applications.commands` (default `GUILD_INSTALL`) |
^1^ Required unless the basic [bot authorization flow](#bot-authorization-flow) is used.
^2^ If a `response_type` is specified and no `redirect_uri` is specified, the response will contain the first redirect URI registered for the application.
###### Response Body
| Field | Type | Description |
| ---------------- | ----------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------ |
| application | partial [application](/resources/application#application-object) object | The application that is being authorized |
| user | partial [user](/resources/user#user-object) object | The user who is authorizing |
| authorized | boolean | Whether the user has already authorized the application with these scopes, meaning consent can be skipped |
| integration_type | integer | The [installation context](/resources/application#application-integration-type) for the authorization |
| redirect_uri? | ?string | The URL to redirect to after authorization; only present if `response_type` is specified |
| bot? | partial [user](/resources/user#user-object) object | The bot user that will be added to the guild; only present the `bot` scope is requested |
| guilds? | array[[oauth2 guild](#oauth2-guild-structure) object] | The user's guilds; only present if `integration_type` is `GUILD_INSTALL` and the `bot` or `applications.commands` scope is requested |
###### OAuth2 Guild Structure
| Field | Type | Description |
| ----------- | --------- | -------------------------------------------------------------------------------------------- |
| id | snowflake | The ID of the guild |
| name | string | The name of the guild (2-100 characters) |
| icon | ?string | The guild's [icon hash](/reference#cdn-formatting) |
| mfa_level | integer | Required [MFA level](/resources/guild#mfa-level) for administrative actions within the guild |
| permissions | string | [Permissions](/topics/permissions#bitwise-permission-flags) the user has in the guild |
###### Example OAuth2 Guild
```json
{
"id": "81384788765712384",
"name": "Discord API",
"icon": "a363a84e969bcbe1353eb2fdfb2e50e6",
"mfa_level": 1,
"permissions": "1095530297282240"
}
```
Create OAuth2 Authorization
Authorizes the user for the given OAuth2 application. May fire a [Guild Integrations Update](/gateway/gateway-events#guild-integrations-update), [Integration Create](/gateway/gateway-events#integration-create), [User Application Update](/gateway/gateway-events#user-application-update), and/or [User Connections Update](/gateway/gateway-events#user-connections-update) Gateway event.
###### Query String Params
| Field | Type | Description |
| ---------------------- | --------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| client_id | snowflake | The ID of the application |
| response_type? ^1^ | string | The [type of response to return](#response-type) |
| scope | string | A space-delimited list of scopes to request; may be omitted if the application has a populated [`integration_types_config`](/resources/application#application-object) |
| redirect_uri? ^2^ | string | The URL to redirect to after authorization; must match one of the registered redirect URIs for the application |
| state? | string | A unique string to bind the user's request to their authenticated state |
| nonce? | string | A unique string to bind the user's request to their authenticated state; only applicable for authorization code grants with the `openid` scope |
| code_challenge? | string | A code challenge for the [PKCE extension](#pkce) to the authorization code grant; must be used with `code_challenge_method` |
| code_challenge_method? | string | The method used to generate the code challenge (must be `S256`); only applicable for the [PKCE extension](#pkce) to the authorization code grant |
^1^ Required unless the basic [bot authorization flow](#bot-authorization-flow) is used.
^2^ If a `response_type` is specified and no `redirect_uri` is specified, the user will be redirected to the first registered redirect URI for the application.
###### JSON Params
| Field | Type | Description |
| ------------------- | -------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| authorize? | boolean | Whether to authorize the user for the application (default false) |
| integration_type? | integer | The [installation context](/resources/application#application-integration-type) for the authorization (default `GUILD_INSTALL`) |
| permissions? ^1^ | string | The permissions to request for the bot user in the guild; only applicable when the `bot` scope is requested |
| guild_id? | snowflake | The ID of the guild to which the application should be added or the webhook should be created; only applicable when the `bot`, `applications.commands`, or `webhook.incoming` scope is requested and `integration_type` is `GUILD_INSTALL` |
| webhook_channel_id? | snowflake | The ID of the channel where the webhook should be created; only applicable when the `webhook.incoming` scope is requested |
| dm_settings? | [application DM settings](#application-dm-settings-structure) object | The DM settings for the application; only applicable when the `applications.commands` scope is requested and `integration_type` is `USER_INSTALL` |
| location_context? | [oauth2 location context](#oauth2-location-context-structure) object | The location context of the authorization within the client, used for analytics |
^1^ If no permissions are requested, an integration role is not created for the bot user in the guild.
###### Application DM Settings Structure
| Field | Type | Description |
| ------------------ | ------- | ------------------------------------------------------------------------------------ |
| allow_mobile_push? | boolean | Whether to allow mobile push notifications for the application's DMs (default false) |
###### OAuth2 Location Context Structure
| Field | Type | Description |
| ------------- | --------- | -------------------------------------------------------------------------------------------- |
| guild_id? | snowflake | The ID of the guild where the authorization is being created |
| channel_id? | snowflake | The ID of the channel where the authorization is being created |
| channel_type? | integer | The [type of channel](/resources/channel#channel-type) the authorization is being created in |
###### Response Body
| Field | Type | Description |
| ------- | ------ | ------------------------------------------------------------------------------------------ |
| url ^1^ | string | The URL to redirect the user to, containing the authorization code, access token, or error |
^1^ If a `redirect_uri` doesn't exist, `https://discord.com` will be used.
Get OAuth2 Authorization
Returns an [OAuth2 authorization](#oauth2-authorization-object) object for the given ID.
Delete OAuth2 Authorization
Revokes the given authorization. Returns a 204 empty response on success. Fires multiple [OAuth2 Token Revoke](/gateway/gateway-events#oauth2-token-revoke) and optionally a [User Application Remove](/gateway/gateway-events#user-application-remove) and [User Connections Update](/gateway/gateway-events#user-connections-update) Gateway event.
---
# Reports
Link: https://docs.discord.food/topics/reports
Discord has a [reporting system](https://discord.com/safety/360044103651-reporting-abusive-behavior-to-discord) that allows users to report messages or profiles that violate Discord's [Terms of Service](https://discord.com/terms) or [Community Guidelines](https://discord.com/guidelines).
When a user creates a report, it is sent to Discord's Trust and Safety team for review. The team evaluates the report and takes appropriate action, which may include warning the user, temporarily suspending their account, or permanently banning them from the platform.
There are multiple versions of the reporting API:
- [**V1**](#reports-v1): The original version of the reporting API, also known as dirt. Supports reporting messages and users.
- [**V2**](#reports-v2): An updated version of the original reporting API that includes detailed report types and saves a snapshot of the reported message for review. Supports reporting messages only.
- [**V3**](#reports-v3): The latest version of the reporting API, known as in-app reports, that includes additional report types and improved functionality. Supports reporting messages, users, guilds, scheduled events, and more.
- [**DSA**](#dsa): A special version of reports V3 that can be used by users living in the European Union to comply with the [Digital Services Act](https://en.wikipedia.org/wiki/Digital_Services_Act).
## Considerations
When using the reporting API, keep the following in mind:
- Only resources you have access to can be reported. For example, you cannot report a message in a private channel you cannot access.
- You must have a verified email on your account to create reports.
- You cannot report your own messages or profile.
- Reports are anonymous. The user being reported will not be notified of who reported them.
- Abuse of the reporting system may result in action being taken against your account.
## Reports V1
The original version of the reporting API, also known as "dirt". Supports reporting messages and users.
### Endpoints
Get Report Reasons
Returns a list of [report reason](#report-reason-structure) objects that can be used when creating a report for a message or user.
###### Query String Params
Either `channel_id` and `message_id`, or `user_id` must be provided.
| Field | Type | Description |
| ---------- | --------- | --------------------------------------- |
| message_id | snowflake | The ID of the message to report |
| channel_id | snowflake | The ID of the channel the message is in |
| user_id | snowflake | The ID of the user to report |
###### Report Reason Structure
| Field | Type | Description |
| ----------- | ------- | ---------------------------------- |
| reason | integer | A unique identifier for the reason |
| label | string | The display name of the reason |
| description | string | A brief description of the reason |
###### Example Report Reason
```json
{
"reason": 2,
"label": "Spam or Phishing Links",
"description": "Fake links, invites to a server via bot, malicious links or attachments."
}
```
Create Report
Creates a report for a message or user.
###### JSON Params
| Field | Type | Description |
| -------------- | --------- | -------------------------------------------------------- |
| message_id ^1^ | snowflake | The ID of the message to report |
| channel_id ^1^ | snowflake | The ID of the channel the message is in |
| user_id ^1^ | snowflake | The ID of the user to report |
| reason | integer | The [report reason](#report-reason-structure) identifier |
^1^ Either `channel_id` and `message_id`, or `user_id` must be provided.
###### Response Body
| Field | Type | Description |
| ----- | --------- | ---------------------------- |
| id | snowflake | The ID of the created report |
## Reports V2
An updated version of the original reporting API that includes detailed report types and saves a snapshot of the reported message for review. Supports reporting messages only.
### Endpoints
Get Report Options
Returns a list of [report option](#report-option-structure) objects that can be used when creating a report for a message.
###### Report Option Structure
| Field | Type | Description |
| ------------- | ------------------------------------------------------------------------- | -------------------------------------------------------- |
| value | string | A unique identifier for the report option |
| label | string | The display name of the report option |
| description | string | A brief description of the report option |
| sub_question? | string | Prompt to ask the user for in order to select a sub-type |
| sub_types? | array[[report option sub-type](#report-option-sub-type-structure) object] | Sub-types for the report option |
###### Report Option Sub-Type Structure
| Field | Type | Description |
| ----- | ------ | --------------------------------------- |
| value | string | A unique identifier for the sub-type |
| label | string | The display name of the report sub-type |
###### Example Report Option
```json
{
"value": "spamming",
"label": "Spamming",
"description": "Unsolicited advertisements",
"sub_question": "How is this spam?",
"sub_types": [
{
"value": "sub_spam",
"label": "User is sending spam messages or requests"
},
{
"value": "sub_spambot",
"label": "This is a spambot account"
}
]
}
```
Stage Report
Stages a report for a message, returning a token that can be used to create the report containing the serialized message data.
###### Response Body
| Field | Type | Description |
| ----- | ------ | ----------------------- |
| token | string | The signed report token |
Create Staged Report
Creates a report for a message, including a snapshot of the message for review. Requires the `MANAGE_MESSAGES` permission if the channel is in a guild. Returns a 204 empty response on success.
###### JSON Params
| Field | Type | Description |
| --------------- | ------ | --------------------------------------------------------------------- |
| token | string | The signed report token |
| report_type | string | The [report option](#report-option-structure) value |
| report_subtype? | string | The [report option sub-type](#report-option-sub-type-structure) value |
| subject | string | The subject of the report (max 300 characters) |
| description | string | Additional details for the report (max 800 characters) |
## Reports V3
The latest version of the reporting API, known as "in-app reports", that includes additional report types and improved functionality. Supports reporting messages, users, guilds, scheduled events, and more.
### DSA
A special version of reports V3 that can be used by users living in the European Union to comply with the [Digital Services Act](https://en.wikipedia.org/wiki/Digital_Services_Act).
Unlike regular reports, DSA reports do not require an account to submit. Instead, users simply need to [verify an email address](#verify-unauthenticated-report).
Additionally, instead of the standard [report menu types](#report-menu-type), DSA reporters fetch their allowed report types from [a separate endpoint](#get-unauthenticated-report-capabilities).
Note that the unauthenticated reporting endpoints require that either authentication or a [fingerprint](/topics/experiments#fingerprints) is provided for experiment tracking purposes.
### Report Menu Object
###### Report Menu Structure
| Field | Type | Description |
| --------------- | ---------------------------------------------------------- | --------------------------------------------------------------------- |
| name | string | The [type of report menu](#report-menu-type) |
| version | string | The version of the report menu schema (currently `1.0`) |
| variant | string | The variant of the menu |
| postback_url | string | The [API URL endpoint for submitting the report](#submit-report-menu) |
| language? | string | The language code for the menu (default `en`) |
| root_node_id | integer | The ID of the starting node in the menu flow |
| success_node_id | integer | The ID of the node shown on successful submission |
| fail_node_id | integer | The ID of the node shown on failed submission |
| nodes | map[integer, [report node](#report-node-structure) object] | A map of node IDs to their corresponding node objects |
###### Report Node Structure
| Field | Type | Description |
| ------------------------ | --------------------------------------------------------------- | ---------------------------------------------------------------- |
| id ^1^ | integer | The unique identifier for the node |
| report_type? | string | The report type identifier if this is a submission node |
| key | string | A unique key identifier for the node |
| header | string | The main header text displayed for this node |
| subheader? | string | Optional secondary header text |
| info? | string | Optional informational text or warning |
| children | array[[report node child](#report-node-child-structure) object] | Child options that lead to other nodes |
| elements | array[[report element](#report-element-structure) object] | UI elements to display on this node |
| button? | [report button](#report-button-structure) object | The action button for this node |
| is_multi_select_required | boolean | Whether multi-select elements require at least one selection |
| is_auto_submit | boolean | Whether this node automatically submits without user interaction |
^1^ Node IDs are unique across all report menu types and often reused in multiple menus.
###### Report Button Structure
| Field | Type | Description |
| ------ | -------- | ---------------------------------------------------------------------- |
| type | string | The [type of button](#report-button-type) |
| target | ?integer | The target node ID for navigation (only applicable for `next` buttons) |
###### Report Button Type
| Value | Description |
| ------ | --------------------------------------------- |
| next | Navigates to the next node in the report flow |
| submit | Submits the report |
| done | Exits the modal successfully |
| cancel | Exits the modal without submitting the report |
###### Report Node Child Structure
This object is represented as an array of the following fields:
| Field | Type | Description |
| -------------- | ------- | -------------------------------------- |
| name | string | The display label for the child option |
| target_node_id | integer | The node ID this option navigates to |
###### Report Element Structure
| Field | Type | Description |
| ------------------- | ------- | ---------------------------------------------------------------- |
| name | string | The name identifier for the element |
| type | string | The [type of element](#report-element-type) |
| data | object | Element-specific data, varies by type |
| should_submit_data | boolean | Whether this element's data should be included in the submission |
| skip_if_unlocalized | boolean | Whether to skip this element if not localized |
| is_localized | boolean | Whether this element has been localized |
###### Report Element Type
| Value | Description | Receive Data | Send Data |
| ----------------------------- | -------------------------------------------------- | -------------------------------------------------------------------------- | ------------------------ |
| checkbox | A checkbox input element | array[array[string]] ^1^ | array[array[string]] ^1^ |
| dropdown | A dropdown select input element | [dropdown element](#dropdown-element-structure) object | string |
| free_text | A free text input element | [free text element](#free-text-element-structure) object | string |
| ~~radio~~ | ~~A radio button input element~~ |
| success | A success element | null |
| fail | A fail element | null |
| breadcrumbs | The user's progress through the report flow | null |
| text_line_resource | A phone number for the user to text | [text line resource element](#text-line-resource-element-structure) object |
| text | A block of text | [text resource element](#text-line-resource-element-structure) object |
| external_link | An external link reference | [external link element](#external-link-element-structure) object |
| ~~more_you_can_do~~ | ~~Additional actions that can be taken~~ |
| block_users | An option to block the reported user | null |
| ignore_users | An option to ignore the reported user | null |
| mute_users | An option to mute the reported user | null |
| delete_message | An option to delete the reported message | null |
| leave_guild | An option to leave the reported guild | null |
| deauthorize_app | An option to deauthorize the reported app | null |
| share_with_parents | An option to share the report with parents | null |
| settings_upsells | Additional settings actions that can be taken | null |
| guild_preview | Displays a preview of the reported guild | null |
| guild_discovery_preview | Displays a preview of the reported guild listing | null |
| guild_directory_entry_preview | Displays a preview of the reported directory entry | null |
| guild_scheduled_event_preview | Displays a preview of the reported scheduled event | null |
| message_preview | Displays a preview of the reported message | null |
| channel_preview | Displays a preview of the reported channel | null |
| user_preview | Displays a preview of the reported user | null |
| app_preview | Displays a preview of the reported application | null |
| widget_preview | Displays a preview of the reported profile widget | null |
^1^ Nested array is in the format (name, label, description?).
###### Dropdown Element Structure
| Field | Type | Description |
| ------- | ----------------------------------------------------------- | -------------------------------------- |
| title | string | The title of the dropdown element |
| options | array[[dropdown option](#dropdown-option-structure) object] | The selectable options in the dropdown |
###### Dropdown Option Structure
| Field | Type | Description |
| ----- | ------ | ------------------------------------ |
| value | string | The unique identifier for the option |
| label | string | The display name of the option |
###### Free Text Element Structure
| Field | Type | Description |
| --------------- | ------- | ----------------------------------------- |
| title? | string | The title of the free text element |
| subtitle? | string | An subtitle for the element |
| placeholder? | string | Placeholder text for the input field |
| rows | integer | The number of visible text rows |
| character_limit | integer | The maximum number of characters allowed |
| pattern? | string | A regex pattern that the input must match |
###### Text Line Resource Element Structure
| Field | Type | Description |
| ------------ | ------- | --------------------------------------- |
| title | string | The title of the text line resource |
| body | string | The body text of the text line resource |
| sms | string | The SMS number to text |
| sms_body? | string | Example SMS message to send |
| is_localized | boolean | Whether this element has been localized |
###### Text Resource Element Structure
| Field | Type | Description |
| ------------ | ------- | --------------------------------------- |
| header | string | The header text of the text resource |
| body | string | The body text of the text resource |
| is_localized | boolean | Whether this element has been localized |
###### External Link Element Structure
| Field | Type | Description |
| ----------------- | ------- | --------------------------------------- |
| url | string | The URL for the external link |
| link_text | string | The display text for the external link |
| link_description? | string | A description of the link's purpose |
| is_localized | boolean | Whether this element has been localized |
###### Report Menu Type
| Value | Description |
| --------------------- | -------------------------------- |
| guild | Report a guild |
| guild_discovery | Report a guild discovery listing |
| guild_directory_entry | Report a guild directory entry |
| guild_scheduled_event | Report a guild scheduled event |
| message | Report a message |
| stage_channel | Report a stage channel |
| first_dm | Report the first message in a DM |
| user | Report a user |
| application | Report an application |
| widget | Report a profile widget |
###### Example Report Menu
```json
{
"name": "user",
"variant": "3",
"version": "1.0",
"postback_url": "/api/reporting/user",
"root_node_id": 1,
"success_node_id": 1,
"fail_node_id": 1,
"nodes": {
"1": {
"id": 1,
"key": "GENERIC_SUBMIT",
"header": "Report Summary",
"subheader": "Review your report before submitting.",
"info": null,
"button": {
"type": "submit",
"target": null
},
"elements": [
{
"name": "breadcrumbs",
"type": "breadcrumbs",
"data": null,
"should_submit_data": false,
"skip_if_unlocalized": false,
"is_localized": true
}
],
"report_type": null,
"children": [],
"is_multi_select_required": false,
"is_auto_submit": false
}
}
}
```
### Endpoints
Get Report Menu
Returns a [report menu](#report-menu-object) object for the specified [type](#report-menu-type). The menu contains a hierarchical tree of nodes that guide users through the reporting process, including questions, options, and submission steps.
###### Query String Params
| Field | Type | Description |
| -------- | ------ | -------------------------------------------------------------------------------- |
| variant? | string | The version variant of the menu to retrieve (max 256 characters, default latest) |
Submit Report Menu
Submits a completed report based on the user's navigation through a report menu. This endpoint processes the collected information from the menu flow and creates a formal report for review by Discord's Trust and Safety team.
###### JSON Params
| Field | Type | Description |
| ------------------------- | -------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| version | string | The version of the report menu schema that was used |
| variant | string | The variant of the menu that was used |
| name | string | The [report menu type](#report-menu-type) |
| language | string | The language code used for the report |
| breadcrumbs | array[integer] | Node IDs clicked in the report menu flow, representing the user's path through the menu |
| elements? | map[string, array[string]] | Map of [element names to their selected values](#report-element-type) (for checkboxes and other inputs) |
| channel_id? | snowflake | The ID of the channel being reported (required for [`message`, `first_dm`, `stage_channel`, and `guild_directory_entry` report menus](#report-menu-type)) |
| message_id? | snowflake | The ID of the message being reported (required for [`message` and `first_dm` report menus](#report-menu-type)) |
| guild_id? | snowflake | The ID of the guild being reported (required for [`guild`, `stage_channel`, `guild_scheduled_event`, `guild_directory_entry`, and `guild_discovery` report menus](#report-menu-type)) |
| stage_instance_id? | snowflake | The ID of the stage instance being reported (required for [`stage_channel` report menus](#report-menu-type)) |
| guild_scheduled_event_id? | snowflake | The ID of the scheduled event being reported (required for [`guild_scheduled_event` report menus](#report-menu-type)) |
| reported_user_id? | snowflake | The ID of the user being reported (required for [`user` report menus](#report-menu-type)) |
| application_id? | snowflake | The ID of the application being reported (required for [`application` report menus](#report-menu-type)) |
| user_id? | snowflake | The ID of the user being reported (required for [`widget` report menus](#report-menu-type)) |
| widget_id? | snowflake | The ID of the profile widget being reported (required for [`widget` report menus](#report-menu-type)) |
###### Response Body
| Field | Type | Description |
| --------- | --------- | ---------------------------- |
| report_id | snowflake | The ID of the created report |
Query Unauthenticated Report Eligibility
Queries whether the user can use unauthenticated reporting. Returns an empty object on success.
Get Unauthenticated Report Capabilities
Returns the report menu types available for unauthenticated reporting.
###### Response Body
| Field | Type | Description |
| ------------ | ------------- | ------------------------------- |
| capabilities | array[string] | The available report menu types |
Get Unauthenticated Report Verification Code
Sends a verification code to the user's email address to initiate the unauthenticated reporting process for the specified type (must be one of the types returned by [Get Unauthenticated Report Capabilities](#get-unauthenticated-report-capabilities)). Returns an empty object on success.
###### JSON Params
| Field | Type | Description |
| ----- | ------ | ----------------------------------------------------------------------- |
| name | string | The report menu type (same as the `type` path parameter) |
| email | string | The email address to send the verification code to (max 320 characters) |
Verify Unauthenticated Report
Verifies the email code sent to the user to confirm their email address for unauthenticated reporting for the specified type (must be one of the types returned by [Get Unauthenticated Report Capabilities](#get-unauthenticated-report-capabilities)).
###### JSON Params
| Field | Type | Description |
| ----- | ------ | ---------------------------------------------------------- |
| name | string | The report menu type (same as the `type` path parameter) |
| email | string | The email address used to request the code |
| code | string | The verification code sent to the email (max 6 characters) |
###### Response Body
| Field | Type | Description |
| ----- | ------ | ---------------------------- |
| token | string | The email verification token |
Get Unauthenticated Report Menu
Returns a [report menu](#report-menu-object) object for the specified type (must be one of the types returned by [Get Unauthenticated Report Capabilities](#get-unauthenticated-report-capabilities)).
The menu contains a hierarchical tree of nodes that guide users through the reporting process, including questions, options, and submission steps.
###### Query String Params
| Field | Type | Description |
| -------- | ------ | -------------------------------------------------------------------------------- |
| variant? | string | The version variant of the menu to retrieve (max 256 characters, default latest) |
Submit Unauthenticated Report Menu
Submits a completed unauthenticated report based on the user's navigation through a report menu. This endpoint processes the collected information from the menu flow and creates a formal report for review by Discord's Trust and Safety team.
###### JSON Params
| Field | Type | Description |
| ----------- | -------------------------- | ----------------------------------------------------------------------------------------------------------------- |
| version | string | The version of the report menu schema that was used |
| variant | string | The variant of the menu that was used |
| name | string | The [report menu type](#report-menu-type) |
| language | string | The language code used for the report |
| breadcrumbs | array[integer] | Node IDs clicked in the report menu flow, representing the user's path through the menu |
| elements? | map[string, array[string]] | Map of [element names to their selected values](#report-element-type) (for checkboxes and other inputs) |
| email_token | string | The verification token obtained from the [Verify Unauthenticated Report](#verify-unauthenticated-report) endpoint |
Request Report Review
Submits a request to have a report on your account reviewed. Report review links are present in emails sent informing you of actions taken on your account.
When clicked, these links redirect to `https://discord.com/report-review?token=...`, where the token can be used with this endpoint to request a review.
Returns an empty object on success.
###### JSON Params
| Field | Type | Description |
| ----- | ------ | ------------------------------------------------------------ |
| token | string | The report review token obtained from the report review link |
---
# Cloud Uploads
Link: https://docs.discord.food/topics/cloud-uploads
You can upload large attachments quickly directly to Discord's Google Cloud storage bucket, using the [endpoints below](#endpoints) to generate upload URLs, and sending each generated URL a `PUT` request with the intended attachment as the body.
This allows you to upload up a file up to **500 MiB** directly to Google Cloud. Note that [file size limits](/reference#uploading-files) will still apply when sending the attachment in a message.
An example implementation in Python pseudocode would be:
```py
import requests
import os
url = "https://discord.com/api/v10/channels//attachments"
headers = {
"Authorization": "Bot "
}
filename = "cat.png"
size = os.stat(filename).st_size
json = {
"files": [{
"file_size": size,
"filename": filename
}]
}
r = requests.post(url, headers=headers, json=json)
r.raise_for_status()
upload = r.json()['attachments'][0]
with open(filename, "r") as f:
data = f.read()
r = requests.put(upload['upload_url'], data=data)
r.raise_for_status()
upload_filename = upload['upload_filename']
```
Now, instead of sending the attachment again in a form body in the request, you can just send the `upload_filename`! For example:
```json
{
"content": "look at my cute cat!",
"attachments": [
{
"id": "0",
"filename": "cat.png",
"uploaded_filename": "6a08e58a-265f-485a-8c85-5cd4df0edde0/cat.png"
}
]
}
```
### Upload Attachment Object
###### Upload Attachment Structure
| Field | Type | Description |
| ---------------------- | ---------- | ---------------------------------------------------------------------------------------------------------------------------------------- |
| id? | ?snowflake | The ID of the attachment to reference in the response |
| filename | string | The name of the file being uploaded (max 1024 characters) |
| file_size | integer | The size of the file being uploaded in bytes |
| is_clip? ^1^ ^2^ | boolean | Whether the file being uploaded is a [clipped recording of a stream](https://support.discord.com/hc/en-us/articles/16861982215703-Clips) |
| original_content_type? | string | The attachment's original [media type](https://en.wikipedia.org/wiki/Media_type) |
^1^ When uploading a clip, an increased default file size limit of **100 MiB** applies.
^2^ Only applicable within [Create Message Attachments](#create-message-attachments) endpoint.
### Cloud Attachment Object
###### Cloud Attachment Structure
| Field | Type | Description |
| --------------- | ---------- | ----------------------------------------------------------- |
| id | ?snowflake | The ID of the attachment upload, if provided in the request |
| upload_url | string | The URL to upload the file to |
| upload_filename | string | The name of the uploaded file |
### Endpoints
Create Message Attachments
Creates attachment URLs to upload the intended attachments directly to Discord's GCP storage bucket. Returns an array of [cloud attachment](#cloud-attachment-object) objects. Requires the same permissions as uploading an attachment inline with a message. See [above](#cloud-uploads) for more information.
###### JSON Params
| Field | Type | Description |
| ----- | ------------------------------------------------------------ | ------------------------------------------------------------------------- |
| files | array[[upload attachment](#upload-attachment-object) object] | The target files to create a URL for, containing the name and size (1-10) |
###### Example Response
```json
{
"attachments": [
{
"id": "23",
"upload_url": "https://discord-attachments-uploads-prd.storage.googleapis.com/87e49c99-43f8-4a33-baad-5a834c94424c/cat.png?upload_id=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
"upload_filename": "87e49c99-43f8-4a33-baad-5a834c94424c/cat.png"
}
]
}
```
Create Guild Product Attachments
Creates attachment URLs to upload the intended attachments directly to Discord's GCP storage bucket. Returns an array of [cloud attachment](#cloud-attachment-object) objects. See [above](#cloud-uploads) for more information.
###### JSON Params
| Field | Type | Description |
| ----- | ------------------------------------------------------------ | ------------------------------------------------------------------------- |
| files | array[[upload attachment](#upload-attachment-object) object] | The target files to create a URL for, containing the name and size (1-10) |
Create Gravity Attachments
Creates attachment URLs to upload the intended attachments directly to Discord's GCP storage bucket. Returns an array of [cloud attachment](#cloud-attachment-object) objects. See [above](#cloud-uploads) for more information.
###### JSON Params
| Field | Type | Description |
| ----- | ------------------------------------------------------------ | ------------------------------------------------------------------------- |
| files | array[[upload attachment](#upload-attachment-object) object] | The target files to create a URL for, containing the name and size (1-10) |
Delete Attachment
Deletes an attachment from Discord's GCP storage bucket. Returns a 204 empty response on success.
This endpoint should be used to delete an uploaded attachment that was not used. See [above](#cloud-uploads) for more information.
Refresh Attachment URLs
Refreshes the URLs of attachments that were uploaded to Discord's CDN. The provided URLs do not have to be valid or signed. Existing query string parameters are preserved.
###### JSON Params
| Field | Type | Description |
| --------------- | ------------- | --------------------------------------------- |
| attachment_urls | array[string] | The URLs of the attachments to refresh (1-50) |
###### Response Body
| Field | Type | Description |
| -------------- | --------------------------------------------------------------------- | ------------------ |
| refreshed_urls | array[[refreshed attachment](#refreshed-attachment-structure) object] | The refreshed URLs |
###### Refreshed Attachment Structure
| Field | Type | Description |
| --------- | ------ | ----------------- |
| original | string | The provided URL |
| refreshed | string | The refreshed URL |
###### Example Response
```json
{
"refreshed_urls": [
{
"original": "https://cdn.discordapp.com/attachments/1012345678900020080/1234567891233211234/my_image.png?ex=65d903de&is=65c68ede&hm=2481f30dd67f503f54d020ae3b5533b9987fae4e55f2b4e3926e08a3fa3ee24f&",
"refreshed": "https://cdn.discordapp.com/attachments/1012345678900020080/1234567891233211234/my_image.png?ex=66143372&is=6601be72&hm=5a90a0ac363d9de3619044102ffe963041517f0e2f78baecabfc2f544a14eace&"
}
]
}
```
---
# Application Commands
Link: https://docs.discord.food/interactions/application-commands
Application commands are commands that an application can register to Discord. They provide users a first-class way of interacting directly with your application that feels deeply integrated into Discord.
###### Application Command Naming
`CHAT_INPUT` and `PRIMARY_ENTRY_POINT` command names and command option names must match the regex `^[-_'\p{L}\p{N}\p{sc=Deva}\p{sc=Thai}]{1,32}$` with the unicode flag set. If there is a lowercase variant of any letters used, you must use those.
Characters with no lowercase variants and uncased letters are still allowed. `USER` and `MESSAGE` commands may be mixed case and can include spaces.
### Application Command Object
###### Application Command Structure
| Field | Type | Description | Valid Types |
| ----------------------------------- | ------------------------------------------------------------------------------------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------- |
| id? ^1^ | snowflake | The ID of the command | All |
| type? | integer | The type of command (default `CHAT_INPUT`) | All |
| application_id ^2^ | snowflake | The ID of the application that the command belongs to | All |
| guild_id? ^2^ | snowflake | The ID of the guild the command is for | All |
| name ^5^ | string | The name of the command (1-32 characters) | All |
| name_localizations? | ?map[string, string] | The localized name for each [locale](/reference#locales) (values follow same restrictions as `name`) | All |
| name_localized? ^2^ ^5^ | ?string | The localized name of the command | All |
| name_default? ^2^ ^4^ ^5^ | string | The name of the command | All |
| description ^5^ | string | The description of the command (1-100 characters) | All |
| description_localizations? | ?map[string, string] | The localized description for each [locale](/reference#locales) (values follow same restrictions as `description`) | All |
| description_localized? ^2^ ^5^ | ?string | The localized description of the command | All |
| description_default? ^2^ ^4^ ^5^ | string | The description of the command | All |
| options? | array[[application command option](#application-command-option-structure) object] | The options for the command (max 25) | `CHAT_INPUT` |
| default_member_permissions | ?string | The default required permissions to call the command | All |
| dm_permission? ^3^ **(deprecated)** | boolean | Whether the command is available in DMs with the application (default true) | All |
| permissions? ^4^ | [application command index permissions](#application-command-index-permissions-structure) object | The command's permissions for the user in the guild | All |
| nsfw? | boolean | Whether the command is age-restricted (default false) | All |
| integration_types? ^3^ | array[integer] | The [installation contexts](/resources/application#application-integration-type) where the command is available (defaults to application's configured contexts) | All |
| global_popularity_rank? ^2^ ^3^ ^4^ | integer | The popularity rank of the application command | All |
| contexts? ^3^ | ?array[integer] | The [interaction context](/interactions/receiving-and-responding#interaction-context-type) where the command can be used | All |
| version ^2^ | snowflake | An autoincrementing version identifier updated during substantial record changes | All |
| handler? ^3^ | integer | [How the command should be handled when called](#application-command-handler-type) | `PRIMARY_ENTRY_POINT` |
^1^ This field is always present when received.
^2^ This field is received only and cannot be set.
^3^ Only applicable for globally-scoped commands.
^4^ Only available within [application command index](#application-command-index-object) objects.
^5^ Within [application command index](#application-command-index-object) objects, if a `name_localized` is determined, it will be serialized as `name`, with the original `name` being serialized as `name_default`. The same applies to `description_localized` and `description_default`.
###### Application Command Type
| Value | Name | Description |
| ----- | ------------------- | ------------------------------------------------------------------------------- |
| 1 | CHAT_INPUT | Slash commands; a text-based command that shows up when a user types `/` |
| 2 | USER | An UI-based command that shows up when you right click or tap on an user |
| 3 | MESSAGE | An UI-based command that shows up when you right click or tap on a message |
| 4 | PRIMARY_ENTRY_POINT | An UI-based command that represents the primary way to invoke an app's activity |
###### Application Command Option Structure
Required options must be listed before optional ones.
| Field | Type | Description |
| -------------------------- | ----------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------- |
| type | integer | The [type of the option](#application-command-option-type) |
| name | string | The name of the option (1-100 characters) |
| name_localizations? | ?map[string, string] | The localized name for each [locale](/reference#locales) (values follow same restrictions as `name`) |
| name_localized? ^1^ | ?string | The localized name of the option (1-100 characters) |
| description | string | The description of the option (1-100 characters) |
| description_localizations? | ?map[string, string] | The localized description for each [locale](/reference#locales) (values follow same restrictions as `description`) |
| description_localized? ^1^ | ?string | The localized description of the option (1-100 characters) |
| required? | boolean | Whether the option is required (default false, only applicable when `type` is not [`SUB_COMMAND` or `SUB_COMMAND_GROUP`](#application-command-option-type)) |
| choices? | array[[application command option choice](#application-command-option-choice-structure) object] | The choices for the user to pick from (max 25, only applicable for [`STRING`, `INTEGER`, and `NUMBER`](#application-command-option-type) options) |
| options? | array[[application command option](#application-command-option-structure) object] | The nested options (only applicable if the option is a subcommand or subcommand group) |
| channel_types? | array[integer] | The allowed [channel types](/resources/channel#channel-type) (only applicable for [`CHANNEL`](#application-command-option-type) options) |
| min_value? | float \| integer | The minimum value permitted (only applicable for [`INTEGER` and `NUMBER`](#application-command-option-type) options) |
| max_value? | float \| integer | The maximum value permitted (only applicable for [`INTEGER` and `NUMBER`](#application-command-option-type) options) |
| min_length? | integer | The minimum length (0-6000, only applicable for [`STRING`](#application-command-option-type) options) |
| max_length? | integer | The maximum length (0-6000, only applicable for [`STRING`](#application-command-option-type) options) |
| autocomplete? | boolean | Whether the option can be autocompleted (only applicable for [`STRING`, `INTEGER`, and `NUMBER`](#application-command-option-type) options) |
| file_types? ^2^ | array[[file type](/reference#file-types)] | The file types permitted to be uploaded (max 10, only applicable for [`ATTACHMENT`](#application-command-option-type) options) |
^1^ This field is received only and cannot be set.
^2^ This field can only be set and is not received.
###### Application Command Option Type
| Value | Name | Description |
| ----- | ----------------- | ----------------------------------------------------- |
| 1 | SUB_COMMAND | A subcommand |
| 2 | SUB_COMMAND_GROUP | A group of subcommands |
| 3 | STRING | A string |
| 4 | INTEGER | An integer between -2^53^ and 2^53^ |
| 5 | BOOLEAN | A boolean |
| 6 | USER | An user |
| 7 | CHANNEL | A channel (includes all channel types by default) |
| 8 | ROLE | A role |
| 9 | MENTIONABLE | A mentionable entity (currently only users and roles) |
| 10 | NUMBER | A float/integer between -2^53^ and 2^53^ |
| 11 | ATTACHMENT | An [attachment](/resources/message#attachment-object) |
###### Application Command Option Choice Structure
If you specify `choices` for an option, they are the **only** valid values for an user to pick.
| Field | Type | Description |
| ------------------- | -------------------------- | ---------------------------------------------------------------------------------------------------- |
| name | string | The name of the choice (1-100 characters) |
| name_localizations? | ?map[string, string] | The localized name for each [locale](/reference#locales) (values follow same restrictions as `name`) |
| name_localized? ^1^ | ?string | The localized name of the choice (1-100 characters) |
| value | float \| integer \| string | The value of the choice (max 100 characters if string) |
^1^ This field is received only and cannot be set.
###### Application Command Handler Type
| Value | Name | Description |
| ----- | --------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| 1 | APP_HANDLER | The application handles the interaction using an interaction token |
| 2 | DISCORD_LAUNCH_ACTIVITY | Discord handles the interaction by launching an embedded activity and sending a follow-up message without coordinating with the app |
| 3 | APP_HANDLER_LAUNCH_ACTIVITY | The application handles the interaction using an interaction token and can only use [`LAUNCH_ACTIVITY`](/interactions/receiving-and-responding#interaction-callback-type) for responding |
## Application Command Index Object
Multiple different resources have application command indexes, including guilds, users, and applications themselves.
###### Application Command Index Structure
| Field | Type | Description |
| -------------------- | ------------------------------------------------------------------------------- | -------------------------------------------------------- |
| applications | array[[command index application](#command-index-application-structure) object] | The applications relevant to the requested resource |
| application_commands | array[[application command](#application-command-object) object] | The application commands |
| version | snowflake | A snowflake representing when commands were last updated |
###### Application Command Index Permissions Structure
| Field | Type | Description |
| --------- | ----------------------- | ----------------------------------------------------------------------------------------------- |
| user? | boolean | Whether the user can use application commands unless overridden by command permissions |
| roles? | map[snowflake, boolean] | Whether specific roles can use application commands unless overridden by command permissions |
| channels? | map[snowflake, boolean] | Whether specific channels can use application commands unless overridden by command permissions |
###### Command Index Application Structure
| Field | Type | Description |
| ----------------------------- | ------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------- |
| id | snowflake | The ID of the application |
| name | string | The name of the application |
| description | string | The description of the application |
| icon | ?string | The application's [icon hash](/reference#cdn-formatting) |
| permissions? | [application command index permissions](#application-command-index-permissions-structure) object | The application-wide command permissions for the user |
| bot? ^1^ | partial [user](/resources/user#user-object) object | The bot attached to this application |
| bot_id? | snowflake | The ID of the bot user attached to this application |
| flags | string | The [application's flags](/resources/application#application-flags) |
| embedded_activity_config? ^2^ | partial [embedded activity config](/resources/application#embedded-activity-config-object) object | The embedded activity configuration for the application |
^1^ Only included when fetched from the [Get Application Command Index](#get-application-command-index) endpoint.
^2^ Embedded activity config objects will only contain the `supported_platforms` field.
###### Example Command Index Application
```json
{
"id": "891436233903964161",
"name": "Lightbulb",
"description": "💡 Let there be light",
"icon": "546242649e3b09a97af7e8f29983837b",
"permissions": {
"roles": {
"1029330445336313927": false
},
"channels": {
"1029316811088478299": false
}
},
"bot_id": "891436233903964161",
"flags": "0",
"embedded_activity_config": {
"supported_platforms": ["web"]
}
}
```
## Authorizing Your Application
Application commands do not depend on a bot user in the guild; they use the [interactions](/interactions/receiving-and-responding) model. To create commands in a guild, your application must be authorized with the `applications.commands` scope.
Requesting the `bot` scope will implicitly direct the client to request the `applications.commands` scope as well.
When requesting this scope, Discord "shortcuts" the OAuth2 flow similar to adding a bot. You don't need to complete the flow, exchange for a token, or any of that.
If your application does not require a bot user within the guild for its commands to work, **you no longer need to add for the bot scope or specific permissions**.
## Registering a Command
Commands can be scoped either globally or to a specific guild. Global commands are available for every guild that adds your app. An individual app's global commands are also available in DMs if that app has a bot that shares a mutual guild with the user.
Guild commands are specific to the guild you specify when making them. Guild commands are not available in DMs. Command names are unique per application, per type, within each scope (global and guild). That means:
- Your app **cannot** have two global `CHAT_INPUT` commands with the same name
- Your app **cannot** have two guild `CHAT_INPUT` commands within the same name **on the same guild**
- Your app **cannot** have two global `USER` commands with the same name
- Your app **can** have a global and guild `CHAT_INPUT` command with the same name
- Your app **can** have a global `CHAT_INPUT` and `USER` command with the same name
- Multiple apps **can** have commands with the same names
This list is non-exhaustive. In general, remember that command names must be unique per application, per type, and within each scope (global and guild).
An app can have the following number of commands:
- 100 global `CHAT_INPUT` commands
- 15 global `USER` commands
- 15 global `MESSAGE` commands
- 1 global `PRIMARY_ENTRY_POINT` command
For all command types except `PRIMARY_ENTRY_POINT`, you can have the same amount of guild-specific commands per guild.
There is a global rate limit of 200 application command creates per day, per guild.
Global commands are available on _all_ your app's guilds.
Global commands have inherent read-repair functionality. That means that if you make an update to a global command, and an user tries to use that command before it has updated for them, Discord will do an internal version check and reject the command, and trigger a reload for that command.
To make a **global** command, make an HTTP POST call like this:
```py
import requests
url = "https://discord.com/api/v10/applications//commands"
# This is an example CHAT_INPUT or Slash Command, with a type of 1
json = {
"name": "blep",
"type": 1,
"description": "Send a random adorable animal photo",
"options": [
{
"name": "animal",
"description": "The type of animal",
"type": 3,
"required": True,
"choices": [
{
"name": "Dog",
"value": "animal_dog"
},
{
"name": "Cat",
"value": "animal_cat"
},
{
"name": "Penguin",
"value": "animal_penguin"
}
]
},
{
"name": "only_smol",
"description": "Whether to show only baby animals",
"type": 5,
"required": False
}
]
}
# For authorization, you can use either your bot token
headers = {
"Authorization": "Bot "
}
# or a client credentials token for your app with the applications.commands.update scope
headers = {
"Authorization": "Bearer "
}
r = requests.post(url, headers=headers, json=json)
```
Guild commands are available only within the guild specified on creation.
To make a **guild** command, make a similar HTTP POST call, but scope it to a specific `guild_id`:
```py
import requests
url = "https://discord.com/api/v10/applications//guilds//commands"
# This is an example USER command, with a type of 2
json = {
"name": "High Five",
"type": 2
}
# For authorization, you can use either your bot token
headers = {
"Authorization": "Bot "
}
# or a client credentials token for your app with the applications.commands.update scope
headers = {
"Authorization": "Bearer "
}
r = requests.post(url, headers=headers, json=json)
```
## Updating and Deleting a Command
Commands can be deleted and updated by making `DELETE` and `PATCH` calls to the command endpoint. Those endpoints are
- `/applications/{application.id}/commands/{command.id}` for global commands, or
- `/applications/{application.id}/guilds/{guild.id}/commands/{command.id}` for guild commands
Because commands have unique names within a type and scope, Discord treats `POST` requests for new commands as upserts. That means **making a new command with an already-used name for your application will update the existing command**.
Full documentation of endpoints can be found [here](#endpoints).
## Contexts
Commands have two sets of contexts on the [application command object](#application-command-object) that let you to configure when and where it can be used:
- `integration_types` defines the **[installation contexts](#installation-context)** that a command supports
- `contexts` defines the **[interaction contexts](#interaction-context)** where a command can be used
Details for both types of command contexts are in the sections below.
Contexts are distinct from, and do not affect, any [command permissions](#permissions) for applications in a guild.
### Installation Context
The [installation context](/resources/application#application-integration-type) is where your app was installed—to a guild, a user, or both. If your app supports both installation contexts, there may be cases where you want some of your app's commands to only be available for one or the other.
For example, maybe your app has a `/profile` command that is only relevant when it's installed to a user.
A command's supported installation context(s) can be set using the [`integration_types` field](#application-command-object) when creating or updating a command as long as any included contexts are already [supported by the application's `integration_types`](/resources/application#application-object).
### Interaction Context
The interaction contexts for a command determines where it can be used, and can be configured by setting the [`contexts` field](#application-command-object) when creating or updating a command.
There are three [interaction context types](/interactions/receiving-and-responding#interaction-context-type) that correspond to different surfaces: `GUILD`, `BOT_DM`, and `PRIVATE_CHANNEL`. However, the `PRIVATE_CHANNEL` interaction context is only meaningful for commands installed to a user (when the command's `integration_types` includes `USER_INSTALL`).
## Permissions
Application command permissions allow commands to be configured on an individual basis for up to 100 users, roles, and channels within a guild.
Command permissions cannot be updated using a bot.
A command's current permissions can be retrieved using the [`GET /applications/{application.id}/guilds/{guild.id}/commands/{command.id}/permissions`](#get-application-command-permissions) endpoint. The response will include a `permissions` arrau with associated IDs and permission types.
Command permissions can be updated with the [`PUT /applications/{application.id}/guilds/{guild.id}/commands/{command.id}/permissions`](#modify-application-command-permissions) endpoint by a user with sufficient permissions.
For their permissions to be considered sufficient, all of the following must be true:
- Has [permission to `MANAGE_GUILD` and `MANAGE_ROLES`](/topics/permissions) in the guild where the command is being edited
- Has the ability to run the command being edited
- Has permission to manage the resources that will be affected (roles, users, and/or channels depending on the [permission types](#application-command-permission-type))
### Application Command Permissions Object
###### Guild Application Command Permissions Structure
Returned when fetching the permissions for a command in a guild.
| Field | Type | Description |
| -------------- | ------------------------------------------------------------------------------------------- | ------------------------------------------------------ |
| id ^1^ | snowflake | The ID of the command |
| application_id | snowflake | The ID of the application the command belongs to |
| guild_id | snowflake | The ID of the guild |
| permissions | array[[application command permissions](#application-command-permissions-structure) object] | The permissions for the command in the guild (max 100) |
^1^ When the `id` field is the application ID instead of a command ID, the permissions apply to all commands the application provides that do not otherwise have explicit overwrites.
###### Application Command Permissions Structure
Application command permissions allow you to enable or disable commands for specific users or roles within a guild.
| Field | Type | Description |
| ---------- | --------- | ------------------------------------------------------------------------------------------------ |
| id | snowflake | The ID of the role or user |
| type | integer | The type of the [application command permission overwrite](#application-command-permission-type) |
| permission | boolean | Whether the command is allowed to be invoked by the entity |
###### Application Command Permissions Constants
The following constants can be used in the `id` field for command permissions payloads.
| Permission | Value | Type | Description |
| ------------ | -------------- | --------- | ----------------------- |
| `@everyone` | `guild_id` | snowflake | All members in a guild |
| All Channels | `guild_id - 1` | snowflake | All channels in a guild |
###### Application Command Permission Type
| Value | Name | Description |
| ----- | ------- | ------------------------ |
| 1 | ROLE | A role within a guild |
| 2 | USER | A guild member |
| 3 | CHANNEL | A channel within a guild |
To allow for fine-tuned access to commands, application command permissions are supported for guild and global commands of all types. Guild members and apps with the [necessary permissions](#permissions) can allow or deny specific users and roles from using a command, or toggle commands for entire channels.
Similar to how threads [inherit user and role permissions from the parent channel](/topics/threads#permissions), any command permissions for a channel will apply to the threads it contains.
If you don't have permission to use a command, it will not show up in the command index. Members with the `ADMINISTRATOR` permission can use all commands.
###### Using Default Permissions
Default permissions can be added to a command during creation using the `default_member_permissions` and `context` fields. This is the only opportunity for bots to configure permissions on commands, as per-guild command permissions must be configured by a user account or through OAuth2.
The `default_member_permissions` field can be used when creating a command to set the permissions a user must have to use it.
The value for `default_member_permissions` is a bitwise OR-ed set of [permissions](/topics/permissions#bitwise-permission-flags), serialized as a string.
Setting it to `0` will prohibit anyone in a guild from using the command unless a specific overwrite is configured or the user has admin permissions.
You can also include `BOT_DM` in `contexts` when setting a global command's [interaction contexts](#interaction-context) to control whether it can be run in DMs with your bot. Guild commands don't support the `BOT_DM` interaction context.
###### Example of Editing Permissions
As an example, the following command would not be usable by anyone except admins in any guilds by default:
```json
{
"name": "permissions_test",
"description": "A test of default permissions",
"type": 1,
"default_member_permissions": "0"
}
```
Or this would enable it just for users that have the `MANAGE_GUILD` permission:
```py
permissions = str(1 << 5)
command = {
"name": "permissions_test",
"description": "A test of default permissions",
"type": 1,
"default_member_permissions": permissions
}
```
And the following would disable a command for a specific channel:
```py
A_SPECIFIC_CHANNEL = ""
url = "https://discord.com/api/v10/applications//guilds//commands//permissions"
json = {
"permissions": [
{
"id": A_SPECIFIC_CHANNEL,
"type": 3,
"permission": False
}
]
}
headers = {
"Authorization": "Bearer "
}
r = requests.put(url, headers=headers, json=json)
```
## Slash Commands
Slash commands—the `CHAT_INPUT` type—are a type of application command. They're made up of a name, description, and a block of `options`, which you can think of like arguments to a function.
The name and description help users find your command among many others, and the `options` validate user input as they fill out your command.
Slash commands can also have groups and subcommands to further organize commands. More on those later.
Slash commands can have a maximum of 8000 characters for combined name, description, and value properties for each command, its options (including subcommands and groups), and choices.
When [localization fields](#localization) are present, only the longest localization for each field (including the default value) is counted towards the size limit.
###### Example Slash Command
```json
{
"id": "1267261558183034922",
"application_id": "891436233903964161",
"version": "1267644402063507572",
"default_member_permissions": null,
"type": 1,
"name": "blep",
"description": "Send a random adorable animal photo",
"dm_permission": true,
"contexts": [0, 1, 2],
"integration_types": [0, 1],
"options": [
{
"name": "animal",
"description": "The type of animal",
"type": 3,
"required": true,
"choices": [
{
"name": "Dog",
"value": "animal_dog"
},
{
"name": "Cat",
"value": "animal_cat"
},
{
"name": "Penguin",
"value": "animal_penguin"
}
]
},
{
"name": "only_smol",
"description": "Whether to show only baby animals",
"type": 5,
"required": false
}
],
"nsfw": false
}
```
When someone uses a slash command, your application will receive an interaction:
###### Example Slash Command Interaction
```json
{
"id": "786008729715212338",
"application_id": "775799577604522054",
"type": 2,
"data": {
"id": "1267261558183034922",
"name": "blep",
"options": [
{
"type": 3,
"name": "animal",
"value": "animal_cat"
},
{
"type": 5,
"name": "only_smol",
"value": true
}
]
},
"guild": {
"id": "290926798626357999",
"features": [],
"locale": "en-US"
},
"channel": {
"id": "645027906669510667",
"type": 0,
"guild_id": "290926798626357999",
"position": 0,
"name": "general",
"topic": null,
"nsfw": false,
"last_message_id": null,
"rate_limit_per_user": 0,
"parent_id": null,
"last_pin_timestamp": null,
"permissions": "2147483647",
"flags": 0,
"icon_emoji": null,
"theme_color": null
},
"channel_id": "645027906669510667",
"member": {
"user": {
"id": "53908232506183680",
"username": "mason",
"avatar": "a_d5efa99b3eeaa7dd43acca82f5692432",
"discriminator": "0",
"public_flags": 4325445,
"banner": "42db4e3be824706cb1304fba05995722",
"accent_color": null,
"global_name": "Mason",
"avatar_decoration_data": null,
"collectibles": null,
"display_name_styles": null,
"primary_guild": null
},
"nick": null,
"avatar": null,
"avatar_decoration_data": null,
"banner": null,
"roles": ["539082325061836999"],
"joined_at": "2017-03-13T19:19:14.040000+00:00",
"premium_since": null,
"deaf": false,
"mute": false,
"pending": false,
"communication_disabled_until": null,
"unusual_dm_activity_until": null,
"flags": 0,
"permissions": "2147483647"
},
"token": "A_UNIQUE_TOKEN",
"version": 1,
"app_permissions": "442368",
"locale": "en-US",
"guild_locale": "en-US",
"entitlements": [],
"entitlement_sku_ids": [],
"authorizing_integration_owners": {
"0": "290926798626357999",
"1": "53908232506183680"
},
"attachment_size_limit": 524288000
}
```
## Subcommands and Subcommand Groups
For those developers looking to make more organized and complex groups of commands, look no further than subcommands and groups.
**Subcommands** organize your commands by **specifying actions within a command or group**.
**Subcommand Groups** organize your **subcommands** by **grouping subcommands by similar action or resource within a command**.
These are not enforced rules. You are free to use subcommands and groups however you'd like; it's just how Discord thinks about them.
Using subcommands or subcommand groups will make your base command unusable. You can't send the base `/permissions` command as a valid command if you also have `/permissions add | remove` as subcommands or subcommand groups
Discord supports nesting one level deep within a group, meaning your top level command can contain subcommand groups, and those groups can contain subcommands. **That is the only kind of nesting supported.** Here's some visual examples:
```
VALID
command
|
|__ subcommand
|
|__ subcommand
#######
command
|
|__ subcommand-group
|
|__ subcommand
|
|__ subcommand-group
|
|__ subcommand
#######
INVALID
command
|
|__ subcommand-group
|
|__ subcommand-group
|
|__ subcommand-group
|
|__ subcommand-group
#######
command
|
|__ subcommand
|
|__ subcommand-group
|
|__ subcommand
|
|__ subcommand-group
```
### Example Walkthrough
Let's look at an example. Let's imagine you run a moderation bot. You want to make a `/permissions` command that can do the following:
- Get the guild permissions for a user or a role
- Get the permissions for a user or a role on a specific channel
- Change the guild permissions for a user or a role
- Change the permissions for a user or a role on a specific channel
We'll start by defining the top-level information for `/permissions`:
```js
{
"name": "permissions",
"description": "Get or edit permissions for a user or a role",
"options": []
}
```
Now we have a command named `permissions`. We want this command to be able to affect users and roles. Rather than making two separate commands, we can use subcommand groups. We want to use subcommand groups here because we are grouping commands on a similar resource: `user` or `role`.
```js
{
"name": "permissions",
"description": "Get or edit permissions for a user or a role",
"options": [
{
"name": "user",
"description": "Get or edit permissions for a user",
"type": 2 // 2 is type SUB_COMMAND_GROUP
},
{
"name": "role",
"description": "Get or edit permissions for a role",
"type": 2
}
]
}
```
You'll notice that a command like this **will not show up** in the command explorer. That's because groups are effectively "folders" for commands, and we've made two empty folders. So let's continue.
Now that we've effectively made `user` and `role` "folders", we want to be able to either `get` and `edit` permissions. Within the subcommand groups, we can make subcommands for `get` and `edit`:
```js
{
"name": "permissions",
"description": "Get or edit permissions for a user or a role",
"options": [
{
"name": "user",
"description": "Get or edit permissions for a user",
"type": 2, // 2 is type SUB_COMMAND_GROUP
"options": [
{
"name": "get",
"description": "Get permissions for a user",
"type": 1 // 1 is type SUB_COMMAND
},
{
"name": "edit",
"description": "Edit permissions for a user",
"type": 1
}
]
},
{
"name": "role",
"description": "Get or edit permissions for a role",
"type": 2,
"options": [
{
"name": "get",
"description": "Get permissions for a role",
"type": 1
},
{
"name": "edit",
"description": "Edit permissions for a role",
"type": 1
}
]
}
]
}
```
Now, we need some arguments! If we chose `user`, we need to be able to pick a user; if we chose `role`, we need to be able to pick a role. We also want to be able to pick between guild-level permissions and channel-specific permissions. For that, we can use optional arguments:
```js
{
"name": "permissions",
"description": "Get or edit permissions for an user or a role",
"options": [
{
"name": "user",
"description": "Get or edit permissions for an user",
"type": 2, // 2 is type SUB_COMMAND_GROUP
"options": [
{
"name": "get",
"description": "Get permissions for an user",
"type": 1, // 1 is type SUB_COMMAND
"options": [
{
"name": "user",
"description": "The user to get",
"type": 6, // 6 is type USER
"required": true
},
{
"name": "channel",
"description": "The channel permissions to get. If omitted, the guild permissions will be returned",
"type": 7, // 7 is type CHANNEL
"required": false
}
]
},
{
"name": "edit",
"description": "Edit permissions for an user",
"type": 1,
"options": [
{
"name": "user",
"description": "The user to edit",
"type": 6,
"required": true
},
{
"name": "channel",
"description": "The channel permissions to edit. If omitted, the guild permissions will be edited",
"type": 7,
"required": false
}
]
}
]
},
{
"name": "role",
"description": "Get or edit permissions for a role",
"type": 2,
"options": [
{
"name": "get",
"description": "Get permissions for a role",
"type": 1,
"options": [
{
"name": "role",
"description": "The role to get",
"type": 8, // 8 is type ROLE
"required": true
},
{
"name": "channel",
"description": "The channel permissions to get. If omitted, the guild permissions will be returned",
"type": 7,
"required": false
}
]
},
{
"name": "edit",
"description": "Edit permissions for a role",
"type": 1,
"options": [
{
"name": "role",
"description": "The role to edit",
"type": 8,
"required": true
},
{
"name": "channel",
"description": "The channel permissions to edit. If omitted, the guild permissions will be edited",
"type": 7,
"required": false
}
]
}
]
}
]
}
```
And, done! The JSON looks a bit complicated, but what we've ended up with is a single command that can be scoped to multiple actions, and then further scoped to a particular resource, and then even _further_ scope with optional arguments.
## User Commands
User commands are application commands that appear on the context menu (right click or tap) of users. They're a great way to surface quick actions for your app that target users. They don't take any arguments, and will return the user on whom you clicked or tapped in the interaction response.
A user must have permission to send text messages in the channel they invoke a user command in.
The `description` field is not allowed when creating user commands. However, to avoid breaking changes to data models, `description` will be an **empty string** (instead of `null`) when fetching commands.
###### Example User Command
```json
{
"id": "1241360244118917161",
"application_id": "682654466453012553",
"version": "1263110356692373562",
"default_member_permissions": null,
"type": 2,
"name": "High Five",
"description": "",
"dm_permission": true,
"contexts": [0, 1, 2],
"integration_types": [1],
"nsfw": false
}
```
When someone uses a user command, your application will receive an interaction:
###### Example User Command Interaction
```json
{
"id": "867794291820986368",
"application_id": "775799577604522054",
"type": 2,
"data": {
"id": "1303493304175955988",
"name": "High Five",
"type": 2,
"resolved": {
"members": {
"809850198683418695": {
"nick": null,
"avatar": null,
"avatar_decoration_data": null,
"banner": null,
"roles": [],
"joined_at": "2021-02-12T18:25:07.972000+00:00",
"premium_since": null,
"pending": false,
"communication_disabled_until": null,
"unusual_dm_activity_until": null,
"flags": 0,
"permissions": "246997699136"
}
},
"users": {
"809850198683418695": {
"id": "809850198683418695",
"username": "VoltyDemo",
"avatar": "afc428077119df8aabbbd84b0dc90c74",
"discriminator": "7302",
"public_flags": 524288,
"bot": true,
"banner": null,
"accent_color": null,
"global_name": null,
"avatar_decoration_data": null,
"collectibles": null,
"display_name_styles": null,
"primary_guild": null
}
}
},
"target_id": "809850198683418695"
},
"guild": {
"id": "772904309264089089",
"features": [],
"locale": "en-US"
},
"channel": {
"id": "772908445358620702",
"type": 0,
"guild_id": "772904309264089089",
"position": 0,
"name": "general",
"topic": null,
"nsfw": false,
"last_message_id": null,
"rate_limit_per_user": 0,
"parent_id": null,
"last_pin_timestamp": null,
"permissions": "2147483647",
"flags": 0,
"icon_emoji": null,
"theme_color": null
},
"channel_id": "772908445358620702",
"member": {
"user": {
"id": "167348773423415296",
"username": "ian",
"avatar": "f61594630cbc4848cfe9d8da1a13088e",
"discriminator": "0",
"public_flags": 4604418,
"banner": "6b9757e5926ac9f31d9e206581fc3cc3",
"accent_color": 16119261,
"global_name": "ian",
"avatar_decoration_data": null,
"collectibles": null,
"display_name_styles": null,
"primary_guild": null
},
"nick": null,
"avatar": null,
"avatar_decoration_data": null,
"banner": null,
"roles": ["785609923542777878"],
"joined_at": "2020-11-02T20:46:57.364000+00:00",
"premium_since": null,
"deaf": false,
"mute": false,
"pending": false,
"communication_disabled_until": null,
"unusual_dm_activity_until": null,
"flags": 0,
"permissions": "274877906943"
},
"token": "AN_UNIQUE_TOKEN",
"version": 1,
"app_permissions": "442368",
"locale": "en-US",
"guild_locale": "en-US",
"entitlements": [],
"entitlement_sku_ids": [],
"authorizing_integration_owners": {
"0": "772904309264089089",
"1": "167348773423415296"
},
"attachment_size_limit": 524288000
}
```
## Message Commands
Message commands are application commands that appear on the context menu (right click or tap) of messages. They're a great way to surface quick actions for your app that target messages. They don't take any arguments, and will return the message on whom you clicked or tapped in the interaction response.
The `description` field is not allowed when creating message commands. However, to avoid breaking changes to data models, `description` will be an **empty string** (instead of `null`) when fetching commands.
###### Example Message Command
```json
{
"id": "1303493304175955988",
"application_id": "682654466453012553",
"version": "1303493304175955989",
"default_member_permissions": null,
"type": 3,
"name": "Bookmarks",
"description": "",
"dm_permission": true,
"contexts": [0, 1, 2],
"integration_types": [1],
"nsfw": false
}
```
When someone uses a message command, your application will receive an interaction:
###### Example Message Command Interaction
```json
{
"id": "867794291820986368",
"application_id": "775799577604522054",
"type": 2,
"data": {
"id": "1303493304175955988",
"name": "Bookmarks",
"type": 3,
"resolved": {
"messages": {
"867793854505943041": {
"id": "867793854505943041",
"channel_id": "772908445358620702",
"author": {
"id": "167348773423415296",
"username": "ian",
"avatar": "f61594630cbc4848cfe9d8da1a13088e",
"discriminator": "0",
"public_flags": 4604418,
"banner": "6b9757e5926ac9f31d9e206581fc3cc3",
"accent_color": 16119261,
"global_name": "ian",
"avatar_decoration_data": null,
"collectibles": null,
"display_name_styles": null,
"primary_guild": null
},
"content": "some message",
"timestamp": "2021-07-22T15:42:57.744000+00:00",
"edited_timestamp": null,
"tts": false,
"mention_everyone": false,
"mentions": [],
"mention_roles": [],
"attachments": [],
"embeds": [],
"pinned": false,
"type": 0,
"flags": 0,
"components": []
}
}
},
"target_id": "867793854505943041"
},
"guild": {
"id": "772904309264089089",
"features": [],
"locale": "en-US"
},
"channel": {
"id": "772908445358620702",
"type": 0,
"guild_id": "772904309264089089",
"position": 0,
"name": "general",
"topic": null,
"nsfw": false,
"last_message_id": null,
"rate_limit_per_user": 0,
"parent_id": null,
"last_pin_timestamp": null,
"permissions": "2147483647",
"flags": 0,
"icon_emoji": {
"id": null,
"name": "💬"
},
"theme_color": null
},
"channel_id": "772908445358620702",
"member": {
"user": {
"id": "167348773423415296",
"username": "ian",
"avatar": "f61594630cbc4848cfe9d8da1a13088e",
"discriminator": "0",
"public_flags": 4604418,
"banner": "6b9757e5926ac9f31d9e206581fc3cc3",
"accent_color": 16119261,
"global_name": "ian",
"avatar_decoration_data": null,
"collectibles": null,
"display_name_styles": null,
"primary_guild": null
},
"nick": null,
"avatar": null,
"avatar_decoration_data": null,
"banner": null,
"roles": ["785609923542777878"],
"joined_at": "2020-11-02T20:46:57.364000+00:00",
"premium_since": null,
"deaf": false,
"mute": false,
"pending": false,
"communication_disabled_until": null,
"unusual_dm_activity_until": null,
"flags": 0,
"permissions": "274877906943"
},
"token": "AN_UNIQUE_TOKEN",
"version": 1,
"app_permissions": "442368",
"locale": "en-US",
"guild_locale": "en-US",
"entitlements": [],
"entitlement_sku_ids": [],
"authorizing_integration_owners": {
"0": "772904309264089089",
"1": "167348773423415296"
},
"attachment_size_limit": 524288000
}
```
## Entry Point Commands
An Entry Point command serves as the primary way for users to open an application's embedded activity.
For the Entry Point command to be visible to users, an app must have the [`EMBEDDED` flag](/resources/application#application-flags) enabled.
###### Example Entry Point Command
```json
{
"id": "1277685617043439616",
"type": 4,
"application_id": "1006584476094177371",
"version": "1277685617043439617",
"name": "launch",
"description": "Launch Racing with Friends",
"dm_permission": true,
"contexts": [0, 1, 2],
"integration_types": [0, 1],
"handler": 2
}
```
### Entry Point Handlers
When a user invokes an app's Entry Point command, the value of [`handler`](#application-command-object) will determine how the interaction is handled:
- For `APP_HANDLER`, the application is responsible for [responding to the interaction](/interactions/receiving-and-responding#responding-to-an-interaction). It can respond by launching the app's associated embedded activity using the [`LAUNCH_ACTIVITY` interaction callback type](/interactions/receiving-and-responding##interaction-callback-type), or take another action (like sending a follow-up message in channel).
- For `DISCORD_LAUNCH_ACTIVITY`, Discord will handle the interaction automatically by launching the associated embedded activity and sending a message to the channel where it was launched.
- For `APP_HANDLER_LAUNCH_ACTIVITY`, the application is again responsible for [responding to the interaction](/interactions/receiving-and-responding#responding-to-an-interaction), but it can only respond by launching the app's associated embedded activity using the [`LAUNCH_ACTIVITY` interaction callback type](/interactions/receiving-and-responding##interaction-callback-type).
When embedded activities are enabled on an application, an Entry Point command (named "launch") is automatically created for your app with `DISCORD_LAUNCH_ACTIVITY` set as the [Entry Point handler](#entry-point-handlers).
## Autocomplete
Autocomplete interactions allow your application to dynamically return option suggestions to a user as they type.
An autocomplete interaction **can return partial data** for option values. Your application will receive partial data for any existing user input, as long as that input passes client-side validation.
For example, you may receive partial strings, but not invalid numbers. The option the user is currently typing will be sent with a `focused: true` boolean field, and will always be casted to a string.
Options the user has already filled will also be sent but without the `focused` field. This is a special case where options that are otherwise required might not be present, due to the user not having filled them yet.
Autocomplete interactions will not contain attachments.
This validation is **client-side only**.
## Localization
Application commands can be localized, which will cause them to use localized names and descriptions depending on the client's selected language. This is entirely optional.
Localization is available for names and descriptions of commands, subcommands, and options, as well as the names of choices, by submitting the appropriate `name_localizations` and `description_localizations` fields when creating or updating the application command.
Application commands may be partially localized—not all [available locales](/reference#locales) are required, nor do different fields within a command need to support the same set of locales.
If a locale is not present in a localizations dictionary for a field, users in that locale will see the default value for that field. It's not necessary to fill out all locales with the default value. Any localized values that are identical to the default will be ignored.
Localized option names are subject to an additional constraint, which is that they must be distinct from all other default option names of that command, as well as all other option names within that locale on that command.
When taking advantage of command localization, the interaction payload received by your client will still use default command, subcommand, and option names.
To localize your interaction response, you can determine the client's selected language by using the `locale` key in the interaction payload.
An application command furnished with localizations might look like this:
```json
{
"name": "birthday",
"type": 1,
"description": "Wish a friend a happy birthday",
"name_localizations": {
"zh-CN": "生日",
"el": "γενέθλια"
},
"description_localizations": {
"zh-CN": "祝你朋友生日快乐"
},
"options": [
{
"name": "age",
"type": 4,
"description": "Your friend's age",
"name_localizations": {
"zh-CN": "岁数"
},
"description_localizations": {
"zh-CN": "你朋友的岁数"
}
}
]
}
```
### Locale Fallbacks
For application commands, there are built-in fallbacks in case a user's locale isn't present in the localizations. If the fallback locale is also missing, it will use the default.
You should make sure to include your default value in its proper locale key, otherwise it may use a fallback value unexpectedly.
For example, if your default value is `en-US`, but you don't specify the `en-US` value in your localizations, users with `en-US` selected will see the `en-GB` value if it's specified.
For example, if you have a command with the default name "color", and your localizations specify only the `en-GB` value as "colour", users in the `en-US` locale will see "colour" because the `en-US` key is missing.
| Locale | Fallback |
| ------ | -------- |
| en-US | en-GB |
| en-GB | en-US |
| es-419 | es-ES |
### Retrieving Localized Commands
While most endpoints that return application command objects will return the `name_localizations` and `description_localizations` fields, some will not by default. This includes `GET` endpoints that return all of an application's guild or global commands.
Instead, those endpoints will supply additional `name_localized` or `description_localized` fields, which only contain the localization relevant to the requester's locale. The full dictionaries can still be obtained by supplying the appropriate query argument.
[Application command index](#application-command-index-object) objects have special behavior for localization. See the [application command](#application-command-object) object notes for details.
For example, if a batch `GET` request were made with locale `zh-CN`, including the above command, the returned object would look as follows:
```json
{
"name": "birthday",
"type": 1,
"description": "Wish a friend a happy birthday",
"name_localized": "生日",
"description_localized": "祝你朋友生日快乐",
"options": [
{
"name": "age",
"type": 4,
"description": "Your friend's age",
"name_localized": "岁数",
"description_localized": "你朋友的岁数"
}
]
}
```
If the requester's locale is not found in a localizations dictionary, then the corresponding `name_localized` or `description_localized` for that field will also not be present.
Locale is determined by looking at the `X-Discord-Locale` header, then the `Accept-Language` header if not present, then lastly the user settings locale.
## Age-Restricted Commands
A command that contains age-restricted content should have the [`nsfw` field](#application-command-object) set to `true` upon creation or update. Marking a command as age-restricted will limit who can see and access the command, and from which channels.
### Using Age-Restricted Commands
To use an age-restricted command, a user must be 18 years or older and access the command from either:
- an [age-restricted channel](https://support.discord.com/hc/articles/115000084051-Age-Restricted-Channels-and-Content) or
- a DM with the app _after_ [enabling age-restricted commands](https://support.discord.com/hc/en-us/articles/10123937946007) within their user settings.
Details about accessing and using age-restricted commands is in [the Help Center](https://support.discord.com/hc/en-us/articles/10123937946007).
## Endpoints
Get Application Command Index
Returns an [application command index](#application-command-index-object) object for the given application ID, containing all of the application's available commands. User must have the application authorized on their account.
Get Channel Application Command Index
Returns an [application command index](#application-command-index-object) object for the given private channel ID. In a bot DM, this will return the commands available from the application associated with the bot. In a group DM, it will query the integrations authorized to the channel.
Get Guild Application Command Index
Returns an [application command index](#application-command-index-object) object for the given guild ID, containing the commands available from all applications installed to the guild. User must be a member of the guild.
Get User Application Command Index
Returns an [application command index](#application-command-index-object) object for the current user, containing the commands available from all applications installed to the user's account.
List Global Application Commands
Returns a list of global [application command](#application-command-object) objects for the given application ID. User must be the owner of the application, developer of the application's team, or have a DM channel with the application's bot.
For OAuth2 requests, only the application associated with the access token can be used.
###### Query String Params
| Field | Type | Description |
| ------------------- | ------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| with_localizations? | boolean | Whether to include full localization dictionaries (`name_localizations` and `description_localizations`) in the returned objects, instead of the `name_localized` and `description_localized` fields (default false) |
Create Global Application Command
Creates a new global command. Returns an [application command](#application-command-object) object on success.
This endpoint is only usable with an OAuth2 access token with the `applications.commands.update` scope for the application specified in the path.
Creating a command with the same name as an existing command for your application will overwrite the old command.
###### JSON Params
| Field | Type | Description | Valid Types |
| ------------------------------- | --------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------- |
| type? | integer | The type of the command (default `CHAT_INPUT`) | All |
| name | string | The name of the option (1-32 characters) | All |
| name_localizations? | ?map[string, string] | The localized name for each [locale](/reference#locales) (values follow same restrictions as `name`) | All |
| description? ^1^ | string | The description of the option (1-100 characters) | All |
| description_localizations? | ?map[string, string] | The localized description for each [locale](/reference#locales) (values follow same restrictions as `description`) | All |
| options? | array[[application command option](#application-command-option-structure) object] | The options for the command (max 25) | `CHAT_INPUT` |
| default_member_permissions? | ?string | The default required permissions to call the command | All |
| dm_permission? **(deprecated)** | boolean | Whether the command is available in DMs with the application (default true) | All |
| nsfw? | boolean | Whether the command is age-restricted (default false) | All |
| integration_types? | array[integer] | The [installation contexts](/resources/application#application-integration-type) where the command is available (default application's configured contexts) | All |
| contexts? | array[integer] | The [interaction context](/interactions/receiving-and-responding#interaction-context-type) where the command can be used | All |
| handler? | integer | [How the command should be handled when called](#application-command-handler-type) | `PRIMARY_ENTRY_POINT` |
^1^ Required for [`PRIMARY_ENTRY_POINT` commands](#application-command-type).
Get Global Application Command
Returns an [application command](#application-command-object) object for the given application and command ID.
This endpoint is only usable with an OAuth2 access token with the `applications.commands.update` scope for the application specified in the path.
Modify Global Application Command
Modifies a global command. Returns the updated [application command](#application-command-object) object on success.
This endpoint is only usable with an OAuth2 access token with the `applications.commands.update` scope for the application specified in the path.
###### JSON Params
| Field | Type | Description | Valid Types |
| ------------------------------- | ---------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------- |
| name? | string | The name of the option (1-32 characters) | All |
| name_localizations? | ?map[string, string] | The localized name for each [locale](/reference#locales) (values follow same restrictions as `name`) | All |
| description? | string | The description of the option (1-100 characters) | All |
| description_localizations? | ?map[string, string] | The localized description for each [locale](/reference#locales) (values follow same restrictions as `description`) | All |
| options? | ?array[[application command option](#application-command-option-structure) object] | The options for the command (max 25) | `CHAT_INPUT` |
| default_member_permissions | ?string | The default required permissions to call the command | All |
| dm_permission? **(deprecated)** | ?boolean | Whether the command is available in DMs with the application | All |
| ~~default_permission?~~ | ~~boolean~~ | ~~Whether the command is enabled by default when the application is added to a guild (default true)~~ | All |
| nsfw? | ?boolean | Whether the command is age-restricted | All |
| integration_types? | ?array[integer] | The [installation contexts](/resources/application#application-integration-type) where the command is available (default application's configured contexts) | All |
| contexts? | ?array[integer] | The [interaction context](/interactions/receiving-and-responding#interaction-context-type) where the command can be used | All |
| handler? | ?integer | [How the command should be handled when called](#application-command-handler-type) | `PRIMARY_ENTRY_POINT` |
Delete Global Application Command
Deletes a global command. Returns a 204 empty response on success.
This endpoint is only usable with an OAuth2 access token with the `applications.commands.update` scope for the application specified in the path.
Bulk Modify Global Application Commands
Overwrites all existing commands that are registered globally for this application. Accepts a list of [application command](#application-command-object) objects. Returns a list of [application command](#application-command-object) objects on success.
Commands that do not already exist will count toward daily application command create limits.
This endpoint is not usable by user accounts.
This will overwrite **all** types of application commands: slash commands, user commands, message commands, and primary entry-point commands.
List Guild Application Commands
Returns a list of [application command](#application-command-object) objects for the given guild ID. User must be the owner of the application or developer of the application's team.
For OAuth2 requests, only the application associated with the access token can be used.
###### Query String Params
| Field | Type | Description |
| ------------------- | ------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| with_localizations? | boolean | Whether to include full localization dictionaries (`name_localizations` and `description_localizations`) in the returned objects, instead of the `name_localized` and `description_localized` fields (default false) |
Create Guild Application Command
Creates a new guild command. Returns an [application command](#application-command-object) object. If the command did not already exist, it will count toward daily application command create limits.
This endpoint is only usable with an OAuth2 access token with the `applications.commands.update` scope for the application specified in the path.
Creating a command with the same name as an existing command for your application will overwrite the old command.
###### JSON Params
| Field | Type | Description | Valid Types |
| --------------------------- | ---------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------ | ------------ |
| type? | integer | The type of the command (default `CHAT_INPUT`) | All |
| name | string | The name of the option (1-32 characters) | All |
| name_localizations? | ?map[string, string] | The localized name for each [locale](/reference#locales) (values follow same restrictions as `name`) | All |
| description | string | The description of the option (1-100 characters) | All |
| description_localizations? | ?map[string, string] | The localized description for each [locale](/reference#locales) (values follow same restrictions as `description`) | All |
| options? | ?array[[application command option](#application-command-option-structure) object] | The options for the command (max 25) | `CHAT_INPUT` |
| default_member_permissions? | ?string | The default required permissions to call the command | All |
| nsfw? | boolean | Whether the command is age-restricted | All |
Get Guild Application Command
Returns an [application command](#application-command-object) object for the given application, guild, and command ID.
This endpoint is only usable with an OAuth2 access token with the `applications.commands.update` scope for the application specified in the path.
Modify Guild Application Command
Modifies a guild command. Returns the updated guild [application command](#application-command-object) object on success. Fires [Guild Application Command Index Update](/gateway/gateway-events#guild-application-command-index-update) Gateway event.
This endpoint is only usable with an OAuth2 access token with the `applications.commands.update` scope for the application specified in the path.
###### JSON Params
| Field | Type | Description | Valid Types |
| --------------------------- | ---------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------ | ------------ |
| name? | string | The name of the option (1-32 characters) | All |
| name_localizations? | ?map[string, string] | The localized name for each [locale](/reference#locales) (values follow same restrictions as `name`) | All |
| description? | string | The description of the option (1-100 characters) | All |
| description_localizations? | ?map[string, string] | The localized description for each [locale](/reference#locales) (values follow same restrictions as `description`) | All |
| options? | ?array[[application command option](#application-command-option-structure) object] | The options for the command (max 25) | `CHAT_INPUT` |
| default_member_permissions? | ?string | The default required permissions to call the command | All |
| nsfw? | ?boolean | Whether the command is age-restricted | All |
Delete Guild Application Command
Deletes a guild application command. Returns a 204 empty response on success.
This endpoint is only usable with an OAuth2 access token with the `applications.commands.update` scope for the application specified in the path.
Bulk Modify Guild Application Commands
Overwrites all existing commands that are registered for the given guild. Accepts a list of [application command](#application-command-object) objects. Returns a list of [application command](#application-command-object) objects on success.
Commands that do not already exist will count toward daily application command create limits.
This endpoint is not usable by user accounts.
List Guild Application Command Permissions
Returns a list of [guild application command permissions](#guild-application-command-permissions-structure) objects representing all configured command permissions for your application in a guild.
Get Application Command Permissions
Returns a [guild application command permissions](#guild-application-command-permissions-structure) object for a specific application command in a guild.
Modify Application Command Permissions
Replaces permissions for a specific application command in a guild. Returns a [guild application command permissions](#guild-application-command-permissions-structure) object on success.
You can only add up to 10 permission overwrites for a command. Deleting or renaming a command will permanently delete all permissions for that command.
###### JSON Params
| Field | Type | Description |
| ----------- | ------------------------------------------------------------------------------------------- | -------------------------------------------- |
| permissions | array[[application command permissions](#application-command-permissions-structure) object] | The permissions for the command in the guild |
---
# Receiving & Responding
Link: https://docs.discord.food/interactions/receiving-and-responding
An [interaction](#interaction-object) is the message that your application receives when an user uses an application command, triggers a message component, or submits a modal.
For [Slash Commands](/interactions/application-commands#slash-commands), it includes the values that the user submitted.
For [User Commands](/interactions/application-commands#user-commands) and [Message Commands](/interactions/application-commands#message-commands), it includes the resolved user or message on which the action was taken.
For [Message Components](/resources/components) it includes identifying information about the component that was used. It will also include some metadata about how the interaction was triggered: the `guild_id`, `channel_id`, `member` and other fields. You can find all the values in data models below.
### Interaction Object
###### Interaction Structure
| Field | Type | Description |
| ------------------------------------- | ---------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------- |
| version | integer | The [interactions system version](/resources/application#application-interactions-version) (currently 1) |
| id | snowflake | The ID of the interaction |
| application_id | snowflake | The ID of the application this interaction is for |
| type | integer | The [type of the interaction](#interaction-type) |
| token | string | The continuation token for responding to the interaction |
| data? ^1^ | object | The interaction data, depending on interaction type |
| guild? | [interaction guild](#interaction-guild-structure) | The guild the interaction was created in |
| guild_id? | snowflake | The ID of the guild the interaction was created in |
| guild_locale? | string | The [preferred locale](/reference#locales) of the guild |
| channel? | [channel](/resources/channel#channel-object) | The channel it was sent from |
| channel_id? ^1^ | snowflake | The ID of the channel it was sent from |
| member? ^2^ | [guild member](/resources/guild#guild-member-object) object | The guild member representing the invoking user |
| user? ^2^ | partial [user](/resources/user#user-object) object | The invoking user |
| locale? | string | The [language option](/reference#locales) of the invoking user |
| message? ^4^ | [message](/resources/message#message-object) object | The message the components are attached to |
| app_permissions | string | The permissions the application has in the source location of the interaction |
| entitlements | array[[entitlement](/resources/entitlement#entitlement-object) object] | The entitlements for the invoking user |
| entitlement_sku_ids? **(deprecated)** | array[snowflake] | The IDs of the SKUs the entitlements grant access to |
| authorizing_integration_owners ^3^ | map[integer, snowflake] | The ID of the target for each [application integration type](/resources/application#application-integration-type) |
| context? ^1^ | integer | The [context the interaction is triggered in](#interaction-context-type) |
| attachment_size_limit | integer | The attachment size limit in bytes |
^1^ This is always present on non-`PING` interaction types. It is optional for future-proofing against new interaction types.
^2^ `member` is sent only when the interaction is triggered in a guild, and `user` is sent only when triggered in a private channel.
^3^ The value of the [`GUILD_INSTALL`](/resources/application#application-integration-type) key may be `0` if the interaction was not triggered in a guild.
^4^ `message` is sent only when the interaction was triggered from a message component, or the modal submit.
###### Interaction Type
| Value | Name | Description | Received Data | Sent Data |
| ----- | ------------------------------------- | --------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------- |
| 1 | PING | Discord is pinging the application | — | — |
| 2 | APPLICATION_COMMAND | User uses an application command | [application command data](#application-command-data-structure) object | [sendable application command data](#sendable-application-command-data-structure) object |
| 3 | MESSAGE_COMPONENT | User triggers a message component | [message component data](#message-component-data-structure) object | [sendable message component data](#sendable-message-component-data-structure) object |
| 4 | APPLICATION_COMMAND_AUTOCOMPLETE | User is requesting an application command option to be auto-completed | [application command data](#application-command-data-structure) object | [sendable application command data](#sendable-application-command-data-structure) object |
| 5 | MODAL_SUBMIT | User submits a modal | [modal submit data](#modal-submit-data-structure) object | [sendable modal submit data](#sendable-modal-submit-data-structure) object |
| 6 | SOCIAL_LAYER_SKU_PURCHASE_ELIGIBILITY | User is checking purchase eligibility for a social layer SKU | [social layer SKU purchase eligibility data](#social-layer-sku-purchase-eligibility-data-structure) object | — |
###### Interaction Context Type
| Value | Name | Description |
| ----- | --------------- | ----------------------------------------------------------------------- |
| 0 | GUILD | The interaction can be triggered within guilds |
| 1 | BOT_DM | The interaction can be triggered within DM channel with the application |
| 2 | PRIVATE_CHANNEL | The interaction can be triggered in all DM and group DMs |
###### Interaction Guild Structure
| Field | Type | Description |
| -------- | ------------- | --------------------------------------------------------- |
| id | snowflake | The ID of the guild |
| features | array[string] | Enabled [guild features](/resources/guild#guild-features) |
| locale | string | The [preferred locale](/reference#locales) of the guild |
###### Application Command Data Structure
| Field | Type | Description |
| ---------------- | ------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------- |
| id | snowflake | The ID of the invoked command |
| name | string | The name of the invoked command |
| type | integer | The [type of the invoked command](/interactions/application-commands#application-command-type) |
| resolved? | [resolved data](#resolved-data-object) object | The resolved entities |
| options? ^1^ ^2^ | array[[application command data option](#application-command-data-option-structure) object] | The options with their values |
| guild_id? | snowflake | The ID of the guild that the command is registered to |
| target_id? ^3^ | snowflake | The ID of the user or message targeted by the command |
^1^ This [can be partial](/interactions/application-commands#autocomplete) in response to [`APPLICATION_COMMAND_AUTOCOMPLETE` interactions](#interaction-type).
^2^ Only present when the application command type is [`CHAT_INPUT`](/interactions/application-commands#application-command-type).
^3^ Only present when the application command type is [`USER` or `MESSAGE`](/interactions/application-commands#application-command-type).
###### Application Command Data Option Structure
All options have names, and an option can either be a parameter, in which case `value` will be set, or it can denote a subcommand or group, in which case it will contain another array of `options`. `value` and `options` are mutually exclusive.
| Field | Type | Description |
| ------------ | ------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------- |
| type | integer | The [type of the application command option](/interactions/application-commands#application-command-option-type) |
| name | string | The name of the option |
| value? ^1^ | boolean \| float \| integer \| snowflake \| string | The value of the option |
| options? | array[[application command data option](#application-command-data-option-structure) object] | The nested options (only applicable if the option is a subcommand or subcommand group) |
| focused? ^2^ | boolean | Whether the option is the currently focused option for autocomplete |
^1^ For [`ATTACHMENT` options](/interactions/application-commands##application-command-option-type), `value` will be the attachment ID.
^2^ Only applicable for [`APPLICATION_COMMAND_AUTOCOMPLETE` interactions](#interaction-type). The focused option will always have a string `value`, even if the option type is not a string.
###### Message Component Data Structure
| Field | Type | Description |
| -------------- | -------------------------------------- | ----------------------------------------------------------------- |
| custom_id | string | The developer-defined identifier for the component |
| component_type | integer | The [type of the component](/resources/components#component-type) |
| values ^1^ | array[snowflake] \| array[string] | The values that the user selected in a select menu |
| resolved? ^1^ | [resolved data](#resolved-data-object) | The resolved entities |
^1^ Only present for select menu components.
###### Modal Submit Data Structure
| Field | Type | Description |
| ---------- | ----------------------------------------------------------------------------------- | --------------------------------------------- |
| custom_id | string | The developer-defined identifier of the modal |
| components | array[[modal submit component data](#modal-submit-component-data-structure) object] | The submitted values |
| resolved? | [resolved data](#resolved-data-object) | The resolved entities |
###### Modal Submit Component Data Structure
| Field | Type | Description | Component Type |
| ---------- | ----------------------------------------------------------------------------------- | ----------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| id ^1^ | integer | The ID of the component | All |
| type | integer | The [type](/resources/components#component-type) of the component | All |
| custom_id | string | The developer-defined identifier for the component | `STRING_SELECT`, `USER_SELECT`, `ROLE_SELECT`, `MENTIONABLE_SELECT`, `CHANNEL_SELECT`, `TEXT_INPUT`, `FILE_UPLOAD`, `RADIO_GROUP`, `CHECKBOX_GROUP`, `CHECKBOX` |
| value | string \| boolean | The value that the user inputted | `TEXT_INPUT`, `RADIO_GROUP`, `CHECKBOX` |
| values | array[snowflake] \| array[string] | The values that the user selected or uploaded | `STRING_SELECT`, `USER_SELECT`, `ROLE_SELECT`, `MENTIONABLE_SELECT`, `CHANNEL_SELECT`, `FILE_UPLOAD`, `CHECKBOX_GROUP` |
| component | [modal submit component data](#modal-submit-component-data-structure) object | Inner component | `LABEL` |
| components | array[[modal submit component data](#modal-submit-component-data-structure) object] | Inner components | `ACTION_ROW` |
^1^ `id` does not need to be provided when [creating an interaction](#create-interaction).
###### Social Layer SKU Purchase Eligibility Data Structure
| Field | Type | Description |
| ------ | --------- | ----------------- |
| sku_id | snowflake | The ID of the SKU |
### Resolved Data Object
Holds extra entities that have been resolved from IDs in an interaction or message.
###### Resolved Data Structure
| Field | Type | Description |
| ------------- | ----------------------------------------------------------------------------- | ------------------------ |
| users? | map[snowflake, partial [user](/resources/user#user-object) object] | The resolved users |
| members? ^1^ | map[snowflake, partial [member](/resources/guild#guild-member-object) object] | The resolved members |
| roles? | map[snowflake, [role](/resources/guild#role-object) object] | The resolved roles |
| channels? ^2^ | map[snowflake, partial [channel](/resources/channel#channel-object) object] | The resolved channels |
| messages? | map[snowflake, [message](/resources/message#message-object) object] | The resolved messages |
| attachments? | map[snowflake, [attachment](/resources/message#attachment-object) object] | The resolved attachments |
^1^ Member objects will not include `user`, `deaf` and `mute` fields. The user will be in the `users` map instead.
^2^ Channel objects will not include `permission_overwrites`, `recipients`, `icon`, `application_id`, `managed` and `member` fields.
## Interactions and Bot Users
We're all used to the way that Discord bots have worked for a long time. You make an application, you add a bot user to it, and you copy the token. That token can be used to connect to the Gateway and to make requests against Discord API.
Interactions bring something entirely new to the table: the ability to interact with an application _without needing a bot user in the guild_. As you read through this documentation, you'll see that bot tokens are only referenced as a helpful alternative to doing a client credentials auth flow. Responding to interactions does not require a bot token.
In many cases, you may still need a bot user. If you need to receive Gateway events, or need to interact with other parts of Discord API (like fetching a guild, or a channel, or updating permissions on an user), those actions are all still tied to having a bot token.
However, if you don't need any of those things, you never have to add a bot user to your application at all.
Welcome to the new world.
## Receiving an Interaction
When a user interacts with your app, your app will receive an [interaction](#interaction-object). Your app can receive an interaction in one of two ways:
- Via the [Interaction Create](/gateway/gateway-events#interaction-create) Gateway event
- Via outgoing webhook
These two methods are **mutually exclusive**; you can _only_ receive interactions one of the two ways. The [Gateway event](/gateway/gateway-events#interaction-create) will be handled by any shard 0 session, while the webhook method detailed below does not require a connected client.
To use webhooks, you must [edit your application](/resources/application#modify-application) and provide a valid `interactions_endpoint_url`. In order for the URL to be valid, you must be prepared for two things ahead of time:
These steps are only necessary for webhook-based interactions. It is not required for receiving them over the Gateway.
1. Your endpoint must be prepared to ACK a `PING` message
2. Your endpoint must be set up to properly handle signature headers—more on that in [Security and Authorization](#security-and-authorization)
If either of these are not complete, Discord will not validate your URL and it will fail to save.
When you attempt to save a URL, Discord will send a `POST` request to that URL with a `PING` payload. The `PING` payload has a `"type": 1`. So, to properly ACK the payload, return a `200` response with a payload of `"type": 1`:
```py
@app.route('/', methods=['POST'])
def handle_interaction():
if request.json["type"] == 1:
return jsonify({
"type": 1
})
```
You'll also need to properly set up [Security and Authorization](#security-and-authorization) on your endpoint for the URL to be accepted. Once both of those are complete and your URL has been saved, you can start receiving interactions via webhook! At this point,
your bot will **no longer receive interactions over the Gateway**. If you want to receive them over the Gateway again, simply delete your URL.
An [interaction](#interaction-object) includes metadata to aid your application in handling it as well as `data` specific to the interaction type. You can find samples for each interaction type on their respective pages:
- [Slash Commands](/interactions/application-commands#example-slash-command-interaction)
- [User Commands](/interactions/application-commands#example-user-command-interaction)
- [Message Commands](/interactions/application-commands#example-message-command-interaction)
- [Message Components](/resources/components)
Now that you've gotten the data from the user, it's time to respond to them.
## Responding to an Interaction
Interactions—both receiving and responding—are webhooks under the hood. So responding to an interaction is just like sending a webhook request!
There are a number of ways you can respond to an interaction:
### Interaction Response Object
###### Interaction Response Structure
| Field | Type | Description |
| ----- | ------- | ------------------------------------------------------------------ |
| type | integer | The [type of the interaction response](#interaction-callback-type) |
| data? | object | The [data of the interaction response](#interaction-callback-type) |
###### Interaction Callback Type
Depending on the interaction type, not all callback types may be available. See `Allowed by` column for interaction types that allow usage of specific callback type.
| Value | Name | Description | Data | Allowed By |
| ----- | --------------------------------------- | ----------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------- |
| 1 | PONG | Acknowledge a [`PING`](#interaction-type) interaction | | `PING` |
| ~~2~~ | ~~ACKNOWLEDGE~~ | ~~Acknowledge a command without sending a message, eating the user's input~~ | | |
| ~~3~~ | ~~CHANNEL_MESSAGE~~ | ~~Respond with a message, eating the user's input~~ | | |
| 4 | CHANNEL_MESSAGE_WITH_SOURCE | Respond to an interaction with a message | [interaction callback message data](#interaction-callback-message-data-structure) object | `APPLICATION_COMMAND`, `MESSAGE_COMPONENT`, `MODAL_SUBMIT` |
| 5 | DEFERRED_CHANNEL_MESSAGE_WITH_SOURCE | Acknowledge an interaction and send a message later; the user sees a loading state | [interaction callback message data](#interaction-callback-message-data-structure) object | `APPLICATION_COMMAND`, `MESSAGE_COMPONENT`, `MODAL_SUBMIT` |
| 6 | DEFERRED_UPDATE_MESSAGE | Acknowledge an interaction and edit the original message later; the user does not see a loading state | [interaction callback message data](#interaction-callback-message-data-structure) object | `MESSAGE_COMPONENT`, `MODAL_SUBMIT` (only when the modal is triggered by a message component) |
| 7 | UPDATE_MESSAGE | Edit the message that the interacted component was attached to | [interaction callback message data](#interaction-callback-message-data-structure) object | `MESSAGE_COMPONENT`, `MODAL_SUBMIT` (only when the modal is triggered by a message component) |
| 8 | APPLICATION_COMMAND_AUTOCOMPLETE_RESULT | Respond to an autocomplete interaction with suggested choices | [interaction callback autocomplete data](#interaction-callback-autocomplete-data-structure) object | `APPLICATION_COMMAND_AUTOCOMPLETE` |
| 9 | MODAL | Respond to an interaction with a popup modal | [interaction callback modal data](#interaction-callback-modal-data-structure) object | `APPLICATION_COMMAND`, `MESSAGE_COMPONENT` |
| 10 | PREMIUM_REQUIRED **(deprecated)** ^1^ | Respond to an interaction with an upgrade button | | `APPLICATION_COMMAND`, `MESSAGE_COMPONENT`, `MODAL_SUBMIT` |
| 11 | IFRAME_MODAL ^2^ | Respond to an interaction with an IFrame modal | [interaction callback iframe modal data](#interaction-callback-iframe-modal-data-structure) object | `APPLICATION_COMMAND`, `MESSAGE_COMPONENT` |
| 12 | LAUNCH_ACTIVITY ^3^ | Launch an embedded activity associated with the application | | `APPLICATION_COMMAND`, `MESSAGE_COMPONENT`, `MODAL_SUBMIT` |
| 13 | SOCIAL_LAYER_SKU_PURCHASE_ELIGIBILITY | Respond to an interaction with purchase eligibility for a social layer SKU | [interaction callback social layer SKU purchase eligibility data](#interaction-callback-social-layer-sku-purchase-eligibility-data-structure) object | `SOCIAL_LAYER_SKU_PURCHASE_ELIGIBILITY` |
^1^ Only available if the application has access to monetization features. Deprecated: see [premium buttons](/resources/components#button-style) instead.
^2^ Only available if the application has the [`IFRAME_MODAL`](/resources/application#application-flags) flag.
^3^ Only available if the application has the [`EMBEDDED`](/resources/application#application-flags) flag.
###### Interaction Callback Message Data Structure
Not all message fields are currently supported.
As interaction responses and followups are webhooks, they respect @everyone's ability to ping @everyone / @here. Nonetheless if your application responds with user data, you should still use [`allowed_mentions`](/resources/message#allowed-mentions-object) to filter which mentions in the content actually ping.
| Field | Type | Description |
| ----------------- | ------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| content? | string | The message contents (up to 2000 characters) |
| tts? | boolean | Whether this is a TTS message |
| embeds? | array[[embed](/resources/message#embed-object) object] | Embedded `rich` content (max 6000 characters, max 10) |
| allowed_mentions? | [allowed mention](/resources/message#allowed-mentions-object) object | Allowed mentions for the message |
| components? | array[[message component](/resources/components#component-object) object] | The components to include with the message |
| flags? | integer | The [message's flags](/resources/message#message-flags) (only `SUPPRESS_EMBEDS`, `EPHEMERAL`, `SUPPRESS_NOTIFICATIONS`, `VOICE_MESSAGE`, `IS_COMPONENTS_V2` can be set) |
| attachments? ^1^ | array[partial [attachment](/resources/message#attachment-object) object] | Partial attachment objects with `filename` and `description` (max 10) |
| poll? | [poll create](/resources/message#poll-create-structure) object | A poll! |
###### Interaction Callback Autocomplete Data Structure
| Field | Type | Description |
| ------- | --------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------- |
| choices | array[[application command option choice](/interactions/application-commands#application-command-option-choice-structure) object] | The autocompleted choices (max 25) |
###### Interaction Callback Modal Data Structure
| Field | Type | Description |
| ---------- | ----------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| custom_id | string | Developer-defined identifier for the modal (1-100 characters) |
| title | string | The title of the modal (max 45 characters) |
| components | array[[component](/resources/components#component-object) object] | Components of the type [action row](/resources/components#action-row), [text display](/resources/components#text-display), or [label](/resources/components#label) (1-5) |
###### Interaction Callback IFrame Modal Data Structure
| Field | Type | Description |
| --------------- | ------- | -------------------------------------------------------------------- |
| iframe_path ^1^ | string | The relative URL to the iFrame modal (max 2048 characters) |
| title | string | The title of the modal (max 45 characters) |
| modal_size | integer | The [size of the modal](#iframe-modal-size) |
| custom_id | string | Developer-defined identifier for the iFrame modal (1-100 characters) |
^1^ The complete iFrame URL will be `https://{application_id}.discordsays.com/{iframe_path}?instance_id={channel_id}:{application_id}:{custom_id}&custom_id={custom_id}&channel_id={channel_id}&guild_id={guild_id}&frame_id={frame_id}&platform={platform}` where `guild_id` is optional, `frame_id` is a unique UUID for the frame, and `platform` is either `desktop` or `mobile`.
###### IFrame Modal Size
| Value | Name | Description |
| ----- | ------ | ------------ |
| 1 | SMALL | Small modal |
| 2 | NORMAL | Normal modal |
| 3 | BIG | Big modal |
###### Interaction Callback Social Layer SKU Purchase Eligibility Data Structure
| Field | Type | Description |
| -------- | ------- | ------------------------------------------------------------ |
| eligible | boolean | Whether the user is eligible for a social layer SKU purchase |
When responding to an interaction received **via webhook**, your server can simply respond to the received `POST` request. You'll want to respond with a `200` status code (if everything went well), as well as specifying a `type` and `data`, which is an [Interaction Response](#interaction-response-object) object:
```py
@app.route('/', methods=['POST'])
def handle_interaction():
if request.json["type"] == 1:
return jsonify({
"type": 1
})
return jsonify({
"type": 4,
"data": {
"content": "Congrats on sending your command!",
}
})
```
Optionally, you can also return a `202` status code and response to the interaction with a regular HTTP request, as described below. Note that **this does not apply to `PING` interactions**, which must be responded to directly.
If you are receiving interactions over the Gateway, you will **also need to respond via HTTP**. Note that responses to interactions **are not sent as commands over the Gateway**.
To respond to an interaction coming from the Gateway, make a `POST` request like this. `interaction_id` and `interaction_token` are both from the received payload.
```py
url = f"https://discord.com/api/v10/interactions/{interaction_id}/{interaction_token}/callback"
json = {
"type": 4,
"data": {
"content": "Congrats on sending your command!"
}
}
r = requests.post(url, json=json)
```
Interaction `tokens` are valid for **15 minutes** and can be used to send followup messages; but, you **must send an initial response within 3 seconds of receiving the event**. If the 3 second deadline is exceeded, the token will be invalidated.
## Followup Messages
Sometimes, your application will want to send followup messages to a user after responding to an interaction. Or, you may want to edit your original response. Whether you receive interactions over the Gateway or by outgoing webhook, you can use the following endpoints to edit your initial response or send followup messages:
- [`PATCH /webhooks/{application.id}/{interaction.token}/messages/@original`](#modify-original-interaction-response) to edit your initial response to an interaction
- [`DELETE /webhooks/{application.id}/{interaction.token}/messages/@original`](#delete-original-interaction-response) to delete your initial response to an interaction
- [`POST /webhooks/{application.id}/{interaction.token}`](#create-followup-message) to send a new followup message
- [`PATCH /webhooks/{application.id}/{interaction.token}/messages/{message.id}`](#modify-followup-message) to edit a message sent with that `token`
Interaction webhooks share the same rate limit properties as normal webhooks.
Interaction tokens are valid for **15 minutes**, meaning you can respond to an interaction within that amount of time.
## Security and Authorization
The internet is a scary place, especially for people hosting open, unauthenticated endpoints. If you are receiving interactions via outgoing webhook, there are some security steps you **must** take before your app is eligible to receive requests.
Every interaction request is sent with the following headers:
- `X-Signature-Ed25519` as a signature
- `X-Signature-Timestamp` as a timestamp
Using your favorite security library, you **must validate the request each time you receive an [interaction](#interaction-object)**. If the signature fails validation, respond with a `401` error code. Here's a couple code examples:
```js
const nacl = require("tweetnacl");
// Your public key can be found on your application in the Developer Portal
const PUBLIC_KEY = "APPLICATION_PUBLIC_KEY";
const signature = req.get("X-Signature-Ed25519");
const timestamp = req.get("X-Signature-Timestamp");
const body = req.rawBody; // rawBody is expected to be a string, not raw bytes
const isVerified = nacl.sign.detached.verify(
Buffer.from(timestamp + body),
Buffer.from(signature, "hex"),
Buffer.from(PUBLIC_KEY, "hex"),
);
if (!isVerified) {
return res.status(401).end("invalid request signature");
}
```
```py
from nacl.signing import VerifyKey
from nacl.exceptions import BadSignatureError
# Your public key can be found on your application in the Developer Portal
PUBLIC_KEY = 'APPLICATION_PUBLIC_KEY'
verify_key = VerifyKey(bytes.fromhex(PUBLIC_KEY))
signature = request.headers["X-Signature-Ed25519"]
timestamp = request.headers["X-Signature-Timestamp"]
body = request.data.decode("utf-8")
try:
verify_key.verify(f'{timestamp}{body}'.encode(), bytes.fromhex(signature))
except BadSignatureError:
abort(401, 'invalid request signature')
```
If you are not properly validating this signature header, Discord will not allow you to save your interactions URL in the Developer Portal.
Discord will also do automated, routine security checks against your endpoint, including purposefully sending you invalid signatures. If you fail the validation,
Discord will remove your interactions URL in the future and alert you via email and system DM.
Currently, interactions are sent with a user agent of `Discord-Interactions/1.0 (+https://discord.com)`. However, you should not rely on this for security.
## Endpoints
Create Interaction Response
Create a response to an interaction from the Gateway. Accepts an [interaction response](#interaction-response-object) object. Returns a 204 empty response or the object below depending on the `with_response` parameter.
This endpoint also supports file attachments similar to the webhook endpoints. Refer to [Uploading Files](/reference#uploading-files) for details on uploading files and `multipart/form-data` requests.
###### Query String Params
| Field | Type | Description |
| -------------- | ------- | --------------------------------------------------------------------------------- |
| with_response? | boolean | Whether to include an interaction callback result as the response (default false) |
###### Response Body
| Field | Type | Description |
| ----------- | -------------------------------------------------------------------------------- | --------------------------------------------------------- |
| interaction | [interaction callback](#interaction-callback-structure) object | The interaction associated with the interaction response |
| resource? | [interaction callback resource](#interaction-callback-resource-structure) object | The resource that was created by the interaction response |
###### Interaction Callback Structure
| Field | Type | Description |
| --------------------------- | --------- | ----------------------------------------------------------------------------------------- |
| id | snowflake | The ID of the interaction |
| type | integer | The [type](#interaction-type) of interaction |
| response_message_id? | snowflake | The ID of the message that was created by the interaction |
| response_message_loading? | boolean | Whether the response message has the [`LOADING`](/resources/message#message-flags) flag |
| response_message_ephemeral? | boolean | Whether the response message has the [`EPHEMERAL`](/resources/message#message-flags) flag |
| activity_instance_id? | string | The ID of the launched activity instance |
| channel_id? | snowflake | The ID of the channel the interaction was created in |
| guild_id? | snowflake | The ID of the guild the interaction was created in |
###### Interaction Callback Resource Structure
| Field | Type | Description |
| ---------------------- | -------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------- |
| type | integer | The [type](#interaction-callback-type) of interaction callback |
| activity_instance? ^1^ | [interaction callback activity instance resource](#interaction-callback-activity-instance-resource-structure) object | The activity launched by the interaction callback |
| message? ^2^ | [message](/resources/message#message-object) object | The message created by the interaction callback |
^1^ Only applicable if `type` is [`LAUNCH_ACTIVITY`](#interaction-callback-type).
^2^ Only applicable if `type` is [`CHANNEL_MESSAGE_WITH_SOURCE`, or `UPDATE_MESSAGE`](#interaction-callback-type).
###### Interaction Callback Activity Instance Resource Structure
| Field | Type | Description |
| ----- | ------ | ---------------------------------------- |
| id | string | The ID of the launched activity instance |
Get Original Interaction Response
Returns the initial interaction response. Functions the same as [Get Webhook Message](/resources/webhook#get-webhook-message).
Modify Original Interaction Response
Edits the initial interaction response. Functions the same as [Edit Webhook Message](/resources/webhook#edit-webhook-message).
Delete Original Interaction Response
Deletes the initial interaction response. Returns a 204 empty response on success.
Create Followup Message
Create a followup message for an interaction. Functions the same as [Execute Webhook](/resources/webhook#execute-webhook), but `wait` is always true, and `flags` can have `EPHEMERAL` flag to send an ephemeral message. The `thread_id` query parameter is ignored when using this endpoint for interaction followups.
Get Followup Message
Returns a followup message for an interaction. Functions the same as [Get Webhook Message](/resources/webhook#get-webhook-message). Does not support ephemeral followups.
Modify Followup Message
Edits a followup message for an interaction. Functions the same as [Edit Webhook Message](/resources/webhook#edit-webhook-message). Does not support ephemeral followups.
Delete Followup Message
Deletes a followup message for an interaction. Functions the same as [Delete Webhook Message](/resources/webhook#delete-webhook-message). Does not support ephemeral followups.
Create Interaction
Creates an interaction. Returns a 204 empty response on success. Fires [Interaction Create](/gateway/gateway-events#interaction-create) and [Interaction Success](/gateway/gateway-events#interaction-success) or [Interaction Failure](/gateway/gateway-events#interaction-failure) Gateway events.
Files must be attached using a `multipart/form-data` body (or pre-uploaded to Discord's GCP bucket) as described in [Uploading Files](/reference#uploading-files).
###### JSON/Form Params
| Field | Type | Description |
| ------------------- | ------------- | --------------------------------------------------------------------------------------------------------- |
| type ^1^ | integer | The [type of interaction to create](#interaction-type) |
| application_id | snowflake | The ID of the application |
| guild_id? | snowflake | The ID of the guild |
| channel_id | snowflake | The ID of the channel |
| message_id? ^2^ | snowflake | The ID of the message that the component is attached to |
| message_flags? ^2^ | integer | The [message's flags](/resources/message#message-flags) |
| session_id? | string | The ID of the Gateway session to send accompanying interaction events to |
| data | object | The [interaction data](#interaction-type), depending on the interaction type |
| files[n]? ^3^ | file contents | Contents of the file being sent (max 25) |
| nonce? | string | The interaction's nonce, used for interaction deduplication |
| analytics_location? | string | [Where the interaction is being created](#interaction-creation-location) |
| section_name? | string | The [name of the section](#interaction-creation-section-name) the embedded activity is being started from |
| source? | string | The [source of interaction creation](#interaction-creation-source-type) |
^1^ To create [`SOCIAL_LAYER_SKU_PURCHASE_ELIGIBILITY`](#interaction-type) interactions, the [Check Social Layer SKU Purchase Eligibility](/resources/store#check-social-layer-sku-purchase-eligibility) endpoint is used instead.
^2^ Only applicable for [`MESSAGE_COMPONENT` interactions](#interaction-type).
^3^ See [Uploading Files](/reference#uploading-files) for details.
###### Sendable Application Command Data Structure
| Field | Type | Description |
| -------------------- | ------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------- |
| id | snowflake | The ID of the application command |
| type? | integer | The [type of the application command](/interactions/application-commands#application-command-type) |
| name | string | The name of the application command |
| version | snowflake | The autoincrementing version identifier updated during substantial command record changes |
| application_command? | [application command](/interactions/application-commands#application-command-object) object | The application command being executed |
| options? ^1^ | array[[application command data option](#application-command-data-option-structure) object] | The options with their values |
| target_id? ^2^ | snowflake | The ID of the user or message targeted by a context menu command |
| attachments? ^3^ | array[partial [attachment](/resources/message#attachment-object) object] | The attachments to upload (max 25) |
^1^ Only applicable when the application command type is [`CHAT_INPUT`](/interactions/application-commands#application-command-type).
^2^ Only applicable when the application command type is [`USER` or `MESSAGE`](/interactions/application-commands#application-command-type).
^3^ See [Uploading Files](/reference#uploading-files) for details.
###### Sendable Message Component Data Structure
| Field | Type | Description |
| ------------------- | --------------------------------- | ----------------------------------------------------------------- |
| component_type? ^1^ | integer | The [type of the component](/resources/components#component-type) |
| type? ^1^ | integer | The [type of the component](/resources/components#component-type) |
| custom_id | string | The developer-defined identifier for the component |
| values? ^2^ | array[snowflake] \| array[string] | The selected options in the select menu |
^1^ Either `component_type` or `type` must be provided.
^2^ Only applicable for select menu components.
###### Sendable Modal Submit Data Structure
| Field | Type | Description |
| ---------------- | ----------------------------------------------------------------------------------- | -------------------------------------------------- |
| id | snowflake | The ID of the interaction that triggered the modal |
| custom_id | string | The developer-defined identifier of the modal |
| components | array[[modal submit component data](#modal-submit-component-data-structure) object] | The components in the modal |
| attachments? ^1^ | array[partial [attachment](/resources/message#attachment-object) object] | The attachments to upload (max 25) |
^1^ See [Uploading Files](/reference#uploading-files) for details.
###### Interaction Creation Location
| Value | Description |
| --------------------------------------- | ---------------------------------------------------------------------------- |
| discovery | Interaction was executed from a message content suggestion |
| suggestion | Interaction was suggested as a replacement of text commands |
| mention | Interaction was executed from a mention |
| paste | Interaction was pasted in chat |
| recall | Interaction was executed by attempting to edit a previous command invocation |
| popular_commands | Interaction was executed from an application's popular commands list |
| mj_chat_bar | Interaction was executed from a Midjourney command promotion |
| query | Interaction was executed from a message content query suggestion |
| slash_ui | Interaction was executed from the chat bar |
| app_launcher | Interaction was executed from the App Launcher |
| app_launcher_home | Interaction was executed from the App Launcher home |
| app_launcher_home_search | Interaction was executed from the App Launcher search |
| app_launcher_list_view_all | Interaction was executed from the App Launcher list view |
| app_launcher_application_view | Interaction was executed from the App Launcher application view |
| app_launcher_application_view_frecent | Interaction was executed from the App Launcher application frecents section |
| app_launcher_application_view_more_menu | Interaction was executed from the App Launcher view more menu |
| app_launcher_slash_search | Interaction was executed from the App Launcher command search |
| app_launcher_frecents_view_all | Interaction was executed from the App Launcher frecents section |
| image_recs_menu | Interaction was executed from the "Edit Image With Apps" menu |
| image_recs_submenu | Interaction was executed from the "Edit Image With Apps" submenu |
| activity_instance_embed | Interaction was executed from an activity instance embed |
| activity_bookmark_embed | Interaction was executed from an activity bookmark embed |
| activities_mini_shelf | Interaction was executed from the activities mini shelf |
| vc_tile_activity_suggestion | Interaction was executed from the activity suggestions in a voice channel |
| app_dms_entry_point_command_button | Interaction was executed by clicking the "Play" button in the chat bar |
###### Interaction Creation Section Name
This value may also be the name of an App Launcher subsection, such as `Promoted` or `Puzzle Games`.
| Value | Description |
| ------------------- | ---------------------------------- |
| search | Search results |
| ~~recent~~ | ~~Recent apps~~ |
| ~~installed~~ | ~~Installed apps~~ |
| activities | Activity Launcher |
| recent_apps | App Launcher > Recents |
| recent_commands | App Launcher > Recents > Commands |
| new_to_apps | New user app coachmark |
| apps_in_this_server | App Launcher > Apps in this Server |
###### Interaction Creation Source Type
| Value | Description |
| ----- | ---------------------------------------------- |
| NONE | Unknown |
| TEXT | The interaction was created in a text channel |
| VOICE | The interaction was created in a voice channel |
---
# Mobile
Link: https://docs.discord.food/remote-authentication/mobile
In the context of remote authentication, the mobile client is the device that is logged in and willing to transfer credentials to the desktop client.
See the [introduction](/remote-authentication/overview) for more information.
## Protocol
Upon scanning the QR code, the mobile client should extract the fingerprint from the received URL (the URL should be in the format `https://discord.com/ra/`).
Once the client has a fingerprint, it can create a new remote auth session using [Create Remote Auth Session](#create-remote-auth-session).
After the session has been established, the client should prompt the user to either accept or deny the request, and then perform this action using [Finish Remote Auth](#finish-remote-auth) or [Cancel Remote Auth](#cancel-remote-auth).
## Endpoints
Create Remote Auth Session
Creates a new remote auth session. This sends the current user info to the desktop client.
###### JSON Params
| Field | Type | Description |
| ----------- | ------ | --------------------------------------------------------------- |
| fingerprint | string | The fingerprint corresponding to the desktop remote auth client |
###### Response Body
| Field | Type | Description |
| --------------- | ------ | -------------------------------------------------------------------- |
| handshake_token | string | The handshake token that can be used to finish or cancel the session |
###### Example Response
```json
{
"handshake_token": ".eJwVkcmSokAARP_Fq0MrICIdExNRYOECsigt4GUCpCgKZC9A6Jh_H_qWkS_z9L4XRRmhxeeiQXlJERN0NGFwQNEQjEzVREwekILBYk8XvxYViebl7_UHy0nbD4Hjtn9-2i58keffDI0zvJxO8ikFhoyzOsnIQRrWMrChCoCpAHsHfriCtTlD0Efmmm6yIp0IyU3Xqh_x-7gStVU3VncD0YPlbZUq13bQTZ5Vfuv5UociKa9o4tsrpW0YxlN5o8hJ3mxgIs3NuDxrB5t04uT52zwAV2cP-4to-ZrFtkF8O661rsKm8CBRYZPaIJCeVff4bNG46YYG5KEEy57FUFar4LDVAOxPHvsKRzGwJQrfkn69ZVjodc5MdyvNp1ZZi6p98KaXEeovaADgAGq4S8vBUTRekH6_sRKHU37ZjpMAqnOw11Ez8nIb5piEvhBmPZryM1ajJnf5DutdXTzEOnoWp7sq6Ks0lvda7bylOG-Mwq2VFCciai8edFvS3Aek1PoxvTRLtnv1fKoNpz2wgTx7iUmBUVM1pKCzmC_iHGiQbiNlE2mGs4OR5COg7_ma7mJmCr0g4fBd9ouv9fztUdOSslh8cv_-A8Mft7I.ZSQp6A.dPkJdzlOjDn1hIxolxZfDu2595k"
}
```
Finish Remote Auth
Finishes a remote auth session. This ends the remote auth session by sending an authentication token to the desktop client. Returns a 204 empty response on success.
###### JSON Params
| Field | Type | Description |
| -------------------- | ------- | -------------------------------------------------------------- |
| handshake_token | string | The handshake token that represents the remote auth session |
| temporary_token? ^1^ | boolean | Whether the authentication token should expire (default false) |
^1^ Expiring authentication tokens are not yet supported.
Cancel Remote Auth
Cancels a remote auth session. This ends the remote auth session without sending an authentication token. Returns a 204 empty response on success.
###### JSON Params
| Field | Type | Description |
| --------------- | ------ | ----------------------------------------------------------- |
| handshake_token | string | The handshake token that represents the remote auth session |
---
# Overview
Link: https://docs.discord.food/remote-authentication/overview
Remote authentication is a feature that allows effortless transfer of credentials from one device to another.
While officially this is used to authenticate desktop Discord clients using an already logged in mobile Discord client,
this is useful when you want to login to a device that does not have a keyboard or a display, such as a smart watch or a smart TV.
## How it Works
The way the authentication process works is fairly simple.
The client that wants to authenticate itself (referred to as "desktop") connects to a special remote auth Gateway and performs a key exchange.
The Gateway eventually responds with a value that can be displayed within a QR code for the authenticated device (referred to as "mobile") to scan:

When the QR code is scanned, the mobile client sends a request to initialize the authentication process. The desktop client then receives the mobile client's user information.
After this occurs, the user has the ability to verify and accept/deny the authentication request on the mobile client. If the user accepts the request, the desktop client receives the user's authorization token.
## How to Use
To get started with using remote authentication, you can fulfill the role of either the desktop client or the mobile client.
The desktop client is the client that wants to authenticate itself, and the mobile client is the client that will be used to verify the authentication request.
For detailed information on the desktop client, please refer to the [desktop section](/remote-authentication/desktop).
To learn more about the mobile client, visit the [mobile section](/remote-authentication/mobile).
---
# Desktop
Link: https://docs.discord.food/remote-authentication/desktop
In the context of remote authentication, the desktop client is the device that wants to be authenticated by the already logged-in mobile client.
See the [introduction](/remote-authentication/overview) for more information.
## Remote Authentication Gateway
The desktop implementation of remote authentication uses WebSocket connections, operating similarly to the [Gateway](/gateway/using-gateway#connections) connection.
However, it has a separate set of payloads and events, as well as a simplified packet structure.
###### Gateway Versions
| Version | Status |
| ------- | ------------ |
| 2 | Available |
| 1 | Discontinued |
### Gateway Payloads
In practice, opcodes are lower-cased with under_scores joining each word in the name. For instance, [Nonce Proof](<#nonce-proof-structure-(receive)>) would be `nonce_proof`.
For readability, opcodes in the following documentation are typically left in Title Case.
Remote authentication Gateway event payloads are flat packets, with the `op` field indicating the type of payload, and the rest of the fields being the payload data.
###### Example Gateway Payload
```json
{
"op": "hello",
"timeout_ms": 142637,
"heartbeat_interval": 41250
}
```
###### Gateway Commands
| Name | Description |
| ---------------------------------------------- | --------------------------------------------- |
| [Init](#init-structure) | Start a new remote auth session |
| [Heartbeat](#heartbeating) | Maintain an active WebSocket connection |
| [Nonce Proof](<#nonce-proof-structure-(send)>) | Submit a cryprographic proof of the handshake |
###### Gateway Events
| Name | Description |
| ----------------------------------------------------- | ------------------------------------------------------------------------------------------------------------- |
| [Hello](#hello-structure) | Defines the heartbeat and timeout intervals |
| [Heartbeat ACK](#heartbeating) | Acknowledges a received client heartbeat |
| [Nonce Proof](<#nonce-proof-structure-(receive)>) | Requests a cryptographic proof of the handshake |
| [Pending Remote Init](#pending-remote-init-structure) | Acknowledges a successful handshake |
| [Pending Ticket](#pending-ticket-structure) | Acknowledges a successful [mobile session creation](/remote-authentication/mobile#create-remote-auth-session) |
| [Pending Login](#pending-login-structure) | Indicates that the mobile session was [finished](/remote-authentication/mobile#finish-remote-auth) |
| [Cancel](#example-cancel) | Indicates that the mobile session was [canceled](/remote-authentication/mobile#cancel-remote-auth) |
###### Gateway Close Event Codes
| Code | Description | Explanation |
| -------- | ----------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| 1000 ^1^ | Normal closure | The remote auth session was [finished](/remote-authentication/mobile#finish-remote-auth) or [canceled](/remote-authentication/mobile#cancel-remote-auth) successfully. |
| 4000 | Invalid version | You sent an invalid version for the remote auth Gateway. |
| 4001 | Decode error | You sent an invalid payload. Don't do that! |
| 4002 | Handshake failure | The [initial handshake](#handshaking) failed. Maybe reconnect and try again? |
| 4003 | Timeout | Your session [timed out](#hello-structure). Reconnect and start a new one. |
^1^ This code may be erroneously received for protocol errors.
### Connecting
For the remote authentication Gateway, the URL you can use to open a WebSocket connection [is static](#endpoint).
When connecting to the URL, you must explicitly pass the API version as a query parameter. For example, `wss://remote-auth-gateway.discord.gg/?v=2` is a URL a client may use to connect to the Gateway.
When connecting to the remote authentication Gateway, you must specify an `Origin` header, set to one of `https://discord.com`, `https://ptb.discord.com`, or `https://canary.discord.com`.
If the origin is invalid, the connection will be rejected. This is to prevent malicious websites from using remote authentication to hijack user accounts.
###### Endpoint
```
wss://remote-auth-gateway.discord.gg/
```
###### Query String Params
| Field | Type | Description |
| ----- | ------- | --------------------------------------- |
| v | integer | [API Version](#gateway-versions) to use |
### Handshaking
Once you open a connection to the Gateway, you will receive an [Opcode Hello](#hello-structure) payload, which contains the heartbeat interval and timeout duration. See the [heartbeating](#heartbeating) section for more information.
At this point, you should generate a 2048-bit RSA-OAEP keypair that will be used in further communications. This will be verified by the Gateway using a nonce proof. An example in Python pseudocode would be:
```py
import base64
from cryptography.hazmat.primitives import serialization, hashes
from cryptography.hazmat.primitives.asymmetric import rsa, padding
private_key = rsa.generate_private_key(
public_exponent=65537,
key_size=2048,
)
public_key = private_key.public_key()
```
###### Hello Structure
| Field | Type | Description |
| ------------------ | ------- | ------------------------------------------------------------------------------------------------------------------ |
| heartbeat_interval | integer | The minimum interval (in milliseconds) the client should heartbeat at |
| timeout_ms ^1^ | integer | The lifespan of the remote auth session (in milliseconds) before the connection is closed, typically a few minutes |
^1^ When the timeout duration passes, the Gateway will close with a [`4003` close code](#gateway-close-event-codes).
###### Example Hello
```json
{
"op": "hello",
"timeout_ms": 142637,
"heartbeat_interval": 41250
}
```
Upon receiving the [Opcode Hello](#hello-structure) payload, you should immediately send an [Opcode Init](#init-structure) containing the public key that all future communication will be encrypted with.
An example in Python pseudocode would be:
```py
spki = public_key.public_bytes(
encoding=serialization.Encoding.DER,
format=serialization.PublicFormat.SubjectPublicKeyInfo,
)
encoded_public_key = base64.b64encode(spki).decode("utf-8")
```
###### Init Structure
| Field | Type | Description |
| ------------------ | ------ | -------------------------------------------------------------------- |
| encoded_public_key | string | The base64-encoded SPKI of the client's 2048-bit RSA-OAEP public key |
###### Example Init
```json
{
"op": "init",
"encoded_public_key": "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAo2PGAKj4v6r6sPJtgJe2eIDCM8uEHKpYCSDmp+pun9vqiqPt4pDToS1vGtwTwc5hKKqtIo+I/5veBpGWSD/veuB0xVb/JbkPn847Q+mXAb6c9vRMJVkA7l9GaZdN49U5bnGJi009aNBoy9cAcP/19H6TLpHmZ9RojnqGqlCUdyAiqceTDTzPqov4ST3GJSyKPydL3ZVpPf5P/PGyNfISuESKA2CxGCoBvB4H6/FH7cwSFelyqhwwHPZcyxBjF/3iXx+k1PdS01y0NoTRun4p76bE9rWnecIWONPFvCkby8Xs/OqQ8QcAoLkfVj5L29Ut1+Kmwwfg3nzc4glZa6RuTwIDAQAB"
}
```
If the Gateway accepts the public key, it will respond with an [Opcode Nonce Proof](<#nonce-proof-structure-(receive)>) payload, which contains a nonce that you must decrypt with your private key.
###### Nonce Proof Structure (Receive)
| Field | Type | Description |
| --------------- | ------ | --------------------------------------------------------------- |
| encrypted_nonce | string | The base64-encoded nonce encrypted with the client's public key |
###### Example Nonce Proof (Receive)
```json
{
"op": "nonce_proof",
"encrypted_nonce": "GrOYi2wz9athue0mTNrdlnWGqJYkqu8tPe2uGr9V7CRwqVWDjgUI06gsPKszkORgB92P1P84V04fo7hG0tkQ/kDVNbVguACKfE4AIUUQXQFSkTVaGbZ2+FsItsoqOd+955EvkBK2oMz+kWlYILTQcISip9g5ZrY9SoKQvk7HDW9DliSteZivHzXQOc5RyecyeexOcV8oyC1zTk+uyVUTv3g7fcZ1Y81AK6u4+hvnEKGjOyEn+lbOotkNwcMC02xyVBX3IysSuNXf/f8/6gPMBNUHXEtlvhYx9AMCsPrPKkiilV7HpLN3oIvAfsZnyxbYcNiC6YS7z7VIPRaXEWW76w=="
}
```
You should then send an [Opcode Nonce Proof](<#nonce-proof-structure-(send)>) payload containing the base64URL-encoded decrypted nonce.
An example in Python pseudocode would be:
```py
nonce = private_key.decrypt(
base64.b64decode(encrypted_nonce),
padding.OAEP(mgf=padding.MGF1(algorithm=hashes.SHA256()), algorithm=hashes.SHA256(), label=None),
)
nonce_proof = base64.urlsafe_b64encode(nonce).decode("utf-8").rstrip("=")
```
###### Nonce Proof Structure (Send)
| Field | Type | Description |
| ----- | ------ | ------------------------------------- |
| nonce | string | The base64URL-encoded decrypted nonce |
###### Example Nonce Proof (Send)
```json
{
"op": "nonce_proof",
"nonce": "1xFdzsYTFMtZuUarGNKpBpMANyqNpRXpDFaxl8wFeQBUnVuY60d9j-or80f36xusAVTmUL90jwHrxMVPGZXJ8ahqDAiXByEOjkreJXZdPRbnvDkHHyqUP0QgHQBvrKq5Cba9-SDO8pFSc9T1YMWGut7n34xx6txX-QR7wDcZAoghq5EBl04WRlnt1DWfX2wMA7NuL1GFIZdw10IedBZ13E72BXnDasX97XMX_ldbxKwee6ABGf18zde2oHbTqw"
}
```
If any part of the handshake fails, the Gateway will close with a [`4001` close code](#gateway-close-event-codes).
If the Gateway accepts the nonce proof, it will respond with an [Opcode Pending Remote Init](#pending-remote-init-structure) payload, which indicates that the key exchange was successful and the remote auth session is ready.
At this point, the fingerprint can be used to [create a remote auth session](/remote-authentication/mobile#create-remote-auth-session) on the mobile client.
The fingerprint is typically communicated using a QR code with the following format: `https://discord.com/ra/`.
Clients should verify the sent fingerprint is the same as the base64URL-encoded SHA-256 digest of the client's public key as a security measure.
If the fingerprints do not match, the client should close the connection and reconnect.
###### Pending Remote Init Structure
| Field | Type | Description |
| ----------- | ------ | --------------------------------------------------------------- |
| fingerprint | string | The base64URL-encoded SHA-256 digest of the client's public key |
###### Example Pending Remote Init
```json
{
"op": "pending_remote_init",
"fingerprint": "UZ0-kOVzXDZTFVV5_QlpURSO2BQHrtkKWHNpIGoDI0k"
}
```
### Heartbeating
In order to maintain your WebSocket connection, you need to continuously send heartbeats at the interval determined in [Opcode Hello](#hello-structure):
This heartbeat interval is the minimum interval you should heartbeat at. You can heartbeat at a faster interval if you wish.
After receiving [Opcode Hello](#hello-structure), you should send [Opcode Heartbeat](#example-heartbeat) every elapsed interval:
The first heartbeat may be offset by a value between 0 and `heartbeat_interval` in order to prevent too many clients from connecting at the same time (which could cause an influx of traffic).
In return, you will be sent back an [Opcode Heartbeat ACK](#example-heartbeat-ack).
If a client does not receive a heartbeat ACK between its attempts at sending heartbeats, this may be due to a failed or "zombied" connection.
The client should immediately terminate the connection and reconnect.
###### Example Heartbeat
```json
{ "op": "heartbeat" }
```
###### Example Heartbeat ACK
```json
{ "op": "heartbeat_ack" }
```
### Finalizing
Once the mobile client [creates a remote auth session](/remote-authentication/mobile#create-remote-auth-session) (scans the QR code), the Gateway will send an [Opcode Pending Ticket](#pending-ticket-structure) payload, which contains the information of the user that is attempting to authenticate.
This payload must be decrypted using your private key. An example in Python pseudocode would be:
```py
user_payload_bytes = private_key.decrypt(
base64.b64decode(encrypted_user_payload),
padding.OAEP(mgf=padding.MGF1(algorithm=hashes.SHA256()), algorithm=hashes.SHA256(), label=None),
)
user_id, discriminator, avatar, username = user_payload_bytes.decode("utf-8").split(":")
```
###### Pending Ticket Structure
| Field | Type | Description |
| ---------------------- | ------ | ------------------------------------------------------------------------------------------------- |
| encrypted_user_payload | string | The base64-encoded [user payload](#user-payload-structure) encrypted with the client's public key |
###### User Payload Structure
The user payload is a colon-separated string in the format `852892297661906993:0:05145cc5646fbcba277b6d5ea2030610:dolfies`.
It contains the following fields (see the [user](/resources/user#user-object) object for more information):
| Field | Type | Description |
| ------------- | --------- | --------------------------------------------------- |
| id | snowflake | The ID of the user |
| discriminator | string | The user's stringified 4-digit Discord tag |
| avatar ^1^ | string | The user's [avatar hash](/reference#cdn-formatting) |
| username | string | The user's username (2-32 characters) |
^1^ The avatar hash will be `0` to represent a `null` avatar.
###### Example Pending Ticket
```json
{
"op": "pending_ticket",
"encrypted_user_payload": "MeJm9TeLa9S+/gUYZlm69TQqT3eqz1sG6f5Ym84lGCH7Hde/Dpv/knXX+wWp8WeyLPHYGn1smpTaGxwHmuvee1IZv8ybP9WeVscsBnrXpO7Fg2aT3hZJfPStncJxI0Uq+JhjqQ1V2lLuhoraeBrZbl/e0CBNhv0wmIGzFow6G078MQvikg20Jr+/2wRgY/buXuipqfW9RYIZUyr3Dl+MRW8EodKU3SOBgqaVpHETDLXkmb6rsvYU+O78iUu+cvTK3A0GkajxmhJ2nfg79iQBuLU6qJm7sN9mHy2uKAExa5TUJfeeCqXjTr1uROozlyBmCMjeP+Srrg37r0y2pkjYCg=="
}
```
At this point, the desktop client will either receive an [Opcode Pending Login](#pending-login-structure) or [Opcode Cancel](#example-cancel) event.
Both of these events will result in the Gateway closing with a [`1000` close code](#gateway-close-event-codes). If neither of these events occur (the mobile client does not finish or cancel), the Gateway will eventually timeout and close with a [`4003` close code](#gateway-close-event-codes).
If the mobile client [finishes remote auth](/remote-authentication/mobile#finish-remote-auth), the Gateway will send an [Opcode Pending Login](#pending-login-structure) payload, which indicates that the authentication was successful.
###### Pending Login Structure
| Field | Type | Description |
| ------ | ------ | ----------------------------------------------------------------------------- |
| ticket | string | The ticket that can be used to [obtain a token](#exchange-remote-auth-ticket) |
###### Example Pending Login
```json
{
"op": "pending_login",
"ticket": "ODUyODkyMjk3NjYxOTA2OTkz.HYoNwT.1X5Qs3Sd2Z2sDf3sFFFwd22_MccjcmwY"
}
```
If the mobile client [cancels remote auth](/remote-authentication/mobile#cancel-remote-auth), the Gateway will send an [Opcode Cancel](#example-cancel) payload, which indicates that the authentication was canceled.
###### Example Cancel
```json
{ "op": "cancel" }
```
## Endpoints
Exchange Remote Auth Ticket
Exchanges a remote auth ticket for an [authentication token](/reference#authentication).
The token must be decrypted using the client's private key. An example in Python pseudocode would be:
```py
encrypted_token_bytes = base64.b64decode(encrypted_token)
token = private_key.decrypt(
encrypted_token_bytes,
padding.OAEP(mgf=padding.MGF1(algorithm=hashes.SHA256()), algorithm=hashes.SHA256(), label=None),
).decode("utf-8")
```
###### JSON Params
| Field | Type | Description |
| ------ | ------ | ---------------------------------------------------------------------- |
| ticket | string | The ticket obtained from the [remote authentication flow](#finalizing) |
###### Response Body
| Field | Type | Description |
| --------------- | ------ | --------------------------------------------------------------- |
| encrypted_token | string | The authentication token encrypted with the client's public key |
---