> ## Documentation Index
> Fetch the complete documentation index at: https://docs.razebot.tech/llms.txt
> Use this file to discover all available pages before exploring further.

# Custom commands

> Define your own server-specific commands with arguments, variables, logic, and actions.

# Custom commands

> Define your own server-specific commands with arguments, variables, logic, and actions.

Custom commands let you define your own prefix commands for a single server. They can take arguments, resolve variables, branch on conditions, render embeds and components, run moderation/economy/database actions, and be locked down per user, role, channel, or Discord permission.

<Info>
  Every `;cc` subcommand requires the **Manage Server** permission.
</Info>

## Notation used in these docs

| Notation  | Meaning                          |
| :-------- | :------------------------------- |
| `(value)` | You must supply this.            |
| `[value]` | Optional — you can leave it out. |
| `a\|b`    | Pick one of the listed values.   |

<Note>
  Argument declarations use the same notation literally: `;cc set greet (member) [message...] -- ...` really is typed with those brackets. Angle brackets — `<member>` — are still accepted as a legacy alias. See [Syntax and separators](/server-config/custom-commands/syntax-separators).
</Note>

***

## How invocation works

Custom commands run off your server prefix (default `;`). They are **not** registered as slash commands.

When someone types a name that doesn't match any built-in command, raze looks it up in your server's custom commands and runs it if it exists and is enabled.

***

## Execution order

Knowing the order explains almost every "why didn't that work" question:

<Steps>
  <Step title="Directives and cooldown">
    Output directives are read from the saved script and stripped. If `{cooldown:}` is set and the member is still on it, nothing else happens. See [Output controls](/server-config/custom-commands/output-controls).
  </Step>

  <Step title="Restrictions">
    Deny list, then allow list, then required permissions. See [Restrictions](/server-config/custom-commands/restrictions).
  </Step>

  <Step title="Arguments">
    The text after the command name is split into your declared arguments. A missing required argument stops execution here.
  </Step>

  <Step title="Action permission check">
    If the script contains actions, the invoker must hold the mapped permission — unless a user/role allow entry covers them.
  </Step>

  <Step title="Fallbacks">
    `{key|fallback}` is resolved against argument and context values.
  </Step>

  <Step title="Variables">
    Argument, command, user, server, date, economy, and moderator variables are substituted. Random tags resolve here too.
  </Step>

  <Step title="Text transforms and conditionals">
    `{upper(...)}` and friends run, then `{if}` / `{elseif}` / `{else}` / `{endif}` blocks are collapsed.
  </Step>

  <Step title="Database tags">
    Inline `{db.*}` tags read and write [stored data](/server-config/custom-commands/stored-data).
  </Step>

  <Step title="Actions">
    `{mod:...}`, `{econ:...}`, and `{customdb:...}` lines execute and are stripped from the output.
  </Step>

  <Step title="Render">
    What's left is parsed into content, embeds, components, or pages.
  </Step>

  <Step title="Deliver">
    The message goes to the invocation channel, or wherever `{respond:}` / `{dm}` point it. Reactions, attachments, threads, and role tags are applied, the trigger is deleted if `{delete}` asked for it, and the cooldown is stamped.
  </Step>
</Steps>

<Tip>
  Because variables are substituted **before** conditionals and actions run, `{if:{sides}>0}` and `{mod:warn {target}}` both work — the inner value is already filled in by the time the outer tag is evaluated.
</Tip>

***

## Limits by tier

The number of custom commands one server can save depends on the donator tier:

| Donator tier | Max custom commands |
| :----------- | :------------------ |
| **Free**     | 10                  |
| **Premium**  | 60                  |
| **Apex**     | Unlimited           |

The limit is only checked when you create a **new** command — updating an existing one is always allowed.

Check or raise your tier with `;upgrade` or `;premium`.

<Note>
  **Premium beta:** custom commands can be temporarily gated to a minimum tier while the feature is in beta. If it is gated, running a custom command replies with the required tier and the reason instead of executing. Creating and managing commands is unaffected.
</Note>

***

## Where to go next

<CardGroup cols={2}>
  <Card title="Create and preview" icon="eye" href="/server-config/custom-commands/create-preview">
    Build your first command and dry-run it safely.
  </Card>

  <Card title="Syntax and separators" icon="code" href="/server-config/custom-commands/syntax-separators">
    Naming rules, separators, and argument declarations.
  </Card>

  <Card title="Arguments and variables" icon="brackets-curly" href="/server-config/custom-commands/arguments-variables">
    Inject user input, metadata, and global placeholders.
  </Card>

  <Card title="Recipes" icon="book-open" href="/server-config/custom-commands/recipes">
    Copy-pasteable examples that already work.
  </Card>
</CardGroup>
