Skip to content

Commands

All commands require authentication except auth. listener is valid on every request and is omitted from the field lists below. “Broadcast” means other relevant connections may receive the event.

Command Request fields Response or event
auth validator: string auth_success, then ready; or auth_error
capabilities capabilities: string[] (or legacy val) No response; strings are stored on the connection
ping sent_at?: number Without a positive sent_at: { cmd, server_time }; otherwise echoes it and adds receive/send timestamps
typing channel?, thread_id?, duration: integer >= 0 = 6000, sent_at?: number Broadcast typing; duration is forwarded unchanged with no server-side unit conversion

The server-originated handshake is not a request. channel_get, unreads_update, user_join, user_connect, user_disconnect, ready, auth_success, auth_error, and rate_limit are also server events or response shapes rather than dispatched requests. Presence changes reuse the dispatched name status_get as their event command.

Command Request fields Response or event
channels_get none channels_get { val: Channel[] }
channel_create name (1–64), type (text|voice|forum|separator); optional permissions, description, display_name, size, max_message_age, slow_mode_cooldown. For separators, size is UI padding/spacing. { cmd, val: true }; channel refresh is pushed
channel_update current_name, updates containing any create field { cmd, val: true }; focused/full refresh is pushed
channel_move name, position: integer >= 0 { cmd, val: true }
channel_delete name { cmd, val: true }

Channel names are validated by the shared channel helper. Metadata mutations are persisted, audited, then followed by channel refreshes.

For message commands, supply either channel or thread_id. When a thread is supplied, the server derives and returns its parent channel.

Command Request fields Response or event
message_new channel?, thread_id?, and at least one of content, embeds, attachments; optional reply_to, ping; optional signature fields Broadcast message_new { channel, thread_id?, message }
message_get channel?, thread_id?, id message_get { channel, thread_id?, message }
message_replies channel?, thread_id?, id message_replies { channel, thread_id?, val }
messages_get channel?, thread_id?, start: number|string = 0, limit = 100 Returns the newest start + limit messages; current code does not trim to limit or treat start as an offset
messages_around channel?, thread_id?, around, bounds?: { above=50, below=50 } { messages, range, at_start?, at_end? }; each bound capped at 200
messages_search query?, fuzzy?, channel?, thread_id?, filters?, limit?, offset? { results, total, offset, limit, has_more, fuzzy }
message_edit channel?, thread_id?, id; any of content, embeds, attachments; optional signature fields Broadcast message_edit { id, channel, thread_id?, message }
message_delete channel?, thread_id?, id Broadcast message_delete { id, channel, thread_id? }
message_pin / message_unpin channel?, thread_id?, id Broadcast pin-change event
messages_pinned channel?, thread_id? { messages: Message[] }

Signature fields are author_id, key_id, signature, and timestamp. Search filters support from, mentions, mentions_role, pinged, has, pinned, edited, before, and after. has accepts attachment, embed, reaction, reply, edit, webhook, command, image, video, audio, poll, link, or mention.

Command Request fields Response or event
poll_create channel?, thread_id?, question, options, optional multiselect/expiry fields Broadcast message_new with poll_id and poll embed
poll_get poll identifier/context accepted by pollRequest poll_get { poll }
poll_vote poll context plus option_id or option_ids Broadcast { poll_id, message_id, user, option_ids, results }
poll_results poll context { poll_id, message_id, results }
poll_end poll context Broadcast { poll_id, message_id, channel, results }

For multiselect polls, sending one option_id toggles that choice relative to the user’s current selection; option_ids replaces the selection.

Command Request fields Response or event
threads_get channel (forum) { channel, val: Thread[] }
thread_create channel, name Broadcast { thread, channel }
thread_get thread_id { thread }
thread_update thread_id; optional name, archived, locked Broadcast { thread, channel }
thread_delete thread_id Broadcast { thread_id, channel }
thread_join / thread_leave thread_id Broadcast { thread, thread_id, user, channel }
thread_pin / thread_unpin thread_id Broadcast pin-change event
unreads_get none { channels, threads, … } unread snapshot
unreads_ack channel, optional thread_id, optional message_id Direct acknowledgement and unreads_update
pings_get pagination/context fields Stored ping records visible to the user

