Gateway events
A Dispatch reports a change or command result through the Gateway. It has opcode 0, an event name, and a payload.
Dispatch envelope
Section titled “Dispatch envelope”| Field | Type | Description |
|---|---|---|
| op | integer | Value 0 |
| t | string | Uppercase event name |
| s | integer | Non-negative session sequence |
| d | any | Payload defined for the named event |
{ "op": 0, "t": "MESSAGE_CREATE", "s": 17, "d": { }}Ready establishes sequence 1. Live Dispatches advance it by one. Replayed Dispatches keep their original sequence and can have gaps. Resumed has the session’s current sequence without advancing it. The next live Dispatch has that sequence plus one. The sequence is local to one Gateway session and orders nothing across shards or HTTP operations.
Dispatch delivery
Section titled “Dispatch delivery”Event filtering defines delivery by guild availability, channel visibility, permissions, and session settings. Account-scoped Dispatches go through only the session-level filters, which are the shard filter and the ignored_events list.
Most guild-scoped Dispatches have a guild_id string. Guild Create and Guild Sync identify the guild as id, and so does every Guild Delete other than the one the guild itself dispatches when the guild is deleted. Guild Counts Update and Channel Member Counts Update have no top-level guild_id, and each entry in their counts array has its own.
The originating session is excluded from a Dispatch only for Message Reaction Add and Message Reaction Remove in a guild channel, and only when the request supplied a session_id. That field is removed from the payload. The same field on a direct message or group direct message reaction is forwarded to every recipient unchanged and excludes nobody. The actor that issues any other mutation receives the resulting Dispatch like every other eligible session.
A Dispatch is buffered for Resume replay unless it is Guild Sync, Guild Member List Update, or Guild Members Chunk. Those are delivered live and never retained. A single oversized Dispatch is delivered but not retained, as Limits and rate limits describes. Ready and the guild burst that follows it for a bot session are also sent outside the replay buffer. The initial Call Create events are retained like any other Dispatch and are replayed on Resume.
Dispatch events
Section titled “Dispatch events”| Event | Description | Scope |
|---|---|---|
| Ready | The initial session state after a successful Identify | Session lifecycle |
| Resumed | Retained replay completes after a successful Resume | Session lifecycle |
| Sessions Replace | The account’s live session presence set is replaced | Current user |
| Auth Session Change | The account’s authentication session is rotated | Current user |
| Rate Limited | A member request is refused by its budget | Command response |
| User Update | The current user’s account record changes | Current user |
| User Settings Update | The current user’s account-wide settings change | Current user |
| User Guild Settings Update | One guild notification record changes | Current user |
| User Note Update | The current user writes or clears a private note | Current user |
| User Pinned DMs Update | The current user’s pinned private channel set is replaced | Current user |
| User Connections Update | The current user’s external connection set is replaced | Current user |
| WebAuthn Credentials Update | The current user’s WebAuthn credential set is replaced | Current user |
| Relationship Add | The current user gains a relationship | Current user |
| Relationship Update | One of the current user’s relationships changes | Current user |
| Relationship Remove | The current user loses a relationship | Current user |
| Saved Message Create | The current user saves a message | Current user |
| Saved Message Delete | The current user unsaves a message | Current user |
| Recent Mention Delete | The current user removes a recent mention | Current user |
| Favorite Meme Create | The current user saves a meme | Current user |
| Favorite Meme Update | One of the current user’s memes changes | Current user |
| Favorite Meme Delete | The current user deletes a meme | Current user |
| Guild Create | A guild becomes available to the session | Guild connection |
| Guild Sync | A subscribed session receives the guild’s full current state again | Guild connection |
| Guild Update | A guild’s configuration changes | Guild connection |
| Guild Delete | A guild leaves the session’s visibility or becomes unavailable | Guild connection |
| Guild Role Create | A role is created in a guild | Guild connection |
| Guild Role Update | Exactly one role record changes | Guild connection |
| Guild Role Update Bulk | One operation changes several role records together | Guild connection |
| Guild Role Delete | A role is deleted from a guild | Guild connection |
| Guild Emojis Update | A guild’s emojis change | Guild connection |
| Guild Stickers Update | A guild’s stickers change | Guild connection |
| Channel Create | A channel becomes visible to the session | Channel visibility |
| Channel Update | A visible channel changes | Channel visibility |
| Channel Update Bulk | One operation changes several channels together | Channel visibility |
| Channel Delete | A channel leaves the session’s visibility | Channel visibility |
| Channel Recipient Add | A user joins a group direct message the session belongs to | Private channel |
| Channel Recipient Remove | A user leaves a group direct message the session belongs to | Private channel |
| Webhooks Update | The webhook set of a viewable guild channel changes | Channel visibility |
| Invite Create | An invite is created | Invite audience |
| Invite Delete | An invite is deleted | Invite audience |
| Guild Member Add | A user becomes a member of a connected guild | Guild connection |
| Guild Member Update | A member’s guild state or public user representation changes | Guild connection |
| Guild Member Remove | A user stops being a member of a connected guild | Guild connection |
| Guild Members Chunk | A bounded member result answers Request Guild Members | Command response |
| Guild Member List Update | A subscribed member list resyncs the subscriber’s ranges | Member list subscription |
| Guild Audit Log Entry Create | An audit log entry is written in a guild | Holders of VIEW_AUDIT_LOG |
| Guild Ban Add | A guild ban is created | Guild connection |
| Guild Ban Remove | A guild ban is removed | Guild connection |
| Presence Update | One visible presence changes | Presence subscription |
| Presence Update Bulk | A recovering guild delivers its visible presences together | Guild connection |
| Passive Updates | Channel last_message_id values or voice states changed for one passive session | Passive session |
| Message Create | A visible message is created | Channel visibility |
| Message Update | A visible message changes and is republished in full | Message access |
| Message Delete | One visible message is deleted | Message access |
| Message Delete Bulk | Several messages in one channel are deleted together | Channel visibility |
| Message ACK | The current user’s read state advances for a channel | Current user |
| Message Reaction Add | A user adds a reaction to a message | Message access |
| Message Reaction Add Many | A debouncing session receives several reaction additions as one event | Message access |
| Message Reaction Remove | One user’s reaction is removed from a message | Message access |
| Message Reaction Remove All | Every reaction is removed from a message at once | Message access |
| Message Reaction Remove Emoji | Every reaction using one emoji is removed from a message | Message access |
| Typing Start | A visible user begins typing in a channel | Channel visibility |
| Channel Pins Update | A channel’s most recent pin time changes | Channel visibility |
| Channel Pins ACK | The current user acknowledges a channel’s pins | Current user |
| Voice State Update | A guild or call participant’s voice state changes | Channel visibility |
| Voice Server Update | The session receives or replaces its own voice grant | Current session |
| Entrance Sound Play | A participant’s entrance sound plays in a voice channel | Voice channel |
| Call Create | A private channel call begins or becomes visible | Call recipient |
| Call Update | The ringing set, participant roster, or region of a call changes | Call recipient |
| Call Delete | A call ends or becomes unavailable | Call recipient |
| Guild Counts Update | Member and online counts are returned for connected guilds | Command response |
| Channel Member Counts Update | Per-channel member and online counts are returned for one guild | Command response |
Session and current user
Section titled “Session and current user”The initial session state. Sent once after a successful Identify, always with sequence 1.
| Field | Type | Description |
|---|---|---|
| session_id | string | Identifier for Resume |
| version | integer | Gateway API version the connection negotiated, always 1 |
| user | user object | The authenticated account in its private representation |
| guilds1 | array[guild ready object] | The session’s guilds |
| private_channels | array[channel object] | Direct message and group direct message channels |
| relationships2 | array[relationship object] | The account’s relationships |
| presences3 | array[presence object] | Visible presences at connection time |
| users4 | array[partial user object] | Users referenced by the payload |
| sessions | array[session presence object] | The account’s other live sessions |
| read_states | array[read state object] | Per-channel read state |
| user_settings | ?user settings object | Account-wide settings |
| user_guild_settings | array[user guild settings object] | Per-guild notification settings |
| notes | map[snowflake, string] | Private notes keyed by user ID |
| pinned_dms | array[snowflake] | Pinned private channel IDs |
| favorite_memes | array[meme object] | Saved memes |
| webauthn_credentials | array[WebAuthn credential object] | Registered WebAuthn credentials |
| rtc_regions | array[RTC region object] | Voice regions, ordered nearest first |
| country_code | string | Country resolved from the connecting address, US when the address resolves to none |
| latitude? | string | Latitude resolved from the connecting address, rendered as a decimal string |
| longitude? | string | Longitude resolved from the connecting address, rendered as a decimal string |
| auth_session_id_hash? | string | Base64url hash identifying the authentication session |
| shard? | array[integer] | The accepted [shard_id, shard_count] pair, present only when Identify supplied one |
| _timings? | object | HTTP-side timing breakdown, present only for a staff account |
| _timings_gw? | object | Gateway-side timing breakdown, present only for a staff account |
1 On a bot session every entry is an unavailable guild with id and unavailable: true alone. The burst described below then sends a Guild Create with the full state of each available guild, and a Guild Delete for each unavailable one
2 Each entry has its user field removed and the removed accounts appear in users instead, so a client resolves a relationship through the entry’s id
3 A bot session always receives an empty array here
4 Collected from the account’s relationships, the recipients of its private channels, and the members in guilds, deduplicated by account ID. A bot session always receives an empty array here
Ready is sent outside the replay buffer, so a Resume never replays it.
A bot session receives one Guild Create per available guild immediately after Ready, and one Guild Delete per unavailable guild. Together they resolve the entries of the guilds array. Those Dispatches are also sent outside the replay buffer.
Shortly after Ready, every session receives one Call Create for each of its private channels that has an active call.
Guild ready object
Section titled “Guild ready object”The same structure appears in Ready, Guild Create, and Guild Sync.
| Field | Type | Description |
|---|---|---|
| id | snowflake | Guild ID |
| properties | guild object | Guild record without its roles, channels, emojis, stickers, or members |
| roles | array[guild role object] | Every role in the guild |
| channels | array[channel object] | Channels the session can view |
| emojis | array[guild emoji object] | Every emoji in the guild |
| stickers | array[guild sticker object] | Every sticker in the guild |
| members1 | array[guild member object] | The members the session needs immediately |
| member_count | integer | Total member count |
| online_count2 | integer | Online member count |
| presences3 | array[presence object] | Always an empty array |
| voice_states | array[voice state object] | Voice states in channels the session can view |
| joined_at | ?ISO8601 timestamp | When the account joined the guild, null when the account is not a member |
| unavailable? | boolean | Whether the guild is unavailable |
| unavailable_hidden? | boolean | Whether an unavailable guild is hidden from the client |
1 The session’s own member object plus the member object of every participant named by voice_states, and nothing else. A client that needs the rest of the roster asks for it with Request Guild Members or subscribes to a member list through Lazy Request
2 Counts the members that hold a live Gateway session and publish a status other than offline or invisible. Every recipient receives the same guild-wide figure. Guild Counts Update reports a per-viewer count
3 Guild presences arrive as separate Presence Update and Presence Update Bulk Dispatches
An unavailable guild is reduced to id and unavailable: true, plus unavailable_hidden: true when the guild is hidden. It has none of the other fields. Every entry in a bot session’s Ready guilds array has this form, with id and unavailable: true alone.
Inside Ready, and inside the Guild Create burst a bot receives immediately after Ready, each entry in members has its user replaced by {"id": "..."}. A bot session’s Ready has no members at all, because each of its guilds is an unavailable guild, so a bot sees the reduced form in the burst alone. On a user session the removed accounts appear in the Ready payload’s users array. A bot’s users array is empty, so a bot pulls those accounts with Request Guild Members. A Guild Create sent later in the session, and every Guild Sync, have the members with user intact.
Session presence object
Section titled “Session presence object”| Field | Type | Description |
|---|---|---|
| session_id | string | Session identifier, or the literal all for the aggregate entry |
| status | string | online, idle, dnd, invisible, or offline |
| afk | boolean | Whether the session is away |
| mobile | boolean | Whether the session is mobile |
The first entry always has session_id: "all" and the account’s combined status, which is the first of dnd, online, idle, and invisible that any of its sessions has, or offline when none has one.
WebAuthn credential object
Section titled “WebAuthn credential object”| Field | Type | Description |
|---|---|---|
| id | string | Credential ID |
| name | string | Credential name |
| created_at | ISO8601 timestamp | When the credential was registered |
| last_used_at | ?ISO8601 timestamp | When the credential was last used |
| rp_id | string | The domain the passkey was created for, as in the WebAuthn credential object |
Replaced passkeys never appear in this list.
RTC region object
Section titled “RTC region object”| Field | Type | Description |
|---|---|---|
| id | string | Region ID |
| name | string | Human-readable region name |
| emoji | string | Region emoji |
The array always begins with a synthetic entry whose id is automatic, name is Automatic, and emoji is the globe. Choosing that entry leaves the region to the server. Every other entry is a region the account can select, ordered by distance from the latitude and longitude in the Identify properties. FiveCord orders by distance only when both values parse as finite numbers, and otherwise orders by region ID.
RESUMED
Section titled “RESUMED”Sent after a successful Resume has replayed every retained Dispatch above the supplied sequence.
| Field | Type | Description |
|---|---|---|
| _timings_gw? | object | Gateway-side timing breakdown, present only for a staff account |
The payload is otherwise empty. Resumed has the session’s current sequence in s without advancing it, and the next live Dispatch has that sequence plus one.
SESSIONS_REPLACE
Section titled “SESSIONS_REPLACE”The account’s set of live sessions changed. The payload is a bare JSON array of session presence objects and is always the complete set. A client that stores the sessions replaces them with this array. Ready sends the initial set as sessions.
AUTH_SESSION_CHANGE
Section titled “AUTH_SESSION_CHANGE”The account’s authentication session was rotated, for example by a password change on another device.
| Field | Type | Description |
|---|---|---|
| old_auth_session_id_hash | string | Base64url hash of the authentication session that was replaced |
| new_auth_session_id_hash | string | Base64url hash of the replacement authentication session |
| new_token | string | Replacement for the token the client holds |
Every session of the account receives the event, including the one that caused the rotation. A client MUST use new_token for every later HTTP request and for any later Resume or Identify. A client whose own auth_session_id_hash from Ready equals old_auth_session_id_hash MUST replace it with new_auth_session_id_hash.
RATE_LIMITED
Section titled “RATE_LIMITED”A Request Guild Members command was refused by the bot full-member-list budget. Delivered to the requesting session alone.
| Field | Type | Description |
|---|---|---|
| opcode | integer | The refused opcode, which is always 8 |
| retry_after | number | Seconds until the request can be retried |
| meta | object | Context for the refused request |
meta has guild_id and, when the request named exactly one guild and supplied a valid nonce, nonce.
That budget admits one unfiltered member request per bot account and guild every 30,000 ms, and retry_after is the remainder of that window in seconds. Every other command refusal is silent.
USER_UPDATE
Section titled “USER_UPDATE”The current user’s account record changed. The payload is the complete user object in its private representation.
Presence subscribers receive the updated user in a Presence Update, unless the user’s published status is offline.
USER_SETTINGS_UPDATE
Section titled “USER_SETTINGS_UPDATE”The current user’s account-wide settings changed. The payload is the complete user settings object.
FiveCord republishes the account’s presence on every settings update, whether or not status or custom_status changed. A status of offline in the payload is treated as invisible, and it forces every live session of the account to that status.
USER_GUILD_SETTINGS_UPDATE
Section titled “USER_GUILD_SETTINGS_UPDATE”One guild’s notification settings changed. The payload is that guild’s complete user guild settings object.
USER_NOTE_UPDATE
Section titled “USER_NOTE_UPDATE”The current user wrote or cleared a private note.
| Field | Type | Description |
|---|---|---|
| id | snowflake | User the note is about |
| note | string | Note text, empty when cleared |
USER_PINNED_DMS_UPDATE
Section titled “USER_PINNED_DMS_UPDATE”The current user’s pinned private channel set changed. The payload is a bare JSON array of channel ID strings in pinned order and is always the complete set. A client that stores the pinned channels replaces them with this array. Ready sends the initial set as pinned_dms.
USER_CONNECTIONS_UPDATE
Section titled “USER_CONNECTIONS_UPDATE”The current user’s external connection set changed.
| Field | Type | Description |
|---|---|---|
| connections | array[connection object] | Every connection the account holds |
connections is always the complete set. A client that stores the connections replaces them with this array.
WEBAUTHN_CREDENTIALS_UPDATE
Section titled “WEBAUTHN_CREDENTIALS_UPDATE”The current user’s WebAuthn credential set changed. The payload is a bare JSON array of WebAuthn credential objects and is always the complete set. A client that stores the credentials replaces them with this array. Ready sends the initial set as webauthn_credentials.
RELATIONSHIP_ADD
Section titled “RELATIONSHIP_ADD”The current user gained a relationship. The payload is the complete relationship object.
| Field | Type | Description |
|---|---|---|
| id | snowflake | The other user’s ID |
| type | integer | Relationship type |
| user | partial user object | The other user |
| since? | ISO8601 timestamp | When the relationship was created, absent when the record has no timestamp |
| nickname | ?string | Private nickname for the other user |
| share_voice_activity | boolean | Whether the current user shares voice activity with this friend on the Active Now panel |
| friend_shares_voice_activity1 | boolean | Whether the other user shares voice activity with the current user |
1 Always true on this Dispatch, even for a friendship whose counterpart has sharing off
A client that needs the real value MUST read it from List relationships.
RELATIONSHIP_UPDATE
Section titled “RELATIONSHIP_UPDATE”An existing relationship changed. The payload has the same structure as Relationship Add.
friend_shares_voice_activity is the counterpart’s real setting only on the pair of Dispatches that Modify voice activity sharing sends to both parties of each friendship. Every other Relationship Update sends true.
RELATIONSHIP_REMOVE
Section titled “RELATIONSHIP_REMOVE”A relationship ended.
| Field | Type | Description |
|---|---|---|
| id | snowflake | The other user’s ID |
SAVED_MESSAGE_CREATE
Section titled “SAVED_MESSAGE_CREATE”The current user saved a message. The payload is the complete message object as that user sees it.
SAVED_MESSAGE_DELETE
Section titled “SAVED_MESSAGE_DELETE”The current user unsaved a message.
| Field | Type | Description |
|---|---|---|
| message_id | snowflake | The message that is no longer saved |
RECENT_MENTION_DELETE
Section titled “RECENT_MENTION_DELETE”The current user removed a message from the recent mention feed.
| Field | Type | Description |
|---|---|---|
| message_id | snowflake | The message removed from the feed |
FAVORITE_MEME_CREATE
Section titled “FAVORITE_MEME_CREATE”The current user saved a meme. The payload is the complete meme object.
FAVORITE_MEME_UPDATE
Section titled “FAVORITE_MEME_UPDATE”One of the current user’s memes changed. The payload is the complete meme object.
FAVORITE_MEME_DELETE
Section titled “FAVORITE_MEME_DELETE”The current user deleted a meme.
| Field | Type | Description |
|---|---|---|
| meme_id | snowflake | The deleted meme |
Guilds and channels
Section titled “Guilds and channels”GUILD_CREATE
Section titled “GUILD_CREATE”A guild became available to the session. The payload is a guild ready object.
roles, channels, emojis, stickers, and voice_states are always complete. A client that stores any of them for the guild replaces its stored list with the new array. members is a partial list. A client adds or updates those members and keeps every other member it already stores.
Every session receives Guild Create when a guild becomes available after Ready, for example after joining one or after an unavailable guild recovers. A bot session also receives one for each available guild in the burst that follows Ready.
A bot session’s Guild Create has unavailable: false unless it is the first Guild Create for a guild the bot joined during the session and Ready did not list. That Dispatch has no unavailable field, even when a Guild Delete with unavailable: true for the guild came before it. A user session never receives the field on Guild Create.
GUILD_SYNC
Section titled “GUILD_SYNC”A session that asked for a sync through Lazy Request receives the guild’s full current state again. The payload is a guild ready object, and a client handles it the same way as Guild Create.
FiveCord sends a sync when a Lazy Request switches the guild between active and passive, and when sync: true names a guild the session has not already synced. A second sync: true for an already-synced guild sends nothing.
GUILD_UPDATE
Section titled “GUILD_UPDATE”A guild’s configuration changed. The payload is the complete guild object with guild_id added, which repeats the object’s own id.
Guild Update is the only Dispatch an unavailable guild sends. A client learns from it that a guild entered or left the unavailable state.
GUILD_DELETE
Section titled “GUILD_DELETE”A guild left the session’s visibility, or became unavailable.
| Field | Type | Description |
|---|---|---|
| id | snowflake | Guild ID |
| guild_id?1 | snowflake | Repeats id |
| unavailable? | boolean | True when the guild is temporarily unavailable |
| unavailable_hidden? | boolean | True when an unavailable guild is hidden from the client |
1 Present only when the guild itself is deleted. The payload has id alone when the account leaves a guild or is removed from one, and id with unavailable in the unavailable form
Without unavailable, the account is no longer a member, and a client deletes everything it stores for that guild. With unavailable: true, the guild is temporarily unreachable. A client keeps the guild as an unavailable entry until a later Guild Create sends its full state again.
GUILD_ROLE_CREATE
Section titled “GUILD_ROLE_CREATE”A role was created in a guild.
| Field | Type | Description |
|---|---|---|
| guild_id | snowflake | Guild the role belongs to |
| role | guild role object | The created role |
GUILD_ROLE_UPDATE
Section titled “GUILD_ROLE_UPDATE”Exactly one role record changed.
| Field | Type | Description |
|---|---|---|
| guild_id | snowflake | Guild the role belongs to |
| role | guild role object | The role’s complete updated representation |
GUILD_ROLE_UPDATE_BULK
Section titled “GUILD_ROLE_UPDATE_BULK”One operation changed several roles together, most often a reorder.
| Field | Type | Description |
|---|---|---|
| guild_id | snowflake | Guild the roles belong to |
| roles | array[guild role object] | Every changed role in its complete updated representation |
GUILD_ROLE_DELETE
Section titled “GUILD_ROLE_DELETE”A role was deleted from a guild.
| Field | Type | Description |
|---|---|---|
| guild_id | snowflake | Guild the role belonged to |
| role_id | snowflake | The deleted role |
GUILD_EMOJIS_UPDATE
Section titled “GUILD_EMOJIS_UPDATE”A guild’s emojis changed.
| Field | Type | Description |
|---|---|---|
| guild_id | snowflake | Guild the emojis belong to |
| emojis | array[guild emoji object] | Every emoji in the guild |
A client that stores the guild’s emojis replaces them with this array. FiveCord does not send per-emoji create, update, or delete events.
GUILD_STICKERS_UPDATE
Section titled “GUILD_STICKERS_UPDATE”A guild’s stickers changed.
| Field | Type | Description |
|---|---|---|
| guild_id | snowflake | Guild the stickers belong to |
| stickers | array[guild sticker object] | Every sticker in the guild |
A client that stores the guild’s stickers replaces them with this array. FiveCord does not send per-sticker create, update, or delete events.
CHANNEL_CREATE
Section titled “CHANNEL_CREATE”A channel became visible to the session, whether newly created or newly permitted. The payload is the complete channel object, with guild_id present for a guild channel.
CHANNEL_UPDATE
Section titled “CHANNEL_UPDATE”A visible channel changed. The payload is the complete channel object.
CHANNEL_UPDATE_BULK
Section titled “CHANNEL_UPDATE_BULK”One operation changed several channels together, most often a reorder.
| Field | Type | Description |
|---|---|---|
| guild_id | snowflake | Guild the channels belong to |
| channels | array[channel object] | Every changed channel in its complete updated representation |
Each recipient sees only channels they can view. An empty result produces no Dispatch and consumes no sequence number.
CHANNEL_DELETE
Section titled “CHANNEL_DELETE”A channel left the session’s visibility, whether deleted or newly hidden. The payload is the complete channel object as it was before the change.
Recipients are the sessions that could see the channel before it was deleted.
CHANNEL_RECIPIENT_ADD
Section titled “CHANNEL_RECIPIENT_ADD”A user joined a group direct message the session belongs to.
| Field | Type | Description |
|---|---|---|
| channel_id | snowflake | Group direct message channel |
| user | partial user object | The user that joined |
CHANNEL_RECIPIENT_REMOVE
Section titled “CHANNEL_RECIPIENT_REMOVE”A user left a group direct message the session belongs to.
| Field | Type | Description |
|---|---|---|
| channel_id | snowflake | Group direct message channel |
| user | partial user object | The user that left |
WEBHOOKS_UPDATE
Section titled “WEBHOOKS_UPDATE”The webhook set of a guild channel changed. The event has no webhook data, so a client that needs the new set reads it over the HTTP API.
| Field | Type | Description |
|---|---|---|
| guild_id | snowflake | Guild the channel belongs to |
| channel_id | snowflake | Channel whose webhooks changed |
INVITE_CREATE
Section titled “INVITE_CREATE”An invite was created. The payload is the complete invite object extended with its invite metadata.
A guild invite reaches the sessions holding MANAGE_CHANNELS on the invite’s channel. A group direct message invite reaches every recipient of that group, with no permission check.
INVITE_DELETE
Section titled “INVITE_DELETE”An invite was deleted.
| Field | Type | Description |
|---|---|---|
| code | string | The deleted invite code |
| channel_id? | snowflake | Channel the invite pointed at, absent when the invite stored none |
| guild_id?1 | snowflake | Guild the invite belonged to |
1 Present on every guild invite. A group direct message invite has no guild_id
Recipients are chosen the same way as for Invite Create.
Members and moderation
Section titled “Members and moderation”GUILD_MEMBER_ADD
Section titled “GUILD_MEMBER_ADD”A user became a member of a guild the session is connected to. The payload is the complete guild member object with guild_id added.
GUILD_MEMBER_UPDATE
Section titled “GUILD_MEMBER_UPDATE”A member’s guild state or public user representation changed. The payload is the complete guild member object with guild_id added.
In a guild with more than 250 members, a passive session receives this event only when the subject is its own user.
GUILD_MEMBER_REMOVE
Section titled “GUILD_MEMBER_REMOVE”A user stopped being a member of a guild the session is connected to.
| Field | Type | Description |
|---|---|---|
| guild_id | snowflake | Guild the user left |
| user1 | object | The user that is no longer a member |
1 The object has id alone. No other account field is sent, so a client MUST resolve the account from state it already holds
In a guild with more than 250 members, a passive session receives this event only when the subject is its own user.
GUILD_MEMBERS_CHUNK
Section titled “GUILD_MEMBERS_CHUNK”Answers Request Guild Members for the requesting session.
| Field | Type | Description |
|---|---|---|
| guild_id | snowflake | Guild the members belong to |
| members | array[guild member object] | Up to 1,000 members |
| chunk_index | integer | Zero-based index of this chunk |
| chunk_count | integer | Total chunks in this response |
| presences? | array[presence object] | Present only when the request set presences and at least one member has a visible presence |
| nonce? | string | Echoed only when the request named exactly one guild and supplied a valid nonce |
A request that matches no member still produces one chunk with an empty members array, chunk_index 0, and chunk_count 1.
This event is delivered live and is never retained for Resume replay.
GUILD_MEMBER_LIST_UPDATE
Section titled “GUILD_MEMBER_LIST_UPDATE”A member list the session subscribed to through Lazy Request resyncs the subscriber’s ranges.
| Field | Type | Description |
|---|---|---|
| guild_id | snowflake | Guild the list belongs to |
| id | string | List identifier, which is always the channel ID as a string |
| channel_id? | snowflake | Channel the list is scoped to |
| member_count | integer | Total members in the list |
| online_count | integer | Online members in the list |
| groups | array[member list group object] | Group headers in list order |
| ops | array[member list operation object] | Operations to apply |
Member list group object
Section titled “Member list group object”| Field | Type | Description |
|---|---|---|
| id1 | string | Group identifier, which is a hoisted role ID, online, or offline |
| count | integer | Members in the group |
1 Hoisted role groups come first in role order, then online, then offline
A group whose count is 0 is omitted. The offline group is also omitted once it holds more than 1,000 members, and in that case items omits the offline members too. member_count can then exceed the number of items a client can ever read back.
Member list operation object
Section titled “Member list operation object”| Field | Type | Description |
|---|---|---|
| op | string | Operation kind, which is always SYNC |
| range | array[integer] | Inclusive [start, end] range this operation replaces |
| items | array[member list item object] | Replacement items for the range |
SYNC is the only operation FiveCord sends. A client MUST ignore an operation whose op it does not recognise or whose range fails the bounds in Lazy Request.
Member list item object
Section titled “Member list item object”Each item has exactly one of the fields.
| Field | Type | Description |
|---|---|---|
| group? | member list group object | A group header occupying one list position |
| member?1 | guild member object | A member of the list |
1 Extended with a presence field that always exists. The value is the guild’s presence object for that member when the member is visibly online to the guild, and otherwise the placeholder {"status": "offline", "mobile": false, "afk": false}
GUILD_AUDIT_LOG_ENTRY_CREATE
Section titled “GUILD_AUDIT_LOG_ENTRY_CREATE”An audit log entry was written. The payload is the guild audit log entry object that List guild audit logs returns for the same entry, with guild_id added. It always has id, action_type, user_id, and target_id. reason is resolved as the audit log reason describes, and options has only the published audit log options keys, with the same number and boolean types. changes is present when at least one change survives scrubbing.
An update that changes nothing records no entry, as the audit actions registry states, so it emits no event.
The ip change key is stripped from changes, so an entry whose only change was ip has no changes at all. A client MUST treat an absent options or changes as an empty set.
Recipients are every session in the guild that holds VIEW_AUDIT_LOG, including the acting session.
GUILD_BAN_ADD
Section titled “GUILD_BAN_ADD”A guild ban was created.
| Field | Type | Description |
|---|---|---|
| guild_id | snowflake | Guild the ban was created in |
| user1 | object | The banned user |
1 The object has id alone. No other account field is sent
GUILD_BAN_REMOVE
Section titled “GUILD_BAN_REMOVE”A guild ban was removed.
| Field | Type | Description |
|---|---|---|
| guild_id | snowflake | Guild the ban was removed from |
| user1 | object | The unbanned user |
1 The object has id alone. No other account field is sent
PRESENCE_UPDATE
Section titled “PRESENCE_UPDATE”One visible presence changed. The payload is a presence object.
A session receives a presence for a friend, for a recipient of a group direct message it belongs to, and for a guild member it subscribed to through the members array of a Lazy Request. A bot session holds no friend or group direct message subscription, so the guild path is the only one that reaches it.
Presence Updates normally follow Ready. The initial Presence Update burst omits users already included in Ready. If Ready takes more than 10,000 ms, Presence Updates can arrive before it.
Later presences can be delayed until their guild, relationship, or group direct message becomes visible. They may arrive after Relationship Add, Relationship Update, Channel Create, Channel Update, or Channel Recipient Add. Delivery is not guaranteed for a subject that never becomes visible.
Presence object
Section titled “Presence object”| Field | Type | Description |
|---|---|---|
| user | partial user object | The user the presence belongs to |
| status | string | online, idle, dnd, or offline |
| mobile | boolean | Whether the user’s active status comes from a mobile session |
| afk | boolean | Whether every one of the user’s sessions is away |
| custom_status | ?custom status object | The user’s custom status |
| guild_id? | snowflake | Guild context, present when the presence arrived through a guild |
An account’s published status is the highest-precedence status across its live sessions, resolved in the order dnd, online, idle, invisible, and finally offline when no session is live. A session that selected invisible, and an account with no live session, both publish status: "offline". A session that lost its transport is published as offline 5,000 ms later, even though it stays resumable for the rest of its 60,000 ms retention window. A successful Resume republishes the status it last selected.
mobile is true only when the account’s resolved status is online and at least one online session declared itself mobile. afk is false whenever mobile is true. Otherwise it is true only when every live session is away.
custom_status is suppressed to null whenever the published status is offline, so an invisible account never reveals one.
Custom status object
Section titled “Custom status object”| Field | Type | Description |
|---|---|---|
| text | ?string | Custom status text |
| expires_at | ?ISO8601 timestamp | When the custom status expires |
| emoji_id | ?snowflake | Custom emoji ID |
| emoji_name | ?string | Unicode emoji, or the custom emoji’s name |
| emoji_animated | boolean | Whether the custom emoji is animated |
PRESENCE_UPDATE_BULK
Section titled “PRESENCE_UPDATE_BULK”Several visible presences are delivered in one Dispatch. A guild sends this only when it leaves the unavailable state. Every session that stayed connected receives it immediately after the Guild Create that restores the guild.
| Field | Type | Description |
|---|---|---|
| guild_id | snowflake | Guild context applied to every entry |
| presences1 | array[presence object] | The presences, at most 500 per Dispatch |
1 Only visibly online presences are included, and the recipient’s own presence is removed. A batch that would be empty produces no Dispatch, and a set larger than 500 is split across consecutive Dispatches
Every entry has the batch’s guild context. A client MUST treat each entry as if it named guild_id itself.
PASSIVE_UPDATES
Section titled “PASSIVE_UPDATES”A passive session in a guild with more than 250 members receives missed changes every 30,000 ms. No event is sent when nothing changed.
| Field | Type | Description |
|---|---|---|
| guild_id | snowflake | Guild the update covers |
| channels | map[snowflake, snowflake] | Changed last_message_id per channel |
| voice_states?1 | array[voice state object] | Changed voice states in channels the session can view |
1 Omitted when the set would be empty. A participant that left a viewable channel since the previous cycle appears here with channel_id set to null
channels contains only the channels whose last_message_id changed since the previous update for that session, and only channels that session can view. voice_states contains only the voice states whose version advanced.
Messages and reactions
Section titled “Messages and reactions”MESSAGE_CREATE
Section titled “MESSAGE_CREATE”A visible message was created. The payload is the complete message object with the fields below added.
| Field | Type | Description |
|---|---|---|
| channel_type | integer | Channel type of the channel the message was created in |
| nicks? | map[snowflake, string] | Group direct message nicknames, present only for a group direct message that stores at least one |
| mention_here? | boolean | Always true when present, and present only when the message has a here mention |
| guild_id? | snowflake | Guild the channel belongs to |
| member?1 | guild member object | The author’s guild member object, present in a guild channel |
1 The user field is removed from it, and the account is in the message’s author
Message Create alone overrides both the passive filter and the ignored_events list, and the two use different tests. A direct mention, a mention of one of the user’s roles, an everyone mention, or a here mention overrides the passive filter. A direct, everyone, or here mention alone overrides the ignored_events list.
MESSAGE_UPDATE
Section titled “MESSAGE_UPDATE”A visible message changed. The payload is the complete current message object, with no channel_type, nicks, or mention_here. In a guild channel it is extended with guild_id and with member, the author’s guild member object with its user field removed.
Recipients must hold READ_MESSAGE_HISTORY on the channel, or the message must be newer than the guild’s message history cutoff.
MESSAGE_DELETE
Section titled “MESSAGE_DELETE”One visible message was deleted.
| Field | Type | Description |
|---|---|---|
| id | snowflake | The deleted message |
| channel_id | snowflake | Channel the message was in |
| content?1 | ?string | Content the message held before it was deleted |
| author_id?1 | snowflake | Account that wrote the message |
| guild_id? | snowflake | Guild the channel belongs to |
| member?2 | guild member object | The author’s guild member object, present in a guild channel |
1 Both fields are omitted when an instance administrator deleted the message through the Admin API, when FiveCord deleted it after a CSAM report, or when FiveCord deleted it because content moderation blocked a link preview in it, and author_id is also omitted for a message with no author
2 The user field is removed from it, and the whole field is absent when author_id is absent or the author is no longer a member
MESSAGE_DELETE_BULK
Section titled “MESSAGE_DELETE_BULK”Several messages in one channel were deleted together.
| Field | Type | Description |
|---|---|---|
| ids | array[snowflake] | The deleted messages |
| channel_id | snowflake | Channel the messages were in |
| guild_id? | snowflake | Guild the channel belongs to |
MESSAGE_ACK
Section titled “MESSAGE_ACK”The current user’s read state advanced for a channel, usually because another of the account’s sessions read it.
| Field | Type | Description |
|---|---|---|
| channel_id | snowflake | Channel whose read state advanced |
| message_id | snowflake | Message the read state now points at |
| mention_count | integer | Remaining mention count for the channel |
| manual? | boolean | Whether the acknowledgement was explicit |
| version? | string | Read state version as a decimal string |
MESSAGE_REACTION_ADD
Section titled “MESSAGE_REACTION_ADD”A user added a reaction to a message.
| Field | Type | Description |
|---|---|---|
| user_id | snowflake | User that reacted |
| channel_id | snowflake | Channel the message is in |
| message_id | snowflake | Message that was reacted to |
| emoji | reaction emoji object | The emoji |
| guild_id? | snowflake | Guild the channel belongs to |
| member? | guild member object | The reacting user’s guild member object, present in a guild channel |
In a guild channel the session named by the request’s session_id is excluded and that field is removed from the payload. In a private channel the field is delivered as session_id and excludes nobody, so a client MUST tolerate receiving its own reaction back.
Reaction emoji object
Section titled “Reaction emoji object”| Field | Type | Description |
|---|---|---|
| name | string | Unicode emoji, or the custom emoji’s name |
| id? | snowflake | Custom emoji ID, absent for a Unicode emoji |
| animated?1 | boolean | Whether the custom emoji is animated |
1 Present only on the Message Reaction Add that creates the first reaction with that emoji on the message. An addition to an emoji that already has a reactor, a Message Reaction Remove, and a Message Reaction Remove Emoji omit the field
Neither id nor animated is ever null. A Unicode reaction omits both, so a client distinguishes the forms by the presence of id. A client MUST NOT read an absent animated as false.
MESSAGE_REACTION_ADD_MANY
Section titled “MESSAGE_REACTION_ADD_MANY”With the DEBOUNCE_MESSAGE_REACTIONS session flag, private-channel additions are grouped over 650 ms and delivered together. Each window keeps the latest 512 additions. Guild-channel additions always arrive as individual Message Reaction Add events.
| Field | Type | Description |
|---|---|---|
| channel_id1 | snowflake | Channel the message is in |
| message_id1 | snowflake | Message that was reacted to |
| guild_id?1 | snowflake | Guild the channel belongs to |
| reactions | array[reaction addition object] | The merged additions, in arrival order |
1 Every addition in reactions belongs to this message. A window covering several messages produces a separate Dispatch for each
When the window closes holding exactly one addition, FiveCord sends Message Reaction Add to the session. A session without the flag receives one Message Reaction Add per addition.
Reaction addition object
Section titled “Reaction addition object”| Field | Type | Description |
|---|---|---|
| user_id | snowflake | User that reacted |
| emoji | reaction emoji object | The emoji |
| member? | guild member object | The reacting user’s guild member object, present in a guild channel |
MESSAGE_REACTION_REMOVE
Section titled “MESSAGE_REACTION_REMOVE”One user’s reaction was removed from a message.
| Field | Type | Description |
|---|---|---|
| user_id | snowflake | User whose reaction was removed |
| channel_id | snowflake | Channel the message is in |
| message_id | snowflake | Message the reaction was on |
| emoji | reaction emoji object | The emoji |
| guild_id? | snowflake | Guild the channel belongs to |
| member? | guild member object | The user’s guild member object, present in a guild channel |
Exclusion works exactly as it does for Message Reaction Add, so the acting session is dropped in a guild channel and kept in a private one.
With reaction debouncing enabled, an addition removed within the same window produces neither event for that message, user, and emoji.
MESSAGE_REACTION_REMOVE_ALL
Section titled “MESSAGE_REACTION_REMOVE_ALL”Every reaction was removed from a message at once.
| Field | Type | Description |
|---|---|---|
| channel_id | snowflake | Channel the message is in |
| message_id | snowflake | Message whose reactions were cleared |
| guild_id? | snowflake | Guild the channel belongs to |
MESSAGE_REACTION_REMOVE_EMOJI
Section titled “MESSAGE_REACTION_REMOVE_EMOJI”Every reaction using one emoji was removed from a message.
| Field | Type | Description |
|---|---|---|
| channel_id | snowflake | Channel the message is in |
| message_id | snowflake | Message the reactions were on |
| emoji | reaction emoji object | The emoji whose reactions were removed |
| guild_id? | snowflake | Guild the channel belongs to |
TYPING_START
Section titled “TYPING_START”A visible user began typing in a channel.
| Field | Type | Description |
|---|---|---|
| channel_id | snowflake | Channel the user is typing in |
| user_id | snowflake | User that started typing |
| timestamp | integer | Unix seconds when typing started |
| guild_id? | snowflake | Guild the channel belongs to |
| member? | guild member object | The typing user’s guild member object, present in a guild channel |
The typing override set through Lazy Request decides delivery in a guild. With no override, a session receives the event when it is active in the guild or when the guild has 250 members or fewer, so a passive session in a small guild still receives it. A guild that sets the TYPING_EVENTS bit in its disabled operations produces the event for nobody.
CHANNEL_PINS_UPDATE
Section titled “CHANNEL_PINS_UPDATE”A channel’s most recent pin time changed.
| Field | Type | Description |
|---|---|---|
| channel_id | snowflake | Channel whose pins changed |
| last_pin_timestamp | ?ISO8601 timestamp | Time of the most recent pin, null when nothing is pinned |
| guild_id? | snowflake | Guild the channel belongs to |
CHANNEL_PINS_ACK
Section titled “CHANNEL_PINS_ACK”The current user acknowledged a channel’s pins. Every session of the account receives it, including the one that issued the acknowledgement.
| Field | Type | Description |
|---|---|---|
| channel_id | snowflake | Channel whose pins were acknowledged |
| timestamp | ISO8601 timestamp | Time the acknowledgement recorded for the channel |
Voice and calls
Section titled “Voice and calls”VOICE_STATE_UPDATE
Section titled “VOICE_STATE_UPDATE”A participant’s voice state changed. The payload is a voice state object.
Recipients are the sessions that can view the voice channel, passive sessions included. A passive session in a guild with more than 250 members also receives the changed voice states through Passive Updates.
A channel_id of null means the participant left.
Voice state object
Section titled “Voice state object”| Field | Type | Description |
|---|---|---|
| guild_id | ?snowflake | Guild the voice channel belongs to, null in a call |
| channel_id | ?snowflake | Voice channel, null when the participant left |
| user_id | ?snowflake | Participant |
| connection_id | ?string | Voice connection identity |
| session_id | ?string | Gateway session that owns the connection |
| member | ?guild member object | The participant’s guild member object, null in a call |
| mute | boolean | Server mute |
| deaf | boolean | Server deafen |
| self_mute | boolean | Local microphone mute |
| self_deaf | boolean | Local output deafen |
| self_video | boolean | Whether the participant publishes camera video |
| self_stream1 | boolean | Whether the connection advertises a screenshare track |
| is_mobile | boolean | Whether the participant is on a mobile client |
| suppress | boolean | Whether the participant is suppressed |
| viewer_stream_keys | array[string] | Streams this connection is watching |
| e2ee_capable | boolean | Whether the participant’s client supports end-to-end encrypted voice |
| version | integer | Monotonic version of this participant’s voice state |
1 The participant’s client reports this value. In a guild voice channel FiveCord sets it to false when the participant lacks STREAM
The broadcast form has no region_id, server_id, latitude, or longitude.
VOICE_SERVER_UPDATE
Section titled “VOICE_SERVER_UPDATE”The session received or replaced its own voice grant. Delivered to the requesting session alone.
| Field | Type | Description |
|---|---|---|
| token | string | The LiveKit access token this connection presents |
| endpoint | string | The LiveKit signalling URL to connect to, a ws:// or wss:// address |
| connection_id | string | The voice connection the grant covers |
| channel_id | snowflake | The channel the grant covers |
| guild_id?1 | snowflake | The guild the channel belongs to |
| e2ee_key?2 | string | The key material the channel’s end-to-end encryption uses |
1 Present for a guild voice channel and absent for a call, so a client reads the scope from this field
2 Present only when the channel is end-to-end encrypted
FiveCord uses LiveKit for voice media. There is no second voice websocket, no voice opcode set, and no UDP discovery step. A client opens a LiveKit connection to endpoint, presents token there, and speaks the LiveKit protocol from that point on. Voice states the room naming, the participant identity, and the track sources a grant admits.
A grant is issued when a connection opens, when it moves to another channel, and when its region changes. Toggling self_mute, self_video, or self_stream produces no new grant. A call region change reissues one grant to each participant of the call.
ENTRANCE_SOUND_PLAY
Section titled “ENTRANCE_SOUND_PLAY”A participant asked for their entrance sound to play in a voice channel they are already connected to.
| Field | Type | Description |
|---|---|---|
| user_id | snowflake | Participant whose sound plays |
| channel_id | snowflake | Voice channel |
| guild_id | ?snowflake | Guild the channel belongs to, null for a call |
| sound_id | snowflake | Entrance sound |
| hash | string | Content hash of the sound file |
| url | string | URL to fetch the sound from |
| duration_ms | integer | Sound duration in milliseconds |
| content_type | string | MIME type of the sound file |
Recipients are every other account with a voice state in that channel, one Dispatch each and at most one per account. The requesting account never receives its own sound.
CALL_CREATE
Section titled “CALL_CREATE”A private channel call began, or became visible in the session’s initial state.
| Field | Type | Description |
|---|---|---|
| channel_id | snowflake | Channel the call is in |
| message_id | snowflake | Call message that opened the call |
| region | ?string | Voice region serving the call, null until one is chosen |
| ringing | array[snowflake] | Recipients being rung |
| voice_states1 | array[voice state object] | Participants, ordered by participant ID |
| recipients?2 | array[snowflake] | Every recipient of the channel |
| created_at?2 | integer | Unix milliseconds when the call was opened |
1 Entries also include region_id and server_id, which clients MUST ignore
2 Present on initial or recovered call state
Initial call state arrives shortly after Ready. Recovered state can arrive after a lost call connection, whether or not the client received Call Delete.
Recipients are every recipient of the channel, whether or not they joined the call. The same set receives Call Update and Call Delete.
CALL_UPDATE
Section titled “CALL_UPDATE”The ringing set, participant roster, or region of an active call changed. The payload has the same structure as Call Create without recipients and created_at.
An operation with no visible effect produces no Call Update.
CALL_DELETE
Section titled “CALL_DELETE”A call ended, or became unavailable.
| Field | Type | Description |
|---|---|---|
| channel_id | snowflake | Channel the call was in |
| unavailable?1 | boolean | True when the call became unavailable |
1 Absent when the call ended
With unavailable: true, the client MUST keep the call as an unavailable entry. If it becomes available again, a fresh Call Create includes recipients and created_at. Recovery is not guaranteed.
Count response events
Section titled “Count response events”GUILD_COUNTS_UPDATE
Section titled “GUILD_COUNTS_UPDATE”Answers Request Guild Counts for the requesting session.
| Field | Type | Description |
|---|---|---|
| counts | array[guild count entry object] | One entry per guild that answered in time |
| nonce? | string | Echoed when the request supplied a valid nonce |
A guild that is not connected, or that missed its deadline, has no entry in counts.
Guild count entry object
Section titled “Guild count entry object”| Field | Type | Description |
|---|---|---|
| guild_id | snowflake | Guild the counts describe |
| member_count | integer | Total members |
| online_count1 | integer | Online members visible to the requesting account |
1 Counts only the online members that share at least one channel the requesting account can view. An account holding ADMINISTRATOR receives the guild’s whole online count instead, and an account that can view no channel receives 1 when it is itself online and 0 when it is not
CHANNEL_MEMBER_COUNTS_UPDATE
Section titled “CHANNEL_MEMBER_COUNTS_UPDATE”Answers Request Channel Member Counts for the requesting session.
| Field | Type | Description |
|---|---|---|
| counts | array[channel count entry object] | One entry per channel that answered |
| nonce? | string | Echoed when the request supplied a valid nonce |
A channel the session cannot view, and a channel on which it lacks VIEW_CHANNEL_MEMBERS, has no entry in counts.
Channel count entry object
Section titled “Channel count entry object”| Field | Type | Description |
|---|---|---|
| guild_id | snowflake | Guild the channel belongs to |
| channel_id | snowflake | Channel the counts describe |
| member_count | integer | Members that can view the channel |
| online_count | integer | Online members that can view the channel |
Resource representation
Section titled “Resource representation”Every resource object named on this page has the representation defined by the HTTP API. A Dispatch payload with a resource object has the same fields, with the guild-scoped events adding guild_id and the message and reaction events adding member.
These reductions are specific to the Gateway and appear nowhere in the HTTP API. Ready strips user from each relationship and from each guild member and moves those accounts into its users array. The member added to a message event has its own user removed, and the account is in the message’s author. A client MUST resolve those accounts from the surrounding payload.