Skip to content
Micup API

Application commands

An application command is a slash command a bot registers so that people can run it from the message composer. Every bot can register commands; no review is required. A user runs a command through Invoke a bot command, and the bot receives it as an interaction.

The field names, type numbers, and routes match Discord’s, so a discord.js or discord.py bot registers commands without changes beyond its API base and version. Differences from Discord lists what is not the same.

A command is either global or belongs to one guild. A global command is available in every guild the bot is in and, when dm_permission is true, in a one-to-one direct message with the bot. A guild command is available in that guild alone and never in a direct message. When a guild command and a global command share a name, the guild command hides the global one in that guild.

Each scope holds one command set with a version. Every write replaces the set atomically and gives it a new version, which is returned as the ETag header of every registration route.

  • Only the application’s own bot token is accepted. Any other credential is refused with 403 ACCESS_DENIED, and a bot token for a different application with 403 MISSING_ACCESS.
  • A guild route requires the bot to be a member of that guild, and one that is not receives 403 MISSING_ACCESS.
  • The bot’s feature_bot_interactions limit key must be 1 and feature_bot_interactions_blocked must be 0. Otherwise every registration route returns 403 APPLICATION_COMMAND_FEATURE_DISABLED.
  • A request body with a declared length over 540,672 bytes is refused with 413 FILE_SIZE_TOO_LARGE before it is parsed.

A write with If-Match set to the ETag of an earlier read fails with 412 APPLICATION_COMMAND_VERSION_CONFLICT when the set has changed since. A malformed tag matches no version and fails the same way. A write with If-None-Match: * fails with 412 when the scope already has commands.

Without either header the server applies the change to the newest set. Concurrent writers to the same scope can still receive 412 when every attempt loses. discord.js and discord.py send neither header.

FieldTypeDescription
idsnowflakeThe ID of the command, kept while its name stays the same
application_idsnowflakeThe ID of the application that owns the command
versionsnowflakeChanges whenever the command itself changes
guild_id?snowflakeThe guild of a guild command, absent on a global command
typeintegerAlways 1, a chat input command
namestringCommand name
descriptionstring1 through 100 characters
optionsarray[command option object]Up to 25 options
default_member_permissions?stringThe permission bits a member needs to see and run the command, as a decimal string, or null for none
dm_permissionbooleanWhether a global command works in a direct message with the bot
contexts?array[integer]The contexts sent with the command, absent when none were sent

The request body takes type, name, description, options, default_member_permissions, and dm_permission. type defaults to 1, options to an empty array, default_member_permissions to null, and dm_permission to false. A guild command can only have dm_permission false.

name_localizations, description_localizations, default_permission, and a false nsfw are accepted and discarded, so discord.js and discord.py can register commands unchanged; the default name shows in every locale. nsfw true is refused. integration_types is accepted and discarded, because user-installed applications do not exist. Any other field is refused with 400 INVALID_FORM_BODY.

contexts works as on Discord: 0 is a guild, 1 the direct message with the bot, and 2 (private channels) has no effect. When it is sent, it is stored and returned, a global command’s dm_permission becomes whether it holds 1, and a command without 0 is neither offered nor run in guilds. Without it, a command is available in guilds and dm_permission decides direct messages.

{
"id": "1558000000000000001",
"application_id": "1557753609842589699",
"version": "1558000000000000002",
"type": 1,
"name": "yardım",
"description": "Komutları kategoriye göre gösterir",
"options": [
{
"type": 3,
"name": "kategori",
"description": "Gösterilecek kategori",
"required": false,
"autocomplete": true
}
],
"default_member_permissions": null,
"dm_permission": true
}

A command, option, subcommand, or group name has 1 through 32 Unicode code points after NFC normalisation. It may contain lowercase letters of any script, digits, -, and _, so yardım and seviye-ödül are valid. An uppercase letter or any other character is refused with 400 INVALID_FORM_BODY.

FieldTypeDescription
typeintegerOption type
namestringName, unique among its siblings
descriptionstring1 through 100 characters
required?booleanWhether the user must fill the option, default false
choices?array[option choice object]Up to 25 fixed values for a string, integer, or number option
autocomplete?booleanWhether the bot suggests values while the user types
min_value?numberSmallest value of an integer or number option
max_value?numberLargest value of an integer or number option
min_length?integerShortest value of a string option, 0 through 6000
max_length?integerLongest value of a string option, 1 through 6000
channel_types?array[integer]Up to 25 channel types a channel option offers
options?array[command option object]The children of a subcommand or group

