Interactions

An interaction 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, it includes the values that the user submitted.

For User Commands and Message Commands, it includes the resolved user or message on which the action was taken.

For Message 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
FieldTypeDescription
versionintegerThe interactions system version (currently 1)
idsnowflakeThe ID of the interaction
application_idsnowflakeThe ID of the application this interaction is for
typeintegerThe type of the interaction
tokenstringThe continuation token for responding to the interaction
data? 1objectThe interaction data, depending on interaction type
guild?interaction guildThe guild the interaction was created in
guild_id?snowflakeThe ID of the guild the interaction was created in
guild_locale?stringThe preferred locale of the guild
channel?channelThe channel it was sent from
channel_id? 1snowflakeThe ID of the channel it was sent from
member? 2guild member objectThe guild member representing the invoking user
user? 2partial user objectThe invoking user
locale?stringThe language option of the invoking user
message? 4message objectThe message the components are attached to
app_permissionsstringThe permissions the application has in the source location of the interaction
entitlementsarray[entitlement 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 3map[integer, snowflake]The ID of the target for each application integration type
context? 1integerThe context the interaction is triggered in
attachment_size_limitintegerThe 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 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
ValueNameDescriptionReceived DataSent Data
1PINGDiscord is pinging the application——
2APPLICATION_COMMANDUser uses an application commandapplication command data objectsendable application command data object
3MESSAGE_COMPONENTUser triggers a message componentmessage component data objectsendable message component data object
4APPLICATION_COMMAND_AUTOCOMPLETEUser is requesting an application command option to be auto-completedapplication command data objectsendable application command data object
5MODAL_SUBMITUser submits a modalmodal submit data objectsendable modal submit data object
6SOCIAL_LAYER_SKU_PURCHASE_ELIGIBILITYUser is checking purchase eligibility for a social layer SKUsocial layer SKU purchase eligibility object—
Interaction Context Type
ValueNameDescription
0GUILDThe interaction can be triggered within guilds
1BOT_DMThe interaction can be triggered within DM channel with the application
2PRIVATE_CHANNELThe interaction can be triggered in all DM and group DMs
Interaction Guild Structure
FieldTypeDescription
idsnowflakeThe ID of the guild
featuresarray[string]Enabled guild features
localestringThe preferred locale of the guild
Application Command Data Structure
FieldTypeDescription
idsnowflakeThe ID of the invoked command
namestringThe name of the invoked command
typeintegerThe type of the invoked command
resolved?resolved data objectThe resolved entities
options? 1 2array[application command data option object]The options with their values
guild_id?snowflakeThe ID of the guild that the command is registered to
target_id? 3snowflakeThe ID of the user or message targeted by the command

1 This can be partial in response to APPLICATION_COMMAND_AUTOCOMPLETE interactions.

2 Only present when the application command type is CHAT_INPUT.

3 Only present when the application command type is USER or MESSAGE.

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.

FieldTypeDescription
typeintegerThe type of the application command option
namestringThe name of the option
value? 1boolean | float | integer | snowflake | stringThe value of the option
options?array[application command data option object]The nested options (only applicable if the option is a subcommand or subcommand group)
focused? 2booleanWhether the option is the currently focused option for autocomplete

1 For ATTACHMENT options, value will be the attachment ID.

2 Only applicable for APPLICATION_COMMAND_AUTOCOMPLETE interactions.

Message Component Data Structure
FieldTypeDescription
custom_idstringThe developer-defined identifier for the component
component_typeintegerThe type of the component
values 1array[snowflake] | array[string]The values that the user selected in a select menu
resolved? 1resolved dataThe resolved entities

1 Only present for select menu components.

FieldTypeDescription
custom_idstringThe developer-defined identifier of the modal
componentsarray[modal submit component data object]The submitted values
resolved?resolved dataThe resolved entities
FieldTypeDescriptionComponent Type
id 1integerThe ID of the componentAll
typeintegerThe type of the componentAll
custom_idstringThe developer-defined identifier for the componentSTRING_SELECT, USER_SELECT, ROLE_SELECT, MENTIONABLE_SELECT, CHANNEL_SELECT, TEXT_INPUT, FILE_UPLOAD, RADIO_GROUP, CHECKBOX_GROUP, CHECKBOX
valuestring | booleanThe value that the user inputtedTEXT_INPUT, RADIO_GROUP, CHECKBOX
valuesarray[snowflake] | array[string]The values that the user selected or uploadedSTRING_SELECT, USER_SELECT, ROLE_SELECT, MENTIONABLE_SELECT, CHANNEL_SELECT, FILE_UPLOAD, CHECKBOX_GROUP
componentmodal submit component data objectInner componentLABEL
componentsarray[modal submit component data object]Inner componentsACTION_ROW

1 id does not need to be provided when creating an interaction.

Social Layer SKU Purchase Eligibility Data Structure
FieldTypeDescription
sku_idsnowflakeThe ID of the SKU

Resolved Data Object

Holds extra entities that have been resolved from IDs in an interaction or message.

Resolved Data Structure
FieldTypeDescription
users?map[snowflake, partial user object]The resolved users
members? 1map[snowflake, partial member object]The resolved members
roles?map[snowflake, role object]The resolved roles
channels? 2map[snowflake, partial channel object]The resolved channels
messages?map[snowflake, message object]The resolved messages
attachments?map[snowflake, attachment 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. Your app can receive an interaction in one of two ways:

These two methods are mutually exclusive; you can only receive interactions one of the two ways. The Gateway event 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 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:

  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

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:

@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 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 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:

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
FieldTypeDescription
typeintegerThe type of the interaction response
data?objectThe data of the interaction response
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.

ValueNameDescriptionDataAllowed By
1PONGAcknowledge a PING interactionPING
2ACKNOWLEDGEAcknowledge a command without sending a message, eating the user's input
3CHANNEL_MESSAGERespond with a message, eating the user's input
4CHANNEL_MESSAGE_WITH_SOURCERespond to an interaction with a messageinteraction callback message data objectAPPLICATION_COMMAND, MESSAGE_COMPONENT, MODAL_SUBMIT
5DEFERRED_CHANNEL_MESSAGE_WITH_SOURCEAcknowledge an interaction and send a message later; the user sees a loading stateinteraction callback message data objectAPPLICATION_COMMAND, MESSAGE_COMPONENT, MODAL_SUBMIT
6DEFERRED_UPDATE_MESSAGEAcknowledge an interaction and edit the original message later; the user does not see a loading stateinteraction callback message data objectMESSAGE_COMPONENT, MODAL_SUBMIT (only when the modal is triggered by a message component)
7UPDATE_MESSAGEEdit the message that the interacted component was attached tointeraction callback message data objectMESSAGE_COMPONENT, MODAL_SUBMIT (only when the modal is triggered by a message component)
8APPLICATION_COMMAND_AUTOCOMPLETE_RESULTRespond to an autocomplete interaction with suggested choicesinteraction callback autocomplete data objectAPPLICATION_COMMAND_AUTOCOMPLETE
9MODALRespond to an interaction with a popup modalinteraction callback modal data objectAPPLICATION_COMMAND, MESSAGE_COMPONENT
10PREMIUM_REQUIRED (deprecated) 1Respond to an interaction with an upgrade buttonAPPLICATION_COMMAND, MESSAGE_COMPONENT, MODAL_SUBMIT
11IFRAME_MODAL 2Respond to an interaction with an IFrame modalinteraction callback iframe modal data objectAPPLICATION_COMMAND, MESSAGE_COMPONENT
12LAUNCH_ACTIVITY 3Launch an embedded activity associated with the applicationAPPLICATION_COMMAND, MESSAGE_COMPONENT, MODAL_SUBMIT
13SOCIAL_LAYER_SKU_PURCHASE_ELIGIBILITYRespond to an interaction with purchase eligibility for a social layer SKUinteraction callback social layer SKU purchase eligibility data objectSOCIAL_LAYER_SKU_PURCHASE_ELIGIBILITY

1 Only available if the application has access to monetization features. Deprecated: see premium buttons instead.

2 Only available if the application has the IFRAME_MODAL flag.

3 Only available if the application has the EMBEDDED flag.

Interaction Callback Message Data Structure

Not all message fields are currently supported.

FieldTypeDescription
content?stringThe message contents (up to 2000 characters)
tts?booleanWhether this is a TTS message
embeds?array[embed object]Embedded rich content (max 6000 characters, max 10)
allowed_mentions?allowed mention objectAllowed mentions for the message
components?array[message component object]The components to include with the message
flags?integerThe message's flags (only SUPPRESS_EMBEDS, EPHEMERAL, SUPPRESS_NOTIFICATIONS, VOICE_MESSAGE, IS_COMPONENTS_V2 can be set)
attachments? 1array[partial attachment object]Partial attachment objects with filename and description (max 10)
poll?poll create objectA poll!
Interaction Callback Autocomplete Data Structure
FieldTypeDescription
choicesarray[application command option choice object]The autocompleted choices (max 25)
Interaction Callback Modal Data Structure
FieldTypeDescription
custom_idstringDeveloper-defined identifier for the modal (1-100 characters)
titlestringThe title of the modal (max 45 characters)
componentsarray[component object]Components of the type action row, text display, or label (1-5)
Interaction Callback IFrame Modal Data Structure
FieldTypeDescription
iframe_pathstringThe relative URL to the iFrame modal (max 2048 characters)
titlestringThe title of the modal (max 45 characters)
modal_sizeintegerThe size of the modal
custom_idstringThe Developer-defined identifier for the iFrame modal (1-100 characters)
IFrame Modal Size
ValueNameDescription
1SMALLSmall modal
2NORMALNormal modal
3BIGBig modal
Interaction Callback Social Layer SKU Purchase Eligibility Data
FieldTypeDescription
eligiblebooleanWhether 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 object:

@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.

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)

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:

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. If the signature fails validation, respond with a 401 error code. Here's a couple code examples:

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");
}
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

