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 Object

Application Command Structure
FieldTypeDescriptionValid Types
idsnowflakeunique id of the commandall
type?one of application command typethe type of command, defaults 1 if not setall
application_idsnowflakeunique id of the parent applicationall
guild_id?snowflakeguild id of the command, if not globalall
namestring1-32 character nameall
descriptionstring1-100 character description for CHAT_INPUT commands, empty string for USER and MESSAGE commandsall
options?array of application command optionthe parameters for the command, max 25CHAT_INPUT
default_permission?boolean (default true)whether the command is enabled by default when the app is added to a guildall
Application Command Types
NameTypeDescription
CHAT_INPUT1Slash commands; a text-based command that shows up when a user types /
USER2A UI-based command that shows up when you right click or tap on a user
MESSAGE3A UI-based command that shows up when you right click or tap on a message
Application Command Option Structure
FieldTypeDescription
typeone of application command option typethe type of option
namestring1-32 lowercase character name matching ^[\w-]{1,32}$
descriptionstring1-100 character description
required?booleanif the parameter is required or optional--default false
choices?array of application command option choicechoices for STRING, INTEGER, and NUMBER types for the user to pick from, max 25
options?array of application command optionif the option is a subcommand or subcommand group type, this nested options will be the parameters
Application Command Option Type
NameValueNote
SUB_COMMAND1
SUB_COMMAND_GROUP2
STRING3
INTEGER4Any integer between -253 and 253
BOOLEAN5
USER6
CHANNEL7Includes all channel types + categories
ROLE8
MENTIONABLE9Includes users and roles
NUMBER10Any double between -253 and 253
Application Command Option Choice Structure

If you specify choices for an option, they are the only valid values for a user to pick

FieldTypeDescription
namestring1-100 character choice name
valuestring, integer, or doublevalue of the choice, up to 100 characters if string
Application Command Interaction Data Option Structure

All options have names, and an option can either be a parameter and input value--in which case value will be set--or it can denote a subcommand or group--in which case it will contain a top-level key and another array of options.

value and options are mutually exclusive.

FieldTypeDescription
namestringthe name of the parameter
typeintegervalue of application command option type
value?application command option typethe value of the pair
options?array of application command interaction data optionpresent if this option is a group or subcommand

Authorizing Your Application

Application commands do not depend on a bot user in the guild; they use the interactions model. To create commands in a guild, your app must be authorized with the applications.commands scope.

When requesting this scope, we "shortcut" 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
  • 5 global USER commands
  • 5 global MESSAGE commands

As well as the same amount of guild-specific commands per guild.

Making a Global Command

Global commands are available on all your app's guilds. Global commands are cached for 1 hour. That means that new global commands will fan out slowly across all guilds, and will be guaranteed to be updated in an hour.

Global commands have inherent read-repair functionality. That means that if you make an update to a global command, and a 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:

import requests
url = "https://discord.com/api/v8/applications/<my_application_id>/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 <my_bot_token>"
}
# or a client credentials token for your app with the applications.commands.update scope
headers = {
"Authorization": "Bearer <my_credentials_token>"
}
r = requests.post(url, headers=headers, json=json)

Making a Guild Command

Guild commands are available only within the guild specified on creation. Guild commands update instantly. We recommend you use guild commands for quick testing, and global commands when they're ready for public use.

To make a guild command, make a similar HTTP POST call, but scope it to a specific guild_id:

import requests
url = "https://discord.com/api/v8/applications/<my_application_id>/guilds/<guild_id>/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 <my_bot_token>"
}
# or a client credentials token for your app with the applications.commands.update scope
headers = {
"Authorization": "Bearer <my_credentials_token>"
}
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/<my_application_id>/commands/<command_id> for global commands, or
  • applications/<my_application_id>/guilds/<guild_id>/commands/<command_id> for guild commands

Because commands have unique names within a type and scope, we treat 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.

Permissions

Application Command Permissions Object

Guild Application Command Permissions Structure

Returned when fetching the permissions for a command in a guild.

