# Slash commands

> Register slash commands, receive them, and answer within three seconds.

Slash commands let people use your app by typing `/` at the start of the message box. They need the `commands` scope on the install, which new apps ask for by default.

## Registering commands

Commands use the same JSON shape as Discord's, so command builders from discord.js and discord.py produce valid input. Keys Lamma doesn't use, such as localizations, are ignored.

`PUT /v1/applications/@me/commands`

Replaces all of the app's global commands. A command keeps its id as long as its name stays the same. Global commands show up in every server at once.

`POST /v1/applications/@me/commands`

Creates one command, or updates the one with the same name. Answers `201` when created and `200` when updated.

`GET /v1/applications/@me/commands`

Lists the global commands.

`GET /v1/applications/@me/commands/{command_id}`

One command. `PATCH` changes it and `DELETE` removes it.

`PUT /v1/applications/@me/guilds/{guild_id}/commands`

The same set of routes exists under `/guilds/{guild_id}/` for one server the app is installed in. A server command replaces a global command with the same name in that server.

`@me` can also be the application's own id.

```json
{
  "name": "roll",
  "description": "Roll dice",
  "options": [
    { "type": 4, "name": "sides", "description": "How many sides", "required": true, "min_value": 2, "max_value": 100 },
    { "type": 3, "name": "label", "description": "What for", "choices": [{ "name": "Luck", "value": "luck" }] }
  ]
}
```

### Option types

| Type | Name | Extra fields |
| --- | --- | --- |
| `3` | String | `min_length`, `max_length`, `choices` |
| `4` | Integer | `min_value`, `max_value`, `choices` |
| `5` | Boolean | |
| `6` | User | |
| `7` | Channel | |
| `8` | Role | |
| `10` | Number | `min_value`, `max_value`, `choices` |

Required options come first. Subcommands, autocomplete, attachment and mentionable options aren't supported yet.

### Limits

- 100 commands globally, and 100 per server.
- 25 options per command and 25 choices per option.
- Names are 1 to 32 lowercase letters, digits, `-` or `_`. Descriptions are 1 to 100 characters.

> [!WARNING]
> `default_member_permissions` isn't enforced yet. Anyone who can post in the channel can use every command, so check the person's roles in your command code before doing anything that needs permission.

## Who sees a command

People see an app's commands in a channel when the app is installed in that server with `commands`, its bot can see and post in the channel, and they can post there too. Someone who is timed out can't use commands.

## Receiving a command

Lamma checks the options first: types, required fields, choices, ranges, and that each user, role or channel belongs to this server. Only then does it send `INTERACTION_CREATE` to the app's gateway connection, whatever intents it asked for. If the app isn't connected, the person is told at once.

```json
{
  "id": "…", "application_id": "…", "type": 2, "guild_id": "…", "channel_id": "…",
  "user": { "id": "…", "username": "noura", "name": "Noura", "avatar_id": null, "bot": false },
  "member": { "nickname": null, "roles": ["…"], "permissions": ["view_channels", "send_messages"] },
  "data": {
    "id": "…", "name": "roll", "type": 1,
    "options": [{ "name": "sides", "type": 4, "value": 20 }],
    "resolved": { "users": {}, "members": {}, "roles": {}, "channels": {} }
  },
  "app_permissions": ["view_channels", "send_messages"],
  "created_at": 1759312800000
}
```

`member.permissions` is what the person who used the command may do in this channel, with roles and channel overrides, and `app_permissions` is the same for the bot. Check `member.permissions` in commands only some people should use. The SDKs give both as Discord's permission bitfields.

## Answering

Answer every interaction within **3 seconds**, either with the answer or with a "thinking" state you fill in later.

`POST /v1/interactions/{interaction_id}/callback`

Once per interaction. Type `4` answers; type `5` shows that the app is thinking.

```json
{ "type": 4, "data": { "content": "You rolled 17", "flags": 64 } }
```

`PATCH /v1/interactions/{interaction_id}/messages/@original`

For 15 minutes: posts the answer after a type `5`, or edits it.

`POST /v1/interactions/{interaction_id}/followups`

For 15 minutes: sends another message.

- These calls use the bot token like every other `/v1` call. There is no separate interaction token.
- The answer is a message from the bot, under its own permissions, with `interaction: { id, name, user_id }`, so people see who used which command above it. Slowmode doesn't hold it back.
- `flags: 64` makes the answer **ephemeral**: only the person who used the command sees it, and it is never stored. It disappears when they dismiss it or reload.
- No answer within 3 seconds tells the person the app didn't respond. A late callback answers `400 interaction_already_handled`.
- Each call is checked again when it is made. If the app was removed from the server or lost sight of the channel, the call answers `404`.
