Import your commands from Discord
Discord knows your command set exactly and hands it to you as JSON on request. Fetch it with one of the lines below and paste it into your dashboard. That takes a minute instead of a quarter hour of typing.
What you need
- Your bot's application ID, in the Developer Portal under “General Information”, the same number as in your invite link.
- The bot token of that same application, in the Developer Portal under “Bot” → “Reset Token” if you no longer have it.
- Both as environment variables, so the token stays out of your shell history: APPLICATION_ID and DISCORD_TOKEN.
In the terminal
The result lands in commands.json or straight in your clipboard. With jq the ids we ignore anyway fall away: what is left is shorter and says nothing about your application. The import reads both forms the same.
curl -sS \
-H "Authorization: Bot $DISCORD_TOKEN" \
"https://discord.com/api/v10/applications/$APPLICATION_ID/commands" \
-o commands.json
# Shorter paste: jq drops the ids we ignore anyway,
# pbcopy (macOS) puts the result straight in your clipboard.
curl -sS -H "Authorization: Bot $DISCORD_TOKEN" \
"https://discord.com/api/v10/applications/$APPLICATION_ID/commands" \
| jq 'map(del(.id, .application_id, .version))' \
| pbcopyIn your language
Every example does the same thing: one GET, the token in the header, print the JSON.
// Node 18 or newer. fetch is built in.
const response = await fetch(
`https://discord.com/api/v10/applications/${process.env.APPLICATION_ID}/commands`,
{ headers: { Authorization: `Bot ${process.env.DISCORD_TOKEN}` } },
);
if (!response.ok) {
throw new Error(`Discord answered with ${response.status}`);
}
console.log(JSON.stringify(await response.json(), null, 2));More languages
using System.Net.Http.Headers;
var applicationId = Environment.GetEnvironmentVariable("APPLICATION_ID");
var token = Environment.GetEnvironmentVariable("DISCORD_TOKEN");
using var client = new HttpClient();
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bot", token);
var json = await client.GetStringAsync(
$"https://discord.com/api/v10/applications/{applicationId}/commands");
Console.WriteLine(json);Commands that live in one server only
If you register per guild instead of globally, the address above returns an empty list. Use this one then, with the ID of the server your commands are registered in. Both at once works too: import one, then add the second list by hand.
curl -sS \
-H "Authorization: Bot $DISCORD_TOKEN" \
"https://discord.com/api/v10/applications/$APPLICATION_ID/guilds/$GUILD_ID/commands"Subcommands
A command with subcommands cannot be invoked on its own. /hosting does nothing, /hosting status does. That is exactly how we take it: every invocable form becomes one line, the bare folder disappears. In the text field “ — ” then separates the path from the description.
Pasting it in
In your dashboard, on the bot, under “Edit”, in the “Commands” field: open “Import from Discord”, paste the JSON and press Import. The import replaces the list completely, so anything you typed by hand before is gone afterwards. The result shows in the field above immediately; nothing is stored until you save.
Why we cannot fetch it ourselves
The endpoint belongs to the requesting application: with our token we get our commands, not yours. Yours would need your token. And a directory that asks for your bot token just to show a list has crossed a line. So this way round: you fetch, you paste.
About the token
The token stays with you. We do not need it and never ask for it. The JSON answer contains none, so you can paste it without worry. And if you did paste it somewhere once: reset it in the Developer Portal, it costs nothing.