FieldTypeDescription
idsnowflakethe id of the command
application_idsnowflakethe id of the application the command belongs to
guild_idsnowflakethe id of the guild
permissionsarray of application command permissionsthe permissions for the command in the guild
Application Command Permissions Structure

Application command permissions allow you to enable or disable commands for specific users or roles within a guild.

FieldTypeDescription
idsnowflakethe id of the role or user
typeapplication command permission typerole or user
permissionbooleantrue to allow, false, to disallow
Application Command Permission Type
NameValue
ROLE1
USER2

Need to keep some of your commands safe from prying eyes, or only available to the right people? Commands support permission overwrites! For both guild and global commands of all types, you can enable or disable a specific user or role in a guild from using a command.

You can also set a default_permission on your commands if you want them to be disabled by default when your app is added to a new guild. Setting default_permission to false will disallow anyone in a guild from using the command—even Administrators and guild owners—unless a specific overwrite is configured. It will also disable the command from being usable in DMs.

For example, this command will not be usable by anyone in any guilds by default:

{
"name": "permissions_test",
"description": "A test of default permissions",
"type": 1,
"default_permission": false
}

To enable it just for a moderator role:

MODERATOR_ROLE_ID = "<moderator_role_id>"
url = "https://discord.com/api/v8/applications/<my_application_id>/guilds/<my_guild_id>/commands/<my_command_id>/permissions"
json = {
"permissions": [
{
"id": MODERATOR_ROLE_ID,
"type": 1,
"permission": True
}
]
}
headers = {
"Authorization": "Bot <my_bot_token>"
}
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.

Example Slash Command
{
"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
}
]
}

When someone uses a slash command, your application will receive an interaction:

Example Slash Command Interaction
{
"type": 2,
"token": "A_UNIQUE_TOKEN",
"member": {
"user": {
"id": "53908232506183680",
"username": "mason",
"global_name": "Mason",
"avatar": "a_d5efa99b3eeaa7dd43acca82f5692432",
"discriminator": "0",
"public_flags": 131141,
"avatar_decoration_data": null,
"primary_guild": null
},
"roles": ["539082325061836999"],
"premium_since": null,
"permissions": "2147483647",
"pending": false,
"nick": null,
"mute": false,
"joined_at": "2017-03-13T19:19:14.040000+00:00",
"deaf": false
},
"id": "786008729715212338",
"guild_id": "290926798626357999",
"data": {
"options": [
{
"name": "cardname",
"value": "The Gitrog Monster"
}
],
"name": "cardsearch",
"id": "771825006014889984"
},
"channel_id": "645027906669510667"
}

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 we think about them.

We support 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:

{
"name": "permissions",
"description": "Get or edit permissions for a user or a role",
"options": []
}

A command with no arguments. It says /permissions

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.

{
"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:

{
"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
}
]
}
]
}

A command with grouped subcommands. It says /permissions user get

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:

