Interactions

An Interaction is the message that your application receives when a user uses an application command or a message component.

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 our data models.

Data Models and Types

Interaction Object

Interaction Structure
FieldTypeDescription
idsnowflakeid of the interaction
application_idsnowflakeid of the application this interaction is for
typeinteraction typethe type of interaction
data? 1interaction datathe command data payload
guild_id?snowflakethe guild it was sent from
channel_id?snowflakethe channel it was sent from
member? 2guild member objectguild member data for the invoking user, including permissions
user?partial user objectuser object for the invoking user, if invoked in a DM
tokenstringa continuation token for responding to the interaction
versionintegerread-only property, always 1
message?message objectfor components, the message they were attached to

1 This is always present on application command and message component interaction types. It is optional for future-proofing against new interaction types.

2 member is sent when the interaction is invoked in a guild, and user is sent when invoked in a DM.

Interaction Type
NameValue
PING1
APPLICATION_COMMAND2
MESSAGE_COMPONENT3
Interaction Data Structure
FieldTypeDescriptionInteraction Type
idsnowflakethe ID of the invoked commandApplication Command
namestringthe name of the invoked commandApplication Command
typeintegerthe type of the invoked commandApplication Command
resolved?resolved dataconverted users + roles + channelsApplication Command
options?array of application command interaction data optionthe params + values from the userApplication Command
custom_id?stringthe custom_id of the componentComponent
component_type?integerthe type of the componentComponent
values?array of select option valuesthe values the user selectedComponent (Select)
target_id?snowflakeid the of user or message targetted by a user or message commandUser Command, Message Command
Resolved Data Structure
FieldTypeDescription
users?Map of Snowflakes to partial user objectsthe ids and User objects
members? 1Map of Snowflakes to partial member objectsthe ids and partial Member objects
roles?Map of Snowflakes to role objectsthe ids and Role objects
channels? 2Map of Snowflakes to partial channel objectsthe ids and partial Channel objects
messages?Map of Snowflakes to partial messages objectsthe ids and partial Message objects

1 Partial Member objects are missing user, deaf and mute fields.

2 Partial Channel objects only have id, name, type and permissions fields. Threads will also have thread_metadata and parent_id fields.

Message Interaction Object

This is sent on the message object when the message is a response to an Interaction without an existing message.

Message Interaction Structure
NameTypeDescription
idsnowflakeid of the interaction
typeinteraction typethe type of interaction
namestringthe name of the application command
userpartial user objectthe user who invoked the interaction

Interactions and Bot Users

We're all used to the way that Discord bots have worked for a long time. You make an application in the Dev Portal, 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 our 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 our API (like fetching a guild, or a channel, or updating permissions on a 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 INTERACTION_CREATE Gateway Event may be handled by connected clients, while the webhook method detailed below does not require a connected client.

In your application in the Developer Portal, there is a field on the main page called "Interactions Endpoint URL". If you want to receive Interactions via outgoing webhook, you can set your URL in this field. 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, we will not validate your URL and it will fail to save.

When you attempt to save a URL, we 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 my_command():
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 app 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:

An explanation of all the fields can be found in our data models.

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
typeinteraction callback typethe type of response
data?interaction callback dataan optional response message
Interaction Callback Type
NameValueDescription
PONG1ACK a Ping
CHANNEL_MESSAGE_WITH_SOURCE4respond to an interaction with a message
DEFERRED_CHANNEL_MESSAGE_WITH_SOURCE5ACK an interaction and edit a response later, the user sees a loading state
DEFERRED_UPDATE_MESSAGE 16for components, ACK an interaction and edit the original message later; the user does not see a loading state
UPDATE_MESSAGE 17for components, edit the message the component was attached to

1 Only valid for component-based interactions

Interaction Callback Data Structure

Not all message fields are currently supported.

NameTypeDescription
tts?booleanis the response TTS
content?stringmessage content
embeds?array of embedssupports up to 10 embeds
allowed_mentions?allowed mentionsallowed mentions object
flags?integerinteraction callback data flags
components?array of componentsmessage components
attachments? 1array of partial attachment objectsattachment objects with filename and description

1 See Uploading Files for details.

Interaction Callback Data Flags
NameValueDescription
EPHEMERAL1 << 6only the user receiving the message can see it

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 my_command():
if request.json["type"] == 1:
return jsonify({
"type": 1
})
else:
return jsonify({
"type": 4,
"data": {
"tts": False,
"content": "Congrats on sending your command!",
"embeds": [],
"allowed_mentions": { "parse": [] }
}
})

If you are receiving Interactions over the gateway, you will also need to respond via HTTP. Responses to Interactions are not sent as commands over the gateway.

To respond to a gateway Interaction, make a POST request like this. interaction_id is the unique id of that individual Interaction from the received payload. interaction_token is the unique token for that interaction from the received payload. This endpoint is only valid for Interactions received over the gateway. Otherwise, respond to the POST request to issue an initial response.

url = "https://discord.com/api/v8/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 bot 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 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, we will not allow you to save your interactions URL in the Dev Portal. We will also do automated, routine security checks against your endpoint, including purposefully sending you invalid signatures. If you fail the validation, we will remove your interactions URL in the future and alert you via email and System DM.

Endpoints

Create Interaction Response

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

Create a response to an Interaction from the gateway. Takes an interaction response. 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.

Get Original Interaction Response

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

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

Edit 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 204 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 be set to 64 in the body to send an ephemeral message. The thread_id query parameter is not required (and is furthermore 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.

Edit 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. Returns 204 on success. Does not support ephemeral followups.