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
| Field | Type | Description |
|---|---|---|
| version | integer | The interactions system 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 |
| token | string | The continuation token for responding to the interaction |
| data? 1 | object | The interaction data, depending on interaction type |
| guild? | interaction guild | 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 of the guild |
| channel? | channel | The channel it was sent from |
| channel_id? 1 | snowflake | The ID of the channel it was sent from |
| member? 2 | guild member object | The guild member representing the invoking user |
| user? 2 | partial user object | The invoking user |
| locale? | string | The language option of the invoking user |
| message? 4 | message 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 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 |
| context? 1 | integer | The context the interaction is triggered in |
| 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 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 object | sendable application command data object |
| 3 | MESSAGE_COMPONENT | User triggers a message component | message component data object | sendable message component data object |
| 4 | APPLICATION_COMMAND_AUTOCOMPLETE | User is requesting an application command option to be auto-completed | application command data object | sendable application command data object |
| 5 | MODAL_SUBMIT | User submits a modal | modal submit data object | sendable modal submit data object |
| 6 | SOCIAL_LAYER_SKU_PURCHASE_ELIGIBILITY | User is checking purchase eligibility for a social layer SKU | social layer SKU purchase eligibility 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 |
| locale | string | The preferred locale 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 |
| resolved? | resolved data object | The resolved entities |
| options? 1 2 | array[application command data option 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 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.
| Field | Type | Description |
|---|---|---|
| type | integer | The type of the application command option |
| 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 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, value will be the attachment ID.
2 Only applicable for APPLICATION_COMMAND_AUTOCOMPLETE interactions.
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 |
| values 1 | array[snowflake] | array[string] | The values that the user selected in a select menu |
| resolved? 1 | resolved data | 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 object] | The submitted values |
| resolved? | resolved data | 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 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 object | Inner component | LABEL |
| components | array[modal submit component data object] | Inner components | ACTION_ROW |
1 id does not need to be provided when creating an 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 object] | The resolved users |
| members? 1 | map[snowflake, partial member object] | The resolved members |
| roles? | map[snowflake, role object] | The resolved roles |
| channels? 2 | map[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:
- Via the 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 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:
- Your endpoint must be prepared to ACK a
PINGmessage - 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:
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
| Field | Type | Description |
|---|---|---|
| type | integer | The type of the interaction response |
| data? | object | The 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.
| Value | Name | Description | Data | Allowed By |
|---|---|---|---|---|
| 1 | PONG | Acknowledge a PING interaction | PING | |
| 4 | CHANNEL_MESSAGE_WITH_SOURCE | Respond to an interaction with a message | interaction callback message data 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 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 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 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 object | APPLICATION_COMMAND_AUTOCOMPLETE |
| 9 | MODAL | Respond to an interaction with a popup modal | interaction callback modal data 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 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 object | SOCIAL_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.
| Field | Type | Description |
|---|---|---|
| content? | string | The message contents (up to 2000 characters) |
| tts? | boolean | Whether this is a TTS message |
| embeds? | array[embed object] | Embedded rich content (max 6000 characters, max 10) |
| allowed_mentions? | allowed mention object | Allowed mentions for the message |
| components? | array[message component object] | The components to include with the message |
| flags? | integer | The message's flags (only SUPPRESS_EMBEDS, EPHEMERAL, SUPPRESS_NOTIFICATIONS, VOICE_MESSAGE, IS_COMPONENTS_V2 can be set) |
| attachments? 1 | array[partial attachment object] | Partial attachment objects with filename and description (max 10) |
| poll? | poll create object | A poll! |
Interaction Callback Autocomplete Data Structure
| Field | Type | Description |
|---|---|---|
| choices | array[application command option choice 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 object] | Components of the type action row, text display, or label (1-5) |
Interaction Callback IFrame Modal Data Structure
| Field | Type | Description |
|---|---|---|
| iframe_path | 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 |
| custom_id | string | The Developer-defined identifier for the iFrame modal (1-100 characters) |
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
| 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 object:
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.
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/@originalto edit your initial response to an interactionDELETE /webhooks/{application.id}/{interaction.token}/messages/@originalto delete your initial response to an interactionPOST /webhooks/{application.id}/{interaction.token}to send a new followup messagePATCH /webhooks/{application.id}/{interaction.token}/messages/{message.id}to edit a message sent with thattoken
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-Ed25519as a signatureX-Signature-Timestampas 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:
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}/callbackCreate 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
| 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 object | The interaction associated with the interaction response |
| resource? | interaction callback resource 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 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 flag |
| response_message_ephemeral? | boolean | Whether the response message has the EPHEMERAL 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 of interaction callback |
| activity_instance? 1 | interaction callback activity instance resource object | The activity launched by the interaction callback |
| message? 2 | message object | The 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
| Field | Type | Description |
|---|---|---|
| id | string | The ID of the launched activity instance |
Get Original Interaction Response
GET/webhooks/{application.id}/{interaction.token}/messages/@originalReturns the initial interaction response. Functions the same as Get Webhook Message.
Modify Original Interaction Response
PATCH/webhooks/{application.id}/{interaction.token}/messages/@originalEdits the initial interaction response. Functions the same as Edit Webhook Message.
Delete Original Interaction Response
DELETE/webhooks/{application.id}/{interaction.token}/messages/@originalDeletes 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/interactionsCreates 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
| Field | Type | Description |
|---|---|---|
| type 1 | integer | The type of interaction to create |
| 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 |
| session_id? | string | The ID of the Gateway session to send accompanying interaction events to |
| data | object | The interaction data, 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 |
| section_name? | string | The name of the section the embedded activity is being started from |
| source? | string | The 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
| Field | Type | Description |
|---|---|---|
| id | snowflake | The ID of the application command |
| type? | integer | The type of the application command |
| name | string | The name of the application command |
| version | snowflake | The autoincrementing version identifier updated during substantial command record changes |
| application_command? | application command object | The application command being executed |
| options? 1 | array[application command data option 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 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
| Field | Type | Description |
|---|---|---|
| component_type? 1 | integer | The type of the component |
| type? 1 | integer | The type of the component |
| 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 object] | The components in the modal |
| attachments? 1 | array[partial attachment object] | The attachments to upload (max 25) |
1 See 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 |
| 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 |