Reference
Differences from Discord
Everything that behaves differently from Discord or is not in the Voidcom subset — ids, voice, encrypted DMs, permissions, intents, installation, interactions, gateway details — with a machine-readable list.
Voidcom implements a subset of the Discord bot API and behaves like Discord inside it. This page is the complete list of where it does not. The front matter of this page carries the same list in machine-readable form; the generated API reference is checked against it, so a route listed here as unsupported is guaranteed to be absent from the reference.
Snowflakes and ids
Voidcom uses UUIDs internally and translates them to 64-bit snowflakes at the API boundary, so every id you see is a Discord-shaped decimal string. The epoch is 2025-01-01T00:00:00Z (1735689600000 ms). A library that extracts the timestamp with (id >> 22) + epoch must use this constant instead of Discord's 2015 epoch, or every timestamp is ten years off. Discord.js's SnowflakeUtil and discord.py's snowflake_time use the Discord epoch by default.
Snowflakes are minted the first time an object crosses the boundary and are stable afterwards; an id you stored keeps resolving.
No voice for bots
Bots are text only in v1. There are no voice channels a bot can join, no VOICE_STATE_UPDATE / VOICE_SERVER_UPDATE events, op 4 is ignored and the CONNECT / SPEAK permission bits are never set. Music bots, soundboards and voice recorders have no Voidcom equivalent today.
Encrypted direct messages
Direct messages between Voidcom users are end-to-end encrypted; the server never sees the plaintext, and neither can a bot. A bot in a DM channel receives the message envelope (id, author, timestamp) with content: "", embeds: [] and the Voidcom-only field voidcom_e2e_encrypted: true.
Bots cannot send encrypted content either: a message a bot posts into a DM is delivered as plaintext content, and the voidcom_e2e: true flag on POST /channels/{id}/messages is ignored. Server channels are not end-to-end encrypted, so bots read and write there as on Discord (given MESSAGE_CONTENT). Ephemeral interaction responses work everywhere.
Permissions
The permissions strings use Discord's bit positions, so permissions & SEND_MESSAGES against the Discord constant works. But Voidcom has 13 permissions, and only these bits are ever set or honoured:
CREATE_INSTANT_INVITE KICK_MEMBERS BAN_MEMBERS ADMINISTRATOR MANAGE_CHANNELS MANAGE_GUILD VIEW_AUDIT_LOG SEND_MESSAGES MANAGE_MESSAGES ATTACH_FILES MUTE_MEMBERS MANAGE_ROLES MANAGE_EXPRESSIONS
Writing a role or overwrite with other bits (MANAGE_WEBHOOKS, MODERATE_MEMBERS, MENTION_EVERYONE, CONNECT, …) silently drops them — nothing is granted and nothing is refused, so a bot cannot tighten a permission Voidcom does not have. Reading always shows those bits as 0.
Intents
Intent bits are Discord's. IDENTIFY may only ask for intents the token was granted — the toggles on the application page, baked into the token when it is minted; asking for more closes the socket with 4014, as on Discord. Of the granted intents only those in the events table deliver anything. GUILD_MODERATION, GUILD_EXPRESSIONS, GUILD_INTEGRATIONS, GUILD_WEBHOOKS, GUILD_INVITES, GUILD_VOICE_STATES, GUILD_SCHEDULED_EVENTS, AUTO_MODERATION_* and *_POLLS are accepted and deliver no events. The three privileged intents (GUILD_MEMBERS, GUILD_PRESENCES, MESSAGE_CONTENT) need approval, and there is no self-service approval yet.
Installation
There is no OAuth2. No /oauth2/authorize URL, no client_id/scope=bot link, no /oauth2/token. A server admin installs a bot from the developer site — the application's install link /install/<application id> — with their Voidcom account; see Authentication & applications.
A bot token cannot join a server, create a server or create an invite: POST /guilds is 501, POST /channels/{id}/invites is 403 for bots even with CREATE_INSTANT_INVITE. GET /guilds/{id}/invites and GET/DELETE /invites/{code} work, and DELETE /users/@me/guilds/{id} still leaves.
Interactions
Interactions are delivered over the gateway only. The interactions endpoint URL you can store in the portal is never called, so there is no PING (type 1) to answer and no Ed25519 signature to verify; callback type 1 answers 204 and does nothing.
Callback types 8 (autocomplete) and 9 (modal) answer 501 with code 50035. Command options with autocomplete: true are stored but no autocomplete interaction is ever sent.
The …/commands/permissions routes are 501 — every command is usable by every member the channel permissions allow. Bulk overwrite (PUT /applications/{application_id}/commands and the guild variant, what CommandTree.sync() and discord.js deploy scripts send) works as on Discord, as one transaction.
An interaction that fires while the bot has no live gateway session is dropped, not queued: the user sees the command fail, and RESUME does not deliver it later.
PATCH of a message, @original or follow-up replaces embeds and components as a whole when either key is present. Omitting both keeps them; [] clears them. There is no per-embed merge.
User, role, mentionable and channel select menus (component types 5–8) are accepted as { type, custom_id, disabled } only and rendered greyed out; they never produce an interaction. Buttons and string selects work as on Discord — limits on Interactions.
Users and messages
bot is true on GET /users/@me and in READY, but false on message author, mention and public-profile objects, including your own bot's messages. Skip your own messages by comparing author.id with your bot's id, not with author.bot.
verified (email verified) is not exposed for other users; the field is present on /users/@me only.
There is no file upload: POST /channels/{id}/messages takes JSON only, no multipart/form-data, no files[n], no attachments array on send. Received messages carry attachments with URLs.
No threads, forum channels, stickers, polls, scheduled events, stage instances or auto-moderation: the routes are 501 and the events never fire.
Gateway
Frames are JSON text only — no compress=zlib-stream, no ETF encoding. The ?v=…&encoding=…&compress=… query parameters are accepted and ignored.
The only 4xxx close codes are 4000 (heartbeat timeout — RESUME) and 4014 (IDENTIFY with intents beyond the token's grant). Every other failure is op 9 Invalid Session (d: false) followed by a plain close: a bad token is not reported as 4004, invalid intent bits not as 4013.
Op 3 (presence update) and op 8 (request guild members) are accepted and ignored: a bot's presence cannot be set, and members come from GET /guilds/{id}/members. Op 7 (reconnect) is never sent.
GET /gateway/bot always returns shards: 1; the shard array in IDENTIFY is ignored and session_start_limit is a static 1000 / 1000 / 86400000 / 1.
REST endpoints
Any REST path or method that is not on the API reference table answers 501 Not Implemented with {"message":"endpoint not yet implemented","code":0}. The endpoints list in this page's front matter names the ones Discord bots most commonly call.
Gateway events
The gateway_events list in this page's front matter is the complete set of Discord dispatch names the gateway never sends; the events table is the complete set it does.