Only the fields of an option’s own type are accepted. autocomplete is limited to string, integer, and number options, and an option cannot have both autocomplete and choices. min_value cannot exceed max_value, and min_length cannot exceed max_length. Required options come before optional ones.

A string value has at most 6000 code points. Integer and number values are bounded by the safe integer range of JSON numbers.

A command’s options are either all value options or all subcommands and groups. A group holds 1 through 25 subcommands, a subcommand holds value options, and nothing nests deeper. A subcommand has no required field.

ValueNameDescription
1SUB_COMMANDA subcommand
2SUB_COMMAND_GROUPA group of subcommands
3STRINGText
4INTEGERA whole number
5BOOLEANTrue or false
6USERA user, resolved in the interaction
7CHANNELA channel, resolved in the interaction
8ROLEA role, resolved in the interaction
10NUMBERA number with a fraction

Type 9 (mentionable) and type 11 (attachment) are not offered and are refused with 400 INVALID_FORM_BODY.

FieldTypeDescription
namestringThe label the user sees, 1 through 100 characters
valuestring | numberThe value the bot receives, a string of at most 100 characters for a string option
LimitValue
Commands in one scope100
Options on a command or subcommand25
Choices on an option25
Serialised size of one command32,768 bytes
Serialised size of one command set524,288 bytes

The sizes count the UTF-8 JSON of each command together with the fields the server adds.

GET/v1/applications/{application_id}/commandsBot

Returns the application’s global commands, with the set’s version as ETag.

FieldTypeDescription
application_idsnowflakeThe ID of the application
StatusBodyCondition
200array[application command object]The set was read
403error responseThe registration rules refuse the caller

30 requests per 10 seconds for each application ID, on the application:commands:read::application_id bucket.

Bulk overwrite global application commands

Section titled “Bulk overwrite global application commands”
PUT/v1/applications/{application_id}/commandsBot

Replaces the whole global set in one write and returns the new set. A command keeps its ID while its name stays the same, and an unchanged command keeps its version. An unchanged set is not rewritten.

FieldTypeDescription
application_idsnowflakeThe ID of the application

An array of up to 100 application command objects with unique names.

StatusBodyCondition
200array[application command object]The set was replaced
400error responseThe body is invalid
403error responseThe registration rules refuse the caller
412error responseA precondition failed with APPLICATION_COMMAND_VERSION_CONFLICT
413error responseThe body is too large and the request returns FILE_SIZE_TOO_LARGE

5 requests per 1 minute for each application ID, on the application:commands:write::application_id bucket.

POST/v1/applications/{application_id}/commandsBot

Creates one global command, or replaces the command with the same name, which keeps its ID. Returns 201 for a new command and 200 for a replaced one.

FieldTypeDescription
application_idsnowflakeThe ID of the application

One application command object.

StatusBodyCondition
200application command objectA command with the same name was replaced
201application command objectThe command was created
400error responseThe body is invalid
403error responseThe registration rules refuse the caller
412error responseA precondition failed with APPLICATION_COMMAND_VERSION_CONFLICT

Shares the application:commands:write::application_id bucket with Bulk overwrite global application commands.

DELETE/v1/applications/{application_id}/commandsBot

Empties the global set. Returns 204 with an empty body.

FieldTypeDescription
application_idsnowflakeThe ID of the application
StatusBodyCondition
204emptyThe set was emptied
403error responseThe registration rules refuse the caller
412error responseA precondition failed with APPLICATION_COMMAND_VERSION_CONFLICT

Shares the application:commands:write::application_id bucket.

GET/v1/applications/{application_id}/commands/{command_id}Bot

Returns one global command.

FieldTypeDescription
application_idsnowflakeThe ID of the application
command_idsnowflakeThe ID of the command
StatusBodyCondition
200application command objectThe command exists
403error responseThe registration rules refuse the caller
404error responseNo such command, and the request returns NOT_FOUND

Shares the application:commands:read::application_id bucket.

PATCH/v1/applications/{application_id}/commands/{command_id}Bot

Replaces the given fields of one global command. The result must be a valid command, and the ID stays.

FieldTypeDescription
application_idsnowflakeThe ID of the application
command_idsnowflakeThe ID of the command

Any subset of the application command request fields.

StatusBodyCondition
200application command objectThe command was changed
400error responseThe resulting command is invalid
403error responseThe registration rules refuse the caller
404error responseNo such command, and the request returns NOT_FOUND
412error responseA precondition failed with APPLICATION_COMMAND_VERSION_CONFLICT

Shares the application:commands:write::application_id bucket.

DELETE/v1/applications/{application_id}/commands/{command_id}Bot

Deletes one global command. Returns 204 with an empty body.