POST/interactions/{interaction.id}/{interaction.token}/callback

Create a response to an interaction from the Gateway. Accepts an interaction response 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 for details on uploading files and multipart/form-data requests.

Query String Params
FieldTypeDescription
with_response?booleanWhether to include an interaction callback result as the response (default false)
Response Body
FieldTypeDescription
interactioninteraction callback objectThe interaction associated with the interaction response
resource?interaction callback resource objectThe resource that was created by the interaction response
Interaction Callback Structure
FieldTypeDescription
idsnowflakeThe ID of the interaction
typeintegerThe type of interaction
response_message_id?snowflakeThe ID of the message that was created by the interaction
response_message_loading?booleanWhether the response message has the LOADING flag
response_message_ephemeral?booleanWhether the response message has the EPHEMERAL flag
activity_instance_id?stringThe ID of the launched activity instance
channel_id?snowflakeThe ID of the channel the interaction was created in
guild_id?snowflakeThe ID of the guild the interaction was created in
Interaction Callback Resource Structure
FieldTypeDescription
typeintegerThe type of interaction callback
activity_instance? 1interaction callback activity instance resource objectThe activity launched by the interaction callback
message? 2message objectThe message created by the interaction callback

1 Only applicable if type is LAUNCH_ACTIVITY.

2 Only applicable if type is CHANNEL_MESSAGE_WITH_SOURCE, or UPDATE_MESSAGE.

