Skip to main content
Gateway events are sent via Dispatch messages (opcode 0). Each event has a type (t field) and contains specific data in the d field.

Event Structure

All events follow this format:
{
  "op": 0,
  "t": "EVENT_NAME",
  "s": 42,
  "d": {
    // Event-specific data
  }
}

Event Categories

Session

READY, RESUMED

Messages

MESSAGE_CREATE, MESSAGE_UPDATE, MESSAGE_DELETE

Guilds

GUILD_CREATE, GUILD_UPDATE, GUILD_DELETE

Channels

CHANNEL_CREATE, CHANNEL_UPDATE, CHANNEL_DELETE

Members

GUILD_MEMBER_UPDATE, GUILD_MEMBER_ADD, GUILD_MEMBER_REMOVE

Reactions

MESSAGE_REACTION_ADD, MESSAGE_REACTION_REMOVE

Voice

VOICE_STATE_UPDATE, VOICE_SERVER_UPDATE

Presence

PRESENCE_UPDATE

Other

TYPING_START, RELATIONSHIP_ADD, and more

Session Events

READY

Sent after successful authentication. Contains initial state data. Example:
{
  "op": 0,
  "t": "READY",
  "s": 1,
  "d": {
    "v": 1,
    "user": {
      "id": "1234567890",
      "username": "fluxer_user",
      "discriminator": "0001"
    },
    "guilds": [
      {
        "id": "9876543210",
        "name": "My Guild",
        "unavailable": false
      }
    ],
    "session_id": "abc123def456",
    "resume_gateway_url": "wss://gateway.fluxer.example",
    "relationships": [],
    "private_channels": []
  }
}
Key Fields:
FieldTypeDescription
vintegerGateway version (1)
userobjectThe authenticated user
guildsarrayGuilds the user is in
session_idstringSession ID for resuming
resume_gateway_urlstringURL to use when resuming
relationshipsarrayUser relationships (friends, blocked)
private_channelsarrayDM and group DM channels
Store session_id to enable session resumption after disconnects.

RESUMED

Sent after successfully resuming a session. Example:
{
  "op": 0,
  "t": "RESUMED",
  "s": 45,
  "d": null
}
After this event, the Gateway continues sending new events normally. Implementation: gateway_handler.erl:handle_resume_success/5

Message Events

MESSAGE_CREATE

A message was created. Example:
{
  "op": 0,
  "t": "MESSAGE_CREATE",
  "s": 42,
  "d": {
    "id": "1234567890",
    "channel_id": "9876543210",
    "guild_id": "1111111111",
    "author": {
      "id": "2222222222",
      "username": "sender",
      "discriminator": "0001"
    },
    "content": "Hello, world!",
    "timestamp": "2026-03-04T12:00:00.000Z",
    "edited_timestamp": null,
    "mentions": [],
    "attachments": []
  }
}

MESSAGE_UPDATE

A message was edited. Example:
{
  "op": 0,
  "t": "MESSAGE_UPDATE",
  "s": 43,
  "d": {
    "id": "1234567890",
    "channel_id": "9876543210",
    "content": "Edited content",
    "edited_timestamp": "2026-03-04T12:01:00.000Z"
  }
}
MESSAGE_UPDATE may only include changed fields, not the complete message object.

MESSAGE_DELETE

A message was deleted. Example:
{
  "op": 0,
  "t": "MESSAGE_DELETE",
  "s": 44,
  "d": {
    "id": "1234567890",
    "channel_id": "9876543210",
    "guild_id": "1111111111"
  }
}

MESSAGE_DELETE_BULK

Multiple messages were deleted at once. Example:
{
  "op": 0,
  "t": "MESSAGE_DELETE_BULK",
  "s": 45,
  "d": {
    "ids": ["1234567890", "1234567891", "1234567892"],
    "channel_id": "9876543210",
    "guild_id": "1111111111"
  }
}

Reaction Events

MESSAGE_REACTION_ADD

A reaction was added to a message. Example:
{
  "op": 0,
  "t": "MESSAGE_REACTION_ADD",
  "s": 46,
  "d": {
    "user_id": "2222222222",
    "channel_id": "9876543210",
    "message_id": "1234567890",
    "guild_id": "1111111111",
    "emoji": {
      "id": null,
      "name": "👍"
    },
    "member": {
      "user": { /* user object */ },
      "roles": ["3333333333"]
    }
  }
}
The Gateway may buffer rapid reactions and send them as MESSAGE_REACTION_ADD_MANY instead.

