Bot API reference
Voidcom's bot API mirrors Discord's REST routes and gateway opcodes, so the libraries you already know work against Voidcom. This page is an overview of the surface; it is not exhaustive.
Base URLs
REST https://bots.voidcom.app/api/v10
Gateway wss://bots.voidcom.app/ws Self-hosted instances expose the same paths on their own host.
Authentication
A bot authenticates with a bot token in the Authorization header. The token is a
signed JWT issued by the Voidcom server; the bot API validates it locally and reads the bot's
application id and intents from it.
Authorization: Bot YOUR_VOIDCOM_BOT_TOKEN Connecting an existing bot
With discord.js, point the REST and gateway URLs at Voidcom and log in with a Voidcom bot token — no code changes:
const client = new Client({
intents: [/* … */],
rest: { api: 'https://bots.voidcom.app/api', version: '10' },
ws: { gateway: 'wss://bots.voidcom.app/ws' },
});
await client.login('Bot YOUR_VOIDCOM_BOT_TOKEN'); discord.py hardcodes Discord's host, so it needs a small host-rewrite proxy or a
fork that accepts a custom API URL. Voice is not exposed to bots yet. Snowflake
timestamps use a Voidcom epoch of 2025-01-01T00:00:00Z — libraries that derive a
creation time from an id must use this epoch, not Discord's 2015 one.
REST resources
All routes are mounted under /api/v10.
| Resource | Representative endpoints |
|---|---|
| Users | GET /users/@me · PATCH /users/@me · GET /users/{id} · GET /users/@me/guilds · POST /users/@me/channels (open DM) |
| Gateway | GET /gateway · GET /gateway/bot |
| Guilds (servers) | GET · PATCH · DELETE /guilds/{id} · GET · POST /guilds/{id}/channels |
| Members | GET /guilds/{id}/members · GET · PATCH · DELETE /guilds/{id}/members/{user} · PUT · DELETE …/roles/{role} |
| Moderation | GET /guilds/{id}/bans · PUT · DELETE /guilds/{id}/bans/{user} · GET /guilds/{id}/audit-logs |
| Roles | GET · POST /guilds/{id}/roles · PATCH · DELETE /guilds/{id}/roles/{role} |
| Channels | GET · PATCH · DELETE /channels/{id} · permissions overwrites |
| Messages | GET · POST /channels/{id}/messages · GET · PATCH · DELETE …/{message} · bulk-delete |
| Reactions | PUT · DELETE /channels/{id}/messages/{m}/reactions/{emoji}/@me |
| Typing & pins | POST /channels/{id}/typing · GET · PUT · DELETE /channels/{id}/pins/{m} |
| Invites | POST · GET · DELETE /channels/{id}/invites · GET · DELETE /invites/{code} |
| Webhooks | GET · POST /channels/{id}/webhooks · GET · POST · PATCH · DELETE /webhooks/{id}/{token} |
| Webhook ingest | POST /webhooks/{id}/{token}/github · POST /webhooks/{id}/{token}/slack |
| Commands | GET · POST /applications/{app}/commands · PATCH · DELETE …/{command} (+ guild-scoped) |
| Interactions | POST /interactions/{id}/{token}/callback |
| Voidcom E2EE | GET /api/voidcom/users/{id}/public-key |
Gateway
Connect to the gateway over WebSocket. The server sends Hello with a heartbeat interval (≈41 s); the client replies with Identify (token + intents) and receives a Ready dispatch. Dropped sessions can be continued with Resume. Events are filtered by the intents bitfield you declare in Identify.
| Op | Name | Direction / meaning |
|---|---|---|
| 0 | Dispatch | Server → client. An event (READY, MESSAGE_CREATE, …). |
| 1 | Heartbeat | Keep-alive, both directions. |
| 2 | Identify | Client → server. Auth + intents on connect. |
| 6 | Resume | Client → server. Resume a dropped session. |
| 7 | Reconnect | Server → client. Reconnect, please. |
| 9 | Invalid Session | Server → client. Re-identify. |
| 10 | Hello | Server → client on connect. Carries heartbeat interval. |
| 11 | Heartbeat ACK | Server → client. Acknowledges a heartbeat. |
Privileged intents (guild members, presences, message content) must be enabled for your application, as on Discord.
Rate limits
Every response carries standard rate-limit headers so clients can back off:
X-RateLimit-Limit
X-RateLimit-Remaining
X-RateLimit-Reset
X-RateLimit-Reset-After
X-RateLimit-Bucket Exceeding a limit returns 429 Too Many Requests.
Slash commands & interactions
Register global or guild-scoped commands under /applications/{app}/commands,
and respond to interactions at /interactions/{id}/{token}/callback.
Supported response types include channel message (4), deferred responses (5, 6), update message
(7), autocomplete result (8), and modal (9).
Webhook ingest
Webhooks can post messages directly, and two ingest adapters translate external events into channel messages:
POST /webhooks/{id}/{token}/github # GitHub push, PR, issue, release, …
POST /webhooks/{id}/{token}/slack # Slack-formatted payloads Encryption-aware messaging
To send into an end-to-end encrypted channel, a bot fetches the recipient's hybrid public key and encrypts client-side:
GET /api/voidcom/users/{user_id}/public-key
→ { "user_id": …, "public_key": "<base64>", "key_version": … } The key is a post-quantum hybrid (X25519 + ML-KEM-768) public key. The server never sees plaintext for encrypted messages.