Interaction Callback Activity Instance Resource Structure
FieldTypeDescription
idstringThe ID of the launched activity instance

Get Original Interaction Response

GET/webhooks/{application.id}/{interaction.token}/messages/@original

Returns the initial interaction response. Functions the same as Get Webhook Message.

Modify Original Interaction Response

PATCH/webhooks/{application.id}/{interaction.token}/messages/@original

Edits the initial interaction response. Functions the same as Edit Webhook Message.

Delete Original Interaction Response

DELETE/webhooks/{application.id}/{interaction.token}/messages/@original

Deletes the initial interaction response. Returns a 204 empty response on success.

Create Followup Message

POST/webhooks/{application.id}/{interaction.token}

Create a followup message for an interaction. Functions the same as 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

GET/webhooks/{application.id}/{interaction.token}/messages/{message.id}

Returns a followup message for an interaction. Functions the same as Get Webhook Message. Does not support ephemeral followups.

Modify Followup Message

PATCH/webhooks/{application.id}/{interaction.token}/messages/{message.id}

Edits a followup message for an interaction. Functions the same as Edit Webhook Message. Does not support ephemeral followups.

Delete Followup Message

DELETE/webhooks/{application.id}/{interaction.token}/messages/{message.id}

Deletes a followup message for an interaction. Functions the same as Delete Webhook Message. Does not support ephemeral followups.

Create Interaction

POST/interactions