MESSAGE_REACTION_ADD_MANY

Multiple reactions were added (batched by Gateway). Example:
{
  "op": 0,
  "t": "MESSAGE_REACTION_ADD_MANY",
  "s": 47,
  "d": {
    "channel_id": "9876543210",
    "message_id": "1234567890",
    "guild_id": "1111111111",
    "reactions": [
      {
        "user_id": "2222222222",
        "emoji": { "id": null, "name": "👍" }
      },
      {
        "user_id": "3333333333",
        "emoji": { "id": null, "name": "❤️" }
      }
    ]
  }
}
Implementation: session_dispatch.erl:dispatch_reaction_add_many/2

MESSAGE_REACTION_REMOVE

A reaction was removed from a message. Example:
{
  "op": 0,
  "t": "MESSAGE_REACTION_REMOVE",
  "s": 48,
  "d": {
    "user_id": "2222222222",
    "channel_id": "9876543210",
    "message_id": "1234567890",
    "guild_id": "1111111111",
    "emoji": {
      "id": null,
      "name": "👍"
    }
  }
}

Guild Events

GUILD_CREATE

Sent when joining a guild or during initial Ready sequence. Example:
{
  "op": 0,
  "t": "GUILD_CREATE",
  "s": 10,
  "d": {
    "id": "1111111111",
    "name": "My Guild",
    "owner_id": "2222222222",
    "channels": [ /* array of channels */ ],
    "members": [ /* array of members */ ],
    "roles": [ /* array of roles */ ]
  }
}

GUILD_UPDATE

Guild properties were updated. Example:
{
  "op": 0,
  "t": "GUILD_UPDATE",
  "s": 50,
  "d": {
    "id": "1111111111",
    "name": "Updated Guild Name",
    "icon": "new_icon_hash"
  }
}

GUILD_DELETE

You left a guild or the guild became unavailable. Example:
{
  "op": 0,
  "t": "GUILD_DELETE",
  "s": 51,
  "d": {
    "id": "1111111111",
    "unavailable": false
  }
}
Fields:
FieldTypeDescription
idsnowflakeGuild ID
unavailablebooleantrue if outage, false if kicked/left

Channel Events

CHANNEL_CREATE

A channel was created. Example:
{
  "op": 0,
  "t": "CHANNEL_CREATE",
  "s": 52,
  "d": {
    "id": "9876543210",
    "type": 0,
    "guild_id": "1111111111",
    "name": "new-channel",
    "position": 1
  }
}
Implementation: session_dispatch.erl:update_channels_map/3

CHANNEL_UPDATE

A channel was updated. Example:
{
  "op": 0,
  "t": "CHANNEL_UPDATE",
  "s": 53,
  "d": {
    "id": "9876543210",
    "name": "renamed-channel",
    "topic": "New topic"
  }
}

CHANNEL_DELETE

A channel was deleted. Example:
{
  "op": 0,
  "t": "CHANNEL_DELETE",
  "s": 54,
  "d": {
    "id": "9876543210",
    "type": 0,
    "guild_id": "1111111111"
  }
}

Member Events

GUILD_MEMBER_ADD

A user joined a guild. Example:
{
  "op": 0,
  "t": "GUILD_MEMBER_ADD",
  "s": 55,
  "d": {
    "guild_id": "1111111111",
    "user": {
      "id": "4444444444",
      "username": "newmember"
    },
    "roles": [],
    "joined_at": "2026-03-04T12:00:00.000Z"
  }
}

GUILD_MEMBER_UPDATE

A guild member was updated (roles, nickname, etc.). Example:
{
  "op": 0,
  "t": "GUILD_MEMBER_UPDATE",
  "s": 56,
  "d": {
    "guild_id": "1111111111",
    "user": {
      "id": "4444444444"
    },
    "roles": ["5555555555"],
    "nick": "NewNickname"
  }
}
Implementation: guild_presence.erl (dispatches member updates on presence changes)

GUILD_MEMBER_REMOVE