{
"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
"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 a 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. Here's what it looks like all put together.

A command with grouped subcommands and parameters. It says /permissions user get with arguments for a user and a channel.

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.

Example User Command
{
"name": "High Five",
"type": 2
}

An example user command. The context menu has an Apps section open to a High Five command

When someone uses a user command, your application will receive an interaction:

Example User Command Interaction
{
"application_id": "775799577604522054",
"channel_id": "772908445358620702",
"data": {
"id": "866818195033292850",
"name": "context-menu-user-2",
"resolved": {
"members": {
"809850198683418695": {
"avatar": null,
"joined_at": "2021-02-12T18:25:07.972000+00:00",
"nick": null,
"pending": false,
"permissions": "246997699136",
"premium_since": null,
"roles": []
}
},
"users": {
"809850198683418695": {
"id": "809850198683418695",
"username": "voltydemo",
"global_name": "VoltyDemo",
"avatar": "afc428077119df8aabbbd84b0dc90c74",
"discriminator": "0",
"public_flags": 0,
"bot": true,
"avatar_decoration_data": null,
"primary_guild": null
}
}
},
"target_id": "809850198683418695",
"type": 2
},
"guild_id": "772904309264089089",
"id": "867794291820986368",
"member": {
"avatar": null,
"deaf": false,
"joined_at": "2020-11-02T20:46:57.364000+00:00",
"mute": false,
"nick": null,
"pending": false,
"permissions": "274877906943",
"premium_since": null,
"roles": ["785609923542777878"],
"user": {
"id": "167348773423415296",
"username": "ian",
"global_name": "Ian",
"avatar": "a_f03401914fb4f3caa9037578ab980920",
"discriminator": "0",
"public_flags": 131141,
"avatar_decoration_data": null,
"primary_guild": null
}
},
"token": "UNIQUE_TOKEN",
"type": 2,
"version": 1
}

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.

Example Message Command
{
"name": "Bookmark",
"type": 3
}

An example message command. The context menu has an Apps section open to a Bookmark command

When someone uses a message command, your application will receive an interaction:

Example Message Command Interaction
{
"application_id": "775799577604522054",
"channel_id": "772908445358620702",
"data": {
"id": "866818195033292851",
"name": "context-menu-message-2",
"resolved": {
"messages": {
"867793854505943041": {
"attachments": [],
"author": {
"id": "167348773423415296",
"username": "ian",
"global_name": "Ian",
"avatar": "a_f03401914fb4f3caa9037578ab980920",
"discriminator": "0",
"public_flags": 131141,
"avatar_decoration_data": null,
"primary_guild": null
},
"channel_id": "772908445358620702",
"components": [],
"content": "some message",
"edited_timestamp": null,
"embeds": [],
"flags": 0,
"id": "867793854505943041",
"mention_everyone": false,
"mention_roles": [],
"mentions": [],
"pinned": false,
"timestamp": "2021-07-22T15:42:57.744000+00:00",
"tts": false,
"type": 0
}
}
},
"target_id": "867793854505943041",
"type": 3
},
"guild_id": "772904309264089089",
"id": "867793873336926249",
"member": {
"avatar": null,
"deaf": false,
"joined_at": "2020-11-02T20:46:57.364000+00:00",
"mute": false,
"nick": null,
"pending": false,
"permissions": "274877906943",
"premium_since": null,
"roles": ["785609923542777878"],
"user": {
"id": "167348773423415296",
"username": "ian",
"global_name": "Ian",
"avatar": "a_f03401914fb4f3caa9037578ab980920",
"discriminator": "0",
"public_flags": 131141,
"avatar_decoration_data": null,
"primary_guild": null
}
},
"token": "UNIQUE_TOKEN",
"type": 2,
"version": 1
}

Endpoints

Get Global Application Commands

GET/applications/{application.id}/commands

Get Global Application Commands

GET/applications/{application.id}/commands

Fetch all of the global commands for your application. Returns an array of application command objects.

Create Global Application Command

POST/applications/{application.id}/commands

Create Global Application Command

POST/applications/{application.id}/commands

Create a new global command. New global commands will be available in all guilds after 1 hour. Returns 201 and an application command object.

JSON Params
FieldTypeDescription
namestring1-32 lowercase character name matching ^[\w-]{1,32}$
descriptionstring1-100 character description
options?array of application command optionthe parameters for the command
default_permission?boolean (default true)whether the command is enabled by default when the app is added to a guild
type?one of application command typethe type of command, defaults 1 if not set

Get Global Application Command

GET/applications/{application.id}/commands/{command.id}

Fetch a global command for your application. Returns an application command object.

Edit Global Application Command

PATCH/applications/{application.id}/commands/{command.id}

Edit a global command. Updates will be available in all guilds after 1 hour. Returns 200 and an application command object.

JSON Params
FieldTypeDescription
name?string1-32 lowercase character name matching ^[\w-]{1,32}$
description?string1-100 character description
options?array of application command optionthe parameters for the command
default_permission?boolean (default true)whether the command is enabled by default when the app is added to a guild

Delete Global Application Command

DELETE/applications/{application.id}/commands/{command.id}

Deletes a global command. Returns 204.

Bulk Overwrite Global Application Commands

PUT/applications/{application.id}/commands

Takes a list of application commands, overwriting existing commands that are registered globally for this application. Updates will be available in all guilds after 1 hour. Returns 200 and a list of application command objects. Commands that do not already exist will count toward daily application command create limits.

Get Guild Application Commands

GET/applications/{application.id}/guilds/{guild.id}/commands

Fetch all of the guild commands for your application for a specific guild. Returns an array of application command objects.

Create Guild Application Command

POST/applications/{application.id}/guilds/{guild.id}/commands

Create a new guild command. New guild commands will be available in the guild immediately. Returns 201 and an application command object. If the command did not already exist, it will count toward daily application command create limits.

JSON Params
FieldTypeDescription
namestring1-32 lowercase character name matching ^[\w-]{1,32}$
descriptionstring1-100 character description
options?array of application command optionthe parameters for the command
default_permission?boolean (default true)whether the command is enabled by default when the app is added to a guild
type?one of application command typethe type of command, defaults 1 if not set

Get Guild Application Command

GET/applications/{application.id}/guilds/{guild.id}/commands/{command.id}

Fetch a guild command for your application. Returns an application command object.

Edit Guild Application Command

PATCH/applications/{application.id}/guilds/{guild.id}/commands/{command.id}

Edit a guild command. Updates for guild commands will be available immediately. Returns 200 and an application command object.

JSON Params
FieldTypeDescription
name?string1-32 lowercase character name matching ^[\w-]{1,32}$
description?string1-100 character description
options?array of application command optionthe parameters for the command
default_permission?boolean (default true)whether the command is enabled by default when the app is added to a guild

Delete Guild Application Command

DELETE/applications/{application.id}/guilds/{guild.id}/commands/{command.id}

Delete a guild command. Returns 204 on success.

Bulk Overwrite Guild Application Commands

PUT/applications/{application.id}/guilds/{guild.id}/commands

Takes a list of application commands, overwriting existing commands for the guild. Returns 200 and a list of application command objects.

Get Guild Application Command Permissions

GET/applications/{application.id}/guilds/{guild.id}/commands/permissions

Fetches command permissions for all commands for your application in a guild. Returns an array of guild application command permissions objects.

Get Application Command Permissions

GET/applications/{application.id}/guilds/{guild.id}/commands/{command.id}/permissions

Fetches command permissions for a specific command for your application in a guild. Returns a guild application command permissions object.

Edit Application Command Permissions

PUT/applications/{application.id}/guilds/{guild.id}/commands/{command.id}/permissions

Edits command permissions for a specific command for your application in a guild. You can only add up to 10 permission overwrites for a command. Returns a GuildApplicationCommandPermissions object.

JSON Params
FieldTypeDescription
permissionsarray of application command permissionsthe permissions for the command in the guild

Batch Edit Application Command Permissions

PUT/applications/{application.id}/guilds/{guild.id}/commands/permissions

Batch edits permissions for all commands in a guild. Takes an array of partial guild application command permissions objects including id and permissions.

You can only add up to 10 permission overwrites for a command.

Returns an array of GuildApplicationCommandPermissions objects.

Example
FIRST_COMMAND_ID = "<first_command_id>"
SECOND_COMMAND_ID = "<second_command_id>"
ADMIN_ROLE_ID = "<admin_role_id>"
url = "https://discord.com/api/v8/applications/<my_application_id>/guilds/<my_guild_id>/commands/permissions"
json = [
{
"id": FIRST_COMMAND_ID,
"permissions": [
{
"id": ADMIN_ROLE_ID,
"type": 1,
"permission": True
}
]
},
{
"id": SECOND_COMMAND_ID,
"permissions": [
{
"id": ADMIN_ROLE_ID,
"type": 1,
"permission": False
}
]
}
]
headers = {
"Authorization": "Bot <my_bot_token>"
}
r = requests.put(url, headers=headers, json=json)