Threads can only be created/listed in forum channels. Their messages use the ordinary message commands with thread_id.

Command Request fields Response or event
users_online none { users: PublicUser[] }
users_list none { users: PublicUser[] } excluding banned users
users_banned none { users: string[] }
status_get user status { username, status }
status_set status, text? (max 100) { status } and presence broadcast
user_update user, updates: { username?, nickname? } Broadcast { user, nickname }
user_ban / user_unban user { user, banned|unbanned }
user_kick user, reason? Broadcast { user, kicked: true }; target receives auth_error
user_timeout user, duration > 0 seconds, reason? { user, timed_out: true, duration }; current code broadcasts rate_limit to all except the actor and sends it to the target a second time
user_leave delete_messages?: boolean { user, messages_deleted, val }

Valid statuses are online, idle, dnd, offline, and invisible.

Command Request fields Response or event
roles_list none { val: Record<string, Role> }
role_create name; optional description, color, gradient, permissions, hoisted, self_assignable, category { val: true, id, name } and broadcast
role_update id? or name?, plus update fields { val: true, id, name } and broadcast
role_delete id? or name? { val: true, id, name } and broadcast
role_reorder roles: string[] { val: true, roles } and broadcast
user_roles_get user { user, roles, color, gradient }
user_roles_set user, roles (non-empty) user_roles_get response/broadcast plus target channel refresh
self_roles_list none { roles }, each with assigned
self_role_add / self_role_remove role self-role response plus channel refresh

An actor cannot assign a permission they do not hold. Role hierarchy and protected system-role rules are enforced in helpers.

Command Request fields Response or event
reaction_add / reaction_remove message context plus reaction identifier Broadcast reaction change
message_react_add / message_react_remove same Legacy aliases
emoji_list none { emojis }
emoji_get emoji_id asset fields
emoji_add name, image asset fields plus added: true
emoji_update emoji_id, at least one of name, image asset fields plus updated
emoji_delete emoji_id { id, deleted }
sticker_list none { stickers }
sticker_get sticker_id asset fields
sticker_add name, image, description? asset fields plus added: true
sticker_update sticker_id, any of name, image, description asset fields plus updated
sticker_delete sticker_id { id, deleted }

image is the asset payload format accepted by the asset backend. File extensions must match handshake upload allowlists.

Command Request fields Response or event
attachment_get attachment_id attachment_info
attachment_list none attachment_list (requires manage_server)
attachment_delete attachment_id attachment_deleted

Upload is HTTP rather than WebSocket; see HTTP & uploads.

Command Request fields Response or event
slash_list channel?, thread_id? { val: command definitions }
slash_call command, args, channel?, thread_id?, optional username response/event defined by command
slash_register commands add/remove events and registration result
slash_response id, response response delivery acknowledgement
voice_join channel, peer_id Broadcast voice state/join event
voice_leave current voice context Broadcast leave event
voice_mute / voice_unmute current voice context Broadcast mute state
voice_state channel { channel, state }

Voice signaling is peer-state coordination; media transport is a client concern.

Command Request fields Response or event
report_create report target/type/context fields created report
report_list filters/pagination report collection
report_resolve report identifier and resolution fields resolved report
modlog_get filters/pagination audit records; requires audit permission in handler
modlog_summary summary filters grouped audit summary
config_get none resolved configuration
config_update updates persisted update result
server_update supported server fields updated server info/broadcast
server_stats none server/runtime statistics
webhook_create webhook definition fields created webhook including secret material as applicable
webhook_get webhook identifier webhook definition
webhook_list none webhook collection
webhook_update identifier plus updates updated definition
webhook_delete identifier deletion result
webhook_regenerate identifier regenerated credential/path

Administrative mutation details are intentionally validated by their focused helpers and may evolve behind the advertised capability name. Inspect error.src and feature-detect before exposing controls.