Creates an interaction. Returns a 204 empty response on success. Fires Interaction Create and Interaction Success or 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.

JSON/Form Params
FieldTypeDescription
type 1integerThe type of interaction to create
application_idsnowflakeThe ID of the application
guild_id?snowflakeThe ID of the guild
channel_idsnowflakeThe ID of the channel
message_id? 2snowflakeThe ID of the message that the component is attached to
message_flags? 2integerThe message's flags
session_id?stringThe ID of the Gateway session to send accompanying interaction events to
dataobjectThe interaction data, depending on the interaction type
files[n]? 3file contentsContents of the file being sent (max 25)
nonce?stringThe interaction's nonce, used for interaction deduplication
analytics_location?stringWhere the interaction is being created
section_name?stringThe name of the section the embedded activity is being started from
source?stringThe source of interaction creation

1 To create SOCIAL_LAYER_SKU_PURCHASE_ELIGIBILITY interactions, the Check Social Layer SKU Purchase Eligibility endpoint is used instead.

2 Only applicable for MESSAGE_COMPONENT interactions.

3 See Uploading Files for details.

Sendable Application Command Data Structure
FieldTypeDescription
idsnowflakeThe ID of the application command
type?integerThe type of the application command
namestringThe name of the application command
versionsnowflakeThe autoincrementing version identifier updated during substantial command record changes
application_command?application command objectThe application command being executed
options? 1array[application command data option object]The options with their values
target_id? 2snowflakeThe ID of the user or message targeted by a context menu command
attachments? 3array[partial attachment object]The attachments to upload (max 25)

1 Only applicable when the application command type is CHAT_INPUT.

2 Only applicable when the application command type is USER or MESSAGE.

3 See Uploading Files for details.

Sendable Message Component Data Structure
FieldTypeDescription
component_type? 1integerThe type of the component
type? 1integerThe type of the component
custom_idstringThe developer-defined identifier for the component
values? 2array[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
FieldTypeDescription
idsnowflakeThe ID of the interaction that triggered the modal
custom_idstringThe developer-defined identifier of the modal
componentsarray[modal submit component data object]The components in the modal
attachments? 1array[partial attachment object]The attachments to upload (max 25)

1 See Uploading Files for details.

Interaction Creation Location
ValueDescription
discoveryInteraction was executed from a message content suggestion
suggestionInteraction was suggested as a replacement of text commands
mentionInteraction was executed from a mention
pasteInteraction was pasted in chat
recallInteraction was executed by attempting to edit a previous command invocation
popular_commandsInteraction was executed from an application's popular commands list
mj_chat_barInteraction was executed from a Midjourney command promotion
queryInteraction was executed from a message content query suggestion
slash_uiInteraction was executed from the chat bar
app_launcherInteraction was executed from the App Launcher
app_launcher_homeInteraction was executed from the App Launcher home
app_launcher_home_searchInteraction was executed from the App Launcher search
app_launcher_list_view_allInteraction was executed from the App Launcher list view
app_launcher_application_viewInteraction was executed from the App Launcher application view
app_launcher_application_view_frecentInteraction was executed from the App Launcher application frecents section
app_launcher_application_view_more_menuInteraction was executed from the App Launcher view more menu
app_launcher_slash_searchInteraction was executed from the App Launcher command search
app_launcher_frecents_view_allInteraction was executed from the App Launcher frecents section
image_recs_menuInteraction was executed from the "Edit Image With Apps" menu
image_recs_submenuInteraction was executed from the "Edit Image With Apps" submenu
activity_instance_embedInteraction was executed from an activity instance embed
activity_bookmark_embedInteraction was executed from an activity bookmark embed
activities_mini_shelfInteraction was executed from the activities mini shelf
vc_tile_activity_suggestionInteraction was executed from the activity suggestions in a voice channel
app_dms_entry_point_command_buttonInteraction 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.

ValueDescription
searchSearch results
recentRecent apps
installedInstalled apps
activitiesActivity Launcher
recent_appsApp Launcher > Recents
recent_commandsApp Launcher > Recents > Commands
new_to_appsNew user app coachmark
apps_in_this_serverApp Launcher > Apps in this Server
Interaction Creation Source Type
ValueDescription
NONEUnknown
TEXTThe interaction was created in a text channel
VOICEThe interaction was created in a voice channel