Docs / Developers / Build / Slash commands
BuildSDK 0.10.1

Slash commands

These docs are public. To publish a plugin you need a YourBot account: sign in to open the Dev Portal.

Two steps: declare the command in manifest.json, then handle it with @plugin.on_slash_command. The platform syncs the command registration with Discord automatically when your version is published.

Capability shortcut: declaring any slash_commands automatically adds interaction:respond to capabilities_required — you don't have to list it yourself. The explicit declaration in the example below is harmless but redundant.

Name rules: command names must be unique within your manifest and may not use names reserved by built-in YourBot services (see the definitive list; yourbot validate checks it locally). Uploads that break these rules are rejected at publish time. If another installed plugin already uses one of your names on a server, the platform picks one deterministically and the other is skipped there — don't count on install order. Server admins can also disable individual commands of your plugin per server; disabled commands are simply not registered with Discord.

Interaction timing. The platform acknowledges each slash command for you before your handler runs (users see a "thinking…" placeholder), and your respond() fills it in — you have up to 15 minutes, not Discord's raw 3 seconds. The exception is modals: a modal must be the first response, so a command that opens one must set "defer_on_dispatch": false in its manifest entry and then call send_modal within 3 seconds.

Declaration in manifest.json

{
  "id": "my_plugin",
  "name": "My Plugin",
  "version": "1.0.0",
  "capabilities_required": ["interaction:respond"],
  "slash_commands": [
    {
      "name": "greet",
      "description": "Say hello to someone",
      "options": [
        {
          "name": "user",
          "description": "Who to greet",
          "type": 6,
          "required": true
        },
        {
          "name": "message",
          "description": "Custom greeting",
          "type": 3,
          "required": false
        },
        {
          "name": "tone",
          "description": "How formal?",
          "type": 3,
          "required": false,
          "choices": [
            {"name": "Casual", "value": "casual"},
            {"name": "Formal", "value": "formal"}
          ]
        }
      ]
    }
  ]
}

Discord option types you'll commonly use:

TypeMeaning
3String
4Integer
5Boolean
6User (resolves to a user ID)
7Channel
8Role
10Number (float)

Handler

@plugin.on_slash_command("greet")
def greet(ctx: Context, event: dict):
    options = {opt["name"]: opt["value"] for opt in event.get("options", [])}
    target_user_id = options.get("user")
    custom_msg = options.get("message", "Hey there!")

    ctx.interaction.respond(
        content=f"<@{target_user_id}> {custom_msg}",
    )

Because the platform already acknowledged the interaction, respond() here edits the "thinking…" placeholder — take the time you need (up to 15 minutes). Additional messages go through followup().

Autocomplete is not forwarded. The platform does not currently deliver Discord autocomplete interactions to plugins, so declare static choices on your options (see the tone option above) instead of autocomplete handlers.

YourBot docs Reference tables are generated from the code that is running. Ask in Discord Suggest a correction