Create your first bot
- Open Settings → Bots → Create bot. Your host may disable bot creation.
- Choose a username using
a-z0-9_, 2–32 characters. Save the token: it is shown once. - Add the bot in community settings and grant only the permissions it needs. Management requires
MANAGE_BOTS. - Run the bot program on your computer or server. Creating a bot account does not run its code.
- Use the API address of the host that issued the token.
Bots work in channels of communities they have joined. The Bot API does not support direct messages or public spaces.
Authentication and secrets
Authorization: Bearer <BOT_TOKEN>Bot actions require a bot token. Creating or editing a bot, adding it to a community and granting permissions require the owner’s or administrator’s account token. Keep these authorities separate.
Store tokens in environment variables, never in browser code or Git. The host database stores token hashes. Revoke leaked tokens and create replacements. Gateway passes the token in a query string, so redact URLs in reverse proxy and monitoring logs. Use HTTPS/WSS.
Minimal working example
Requires Node.js 22+ with built-in fetch and WebSocket. Download ping-bot.en.mjs. The example registers /ping, replies in a channel and reconnects after a disconnect.
$env:SIBREL_API_URL = "https://api.example.org"
$env:SIBREL_BOT_TOKEN = "your-token"
node ./ping-bot.en.mjsBot REST API
| Method and path | Purpose |
|---|---|
| GET /api/bots/me | Profile, connection status, commands and communities. |
| GET /api/bots/guilds | Communities the bot has joined. |
| GET /api/bots/guilds/:guildId/channels | Available channels. |
| GET /api/bots/channels/:channelId/messages?limit=20&before=:id | History; at most 100 messages per request. |
| POST /api/bots/messages | Send channel_id and content / embeds / components; optional reply_to_id. |
| PATCH /api/bots/messages/:id | Edit the bot’s own message. |
| DELETE /api/bots/messages/:id | Soft delete. mode=hard requires the relevant permissions. |
| POST /api/bots/channels/:id/typing | Typing indicator; returns 204. |
| GET /api/bots/commands | List declared commands. |
| PUT /api/bots/commands | Replace the entire global command list. |
| PUT /api/bots/guilds/:guildId/commands | Replace the entire community command list. |
| POST /api/bots/voice/join | Join: {channel_id}. |
| POST /api/bots/voice/leave | Leave: {channel_id}; returns 204. |
POST /api/bots/messages
{
"channel_id": 42,
"content": "Hello from the bot!",
"reply_to_id": 123
}Successful send: 201 { message }. Do not set Content-Type: application/json when sending no body: an empty JSON request may return 400.
Managing bots and permissions
| Account authentication | Action |
|---|---|
| GET /api/bots; POST /api/bots | List your bots; create with username and optional profile fields. |
| PATCH /api/bots/:id; DELETE /api/bots/:id | Edit a profile; delete a bot and its messages. |
| GET /api/bots/:id/tokens; POST /api/bots/:id/tokens | Token metadata; issue a new token with {name}. |
| DELETE /api/bots/:id/tokens/:tokenId | Revoke a token. |
| POST /api/guilds/:guildId/bots | Add {bot_id}. |
| DELETE /api/guilds/:guildId/bots/:botId | Remove from the community. |
| GET /api/guilds/:guildId/bots/:botId/permissions | Current bitmask and available permissions. |
| PUT /api/guilds/:guildId/bots/:botId/permissions | Save {permissions: "114688"}; send bigint as a string. |
Bots have a separate permission bitmask per community, not ordinary member roles. View channels: 16384; send messages: 32768; voice: 65536. These three permissions total 114688. Bots are not granted administrator access.
Slash commands
PUT /api/bots/commands
{ "commands": [
{ "name": "ping", "description": "Check the bot response", "options": [] },
{ "name": "echo", "description": "Repeat text", "options": [
{ "name": "text", "description": "Your text", "type": "string", "required": true }
] }
] }Names: 1–32 characters, a-z0-9_-. Up to 100 commands and 10 options per command. Types: string, number, boolean, user, channel, role; up to 25 choices. Command descriptions may contain up to 200 characters.
PUT replaces the whole list, so send the full set. In message:create, a recognized invocation contains command: {bot_id, name, options, args}. Check bot_id to avoid answering another bot’s commands. Disabled or unknown commands arrive as ordinary text.
Picking a member, channel or role
Options of type user, channel and role are not typed by hand — they are picked from a searchable list. The bot receives a mention token rather than a name, so renaming a channel, role or member never breaks an invocation that was already sent.
| Type | What is offered | What the bot receives |
|---|---|---|
| user | Members of the community where the command was invoked | <@id> |
| channel | Text and voice channels of that community | <#id> |
| role | Roles of that community | <@&id> |
- Search matches the name and, for members, also the nickname and login.
- Service words work too: “voice” finds voice channels, “role” finds roles, “text” finds text channels.
- Matches from the start of the name rank above the rest.
- At most eight options are shown; refine the query if the one you need is missing.
- Enter picks the first option, arrows move the selection, Esc clears the search, Backspace returns to ordinary typing.
The value arrives as a token in command.options ({ "user": "<@42>" }) and as the same value positionally in command.args. A bare id is accepted too, but only the token renders as a mention in your reply text.
Gateway and events
wss://api.example.org/api/bots/gateway?token=<BOT_TOKEN>
{ "type": "ready", "bot_id": 7, "guilds": [1, 2] }
{ "type": "ping" }
{ "type": "pong" }Events: message:create, message:update, message:delete, reaction:add, reaction:remove, interaction. Action event payloads are in data; ready carries bot_id and guilds at the root.
The connection queue holds 256 messages. Overflow produces message:drop; older events may be lost. Implement delayed reconnects, pong monitoring and REST-based state recovery. Do not assume exactly-once event delivery.
Voice
POST /api/bots/voice/join returns channel_id, identity and livekit. When LiveKit is configured, use the returned token and livekitUrl with a compatible client SDK. With livekit: null, the bot only appears in the member list and does not transmit audio. The REST request itself does not start playback.
Errors and operation
| Situation | What to do |
|---|---|
| 400 | Check field types, lengths, JSON and component format. |
| 401 | Check host and token. If revoked, stop retries until the token is replaced. |
| 403 | Check membership and the bot’s separate channel/community permissions. |
| 404 | Check the API address and local resource identifier. |
| 429 | Respect Retry-After when provided and increase the delay. |
| Disconnect / 5xx | Reconnect with bounded backoff. Do not blindly retry sends: duplicates are possible. |
Redact secrets in logs, restrict environment access and do not reply to the bot’s own messages. Agree on data collection with administrators and users, and define retention and deletion procedures.
Voice channels for bots
A bot with the separate CREATE_VOICE_CHANNELS permission can create voice channels using POST /api/bots/guilds/:guildId/channels. It can query states with GET /api/bots/guilds/:guildId/voice-states, request a move with POST /api/bots/guilds/:guildId/voice/move and delete an empty channel with DELETE /api/bots/channels/:channelId. The host checks permissions and limits; a token alone does not grant these actions.