A user left or was removed from a guild. Example:
{
  "op": 0,
  "t": "GUILD_MEMBER_REMOVE",
  "s": 57,
  "d": {
    "guild_id": "1111111111",
    "user": {
      "id": "4444444444"
    }
  }
}

Voice Events

VOICE_STATE_UPDATE

A user’s voice state changed. Example:
{
  "op": 0,
  "t": "VOICE_STATE_UPDATE",
  "s": 58,
  "d": {
    "guild_id": "1111111111",
    "channel_id": "9876543210",
    "user_id": "2222222222",
    "session_id": "voice_session_123",
    "self_mute": false,
    "self_deaf": false,
    "mute": false,
    "deaf": false
  }
}

VOICE_SERVER_UPDATE

Voice server information for connecting. Example:
{
  "op": 0,
  "t": "VOICE_SERVER_UPDATE",
  "s": 59,
  "d": {
    "token": "voice_token_abc123",
    "guild_id": "1111111111",
    "endpoint": "voice.fluxer.example"
  }
}

Presence Events

PRESENCE_UPDATE

A user’s presence changed (status, activity, etc.). Example:
{
  "op": 0,
  "t": "PRESENCE_UPDATE",
  "s": 60,
  "d": {
    "user": {
      "id": "2222222222"
    },
    "guild_id": "1111111111",
    "status": "idle",
    "activities": [],
    "client_status": {
      "desktop": "idle"
    }
  }
}

Presence Buffering

The Gateway may buffer presence updates for users who are not:
  • In a guild channel
  • Friends (relationship type 1 or 3)
  • In a group DM with you
Buffered presences are flushed when you add them as a friend. Implementation: session_dispatch.erl:should_buffer_presence/3

Relationship Events

RELATIONSHIP_ADD

A relationship was created (friend request, friend, blocked). Example:
{
  "op": 0,
  "t": "RELATIONSHIP_ADD",
  "s": 61,
  "d": {
    "id": "3333333333",
    "type": 1,
    "user": {
      "id": "3333333333",
      "username": "newfriend"
    }
  }
}
Relationship Types:
TypeDescription
0None
1Friend
2Blocked
3Incoming friend request
4Outgoing friend request

RELATIONSHIP_UPDATE

A relationship was updated. Example:
{
  "op": 0,
  "t": "RELATIONSHIP_UPDATE",
  "s": 62,
  "d": {
    "id": "3333333333",
    "type": 1
  }
}

RELATIONSHIP_REMOVE

A relationship was removed. Example:
{
  "op": 0,
  "t": "RELATIONSHIP_REMOVE",
  "s": 63,
  "d": {
    "id": "3333333333",
    "type": 0
  }
}

Other Events

TYPING_START

A user started typing. Example:
{
  "op": 0,
  "t": "TYPING_START",
  "s": 64,
  "d": {
    "channel_id": "9876543210",
    "user_id": "2222222222",
    "timestamp": 1709553600
  }
}
You can filter out TYPING_START events by including "TYPING_START" in the ignored_events array during Identify.

CHANNEL_RECIPIENT_ADD

A user was added to a group DM. Example:
{
  "op": 0,
  "t": "CHANNEL_RECIPIENT_ADD",
  "s": 65,
  "d": {
    "channel_id": "9876543210",
    "user": {
      "id": "4444444444",
      "username": "newuser"
    }
  }
}
Implementation: session_dispatch.erl:update_recipient_membership/3

CHANNEL_RECIPIENT_REMOVE

A user was removed from a group DM. Example:
{
  "op": 0,
  "t": "CHANNEL_RECIPIENT_REMOVE",
  "s": 66,
  "d": {
    "channel_id": "9876543210",
    "user": {
      "id": "4444444444"
    }
  }
}

Event Filtering

You can filter unwanted events during Identify:
{
  "op": 2,
  "d": {
    "token": "...",
    "properties": { /* ... */ },
    "ignored_events": [
      "TYPING_START",
      "PRESENCE_UPDATE"
    ]
  }
}
Filtered events will not be sent to your client, reducing bandwidth. Implementation: session_dispatch.erl:should_ignore_event/2

Event Normalization

Event names are normalized to uppercase. The Gateway accepts both:
  • Uppercase: "MESSAGE_CREATE"
  • Lowercase: "message_create"
Both are converted to the atom message_create internally. Implementation: event_atoms.erl:normalize/1

Build docs developers (and LLMs) love