FieldTypeDescription
application_idsnowflakeThe ID of the application
command_idsnowflakeThe ID of the command
StatusBodyCondition
204emptyThe command was deleted
403error responseThe registration rules refuse the caller
404error responseNo such command, and the request returns NOT_FOUND
412error responseA precondition failed with APPLICATION_COMMAND_VERSION_CONFLICT

Shares the application:commands:write::application_id bucket.

The guild routes take the same bodies and return the same objects as the global routes, for one guild. The bot must be a member of the guild, dm_permission must be false, and each successful write sends Application Commands Update to the guild’s active sessions so their clients reload the catalog. A global write reaches no session.

Their writes are limited to 2 requests per 1 minute for each application and guild, on the application:commands:guild:write::application_id::guild_id bucket. Their reads share the application:commands:read::application_id bucket.

FieldTypeDescription
application_idsnowflakeThe ID of the application
guild_idsnowflakeThe ID of the guild
command_idsnowflakeThe ID of the command, on the single command routes
GET/v1/applications/{application_id}/guilds/{guild_id}/commandsBot

Returns the application’s commands for the guild, as List global application commands does for the global set.

PUT/v1/applications/{application_id}/guilds/{guild_id}/commandsBot

Replaces the guild’s whole set, as Bulk overwrite global application commands does.

POST/v1/applications/{application_id}/guilds/{guild_id}/commandsBot

Creates or replaces one guild command by name, as Create global application command does.

DELETE/v1/applications/{application_id}/guilds/{guild_id}/commandsBot

Empties the guild’s set. Returns 204 with an empty body.

GET/v1/applications/{application_id}/guilds/{guild_id}/commands/{command_id}Bot

Returns one guild command, or 404 NOT_FOUND.

PATCH/v1/applications/{application_id}/guilds/{guild_id}/commands/{command_id}Bot

Replaces the given fields of one guild command, as Edit global application command does.

DELETE/v1/applications/{application_id}/guilds/{guild_id}/commands/{command_id}Bot

Deletes one guild command. Returns 204 with an empty body, or 404 NOT_FOUND.

The commands a user may run in one channel, as the client’s composer lists them.

FieldTypeDescription
applicationsarray[catalog application object]The bots whose commands are on this page
application_commandsarray[application command object]At most 50 commands
next_cursor?stringThe cursor of the next page, or null on the last one

A page holds at most 50 commands and at most 131,072 bytes. Every page carries the same weak ETag, which covers the whole catalog, so a change on a later page changes it too. A first-page request with a matching If-None-Match returns 304. The tag does not change when only a bot’s name, avatar, or channel permissions change, so a client can show those for up to 10 minutes; a command run from an outdated list returns 409 APPLICATION_COMMAND_STALE.

FieldTypeDescription
idsnowflakeThe ID of the application
namestringThe application name
botpartial user objectThe bot user
GET/v1/guilds/{guild_id}/application-commands

Returns, page by page, the commands of the guild’s bots that the caller may run in the channel. A command whose default_member_permissions the caller does not hold is left out.

  • This is a user-only operation, and a bot credential is refused with 403 ACCESS_DENIED.
  • An unknown channel, one the caller cannot view, or one in another guild returns 404 UNKNOWN_CHANNEL.
  • An account whose feature_app_commands limit key is 0 receives an empty page.
FieldTypeDescription
guild_idsnowflakeThe ID of the guild
FieldTypeDescription
channel_idsnowflakeThe channel the commands would run in
cursor?stringThe next_cursor of the previous page
StatusBodyCondition
200command catalog objectThe page was built
304emptyThe first page matches If-None-Match
403error responseCaller is a bot and the request returns ACCESS_DENIED
404error responseThe channel cannot be used and the request returns UNKNOWN_CHANNEL

30 requests per 1 minute for each authenticated user, on the application:commands:catalog bucket.

GET/v1/channels/{channel_id}/application-commands

In a one-to-one direct message with a bot, returns that bot’s global commands with dm_permission true and no default_member_permissions. Any other private channel returns an empty page, and a guild channel returns 404 UNKNOWN_CHANNEL.

  • This is a user-only operation, and a bot credential is refused with 403 ACCESS_DENIED.
FieldTypeDescription
channel_idsnowflakeThe ID of the direct message channel
FieldTypeDescription
cursor?stringThe next_cursor of the previous page
StatusBodyCondition
200command catalog objectThe page was built
304emptyThe first page matches If-None-Match
403error responseCaller is a bot and the request returns ACCESS_DENIED
404error responseThe channel is a guild channel and the request returns UNKNOWN_CHANNEL

Shares the application:commands:catalog bucket with List guild command catalog.