Docs

Bots

Bots are self-hosted integrations. You run the code, Disband relays messages to and from it. Disband never hosts or executes your bot's code.

How it works

  1. Create a bot in Settings → Botsand pick the scopes it needs. You get a token back — it's shown once.
  2. In Settings → Bots, generate an invite link for the server you want the bot to join, and send it to that server's owner.
  3. The owner opens the link and approves. The bot becomes a member of the server.
  4. You run the client library somewhere (a server, a cloud function, your laptop) and it connects to Disband with the token.

Scopes

A bot's reach in a server is the intersection of the scopes you requested when creating it and the scopes the owner approved for that specific server:

ScopeDescription
messages.readReceive message events on the gateway and read messages/channels.
messages.writeSend and reply to messages in channels the bot can see.
members.readList the members of servers the bot has joined.
channels.manageCreate, rename, and delete channels — also needs the manage_channels role in the server.

Client libraries

The official clients are token-authenticated and have zero runtime dependencies.

JavaScript

Works from Node.js 18+, Deno, Bun, and the browser. Install from this repo:

npm install /path/to/packages/bot
import { Client } from "@disband/bot";

const client = new Client({ token: process.env.DISBAND_BOT_TOKEN });

client.on("ready", (me) => console.log(`Logged in as ${me.name}`));

client.on("messageCreate", async (message) => {
  if (message.author?.is_bot) return;
  if (message.content !== "!ping") return;
  await message.reply("pong");
});

await client.connect();

Python

Standard library only (threading + urllib). Install from this repo:

pip install ./packages/disband-bot-python
from disband_bot import Client

client = Client(token=DISBAND_BOT_TOKEN)

@client.on("messageCreate")
def handle(message):
    if message.author_is_bot:
        return
    if message.content == "!ping":
        message.reply("pong")

client.run()

API

All endpoints take Authorization: Bot <token>. Errors return JSON with an error field and a 4xx/5xx status.

Endpoints
GET/api/v1/gateway?timeout=20
POST/api/v1/channels/:id/messages
GET/api/v1/channels/:id/messages
GET/api/v1/servers/:id/channels
GET/api/v1/servers/:id/members
POST/api/v1/servers/:id/channels
PATCH/api/v1/channels/:id
DELETE/api/v1/channels/:id
POST/api/v1/servers/:id/leave
POST/api/v1/bots/:botId/invites

Message payload

{
  "id": "…",
  "channel_id": "…",
  "server_id": "…",
  "author": { "id": "…", "username": "…", "display_name": "…", "avatar_url": "…", "is_bot": false },
  "content": "Deploy finished",
  "reply_to_id": null,
  "mentions": [],
  "attachment_url": null,
  "attachment_type": null,
  "created_at": "2026-01-01T00:00:00Z",
  "edited_at": null,
  "display_id": 1234
}

Limits & safety

  • Up to 5 bots per account. A bot can be revoked at any time, which kills its token.
  • Messages up to 4,000 characters. Bots need the mention_everyone role permission to use @everyone.
  • Only a server's owner can approve a bot invite. Invites expire after 7 days.
  • Bot tokens are hashed at rest; the raw token is never stored or retrievable.
  • Bots can never reach the database directly — every action goes through scoped API endpoints.