Initial Connection
1. Establish WebSocket Connection
Connect to the Gateway URL with required query parameters:2. Receive Hello
Immediately after connecting, the Gateway sends a Hello message (opcode 10):The
heartbeat_interval is always 41,250 milliseconds (41.25 seconds) in the current implementation.3. Start Heartbeating
Upon receiving Hello, start a timer to send heartbeats. The server also initiates heartbeat checks everyheartbeat_interval / 3 (~13.75s).
Heartbeat Mechanism
Heartbeats keep the connection alive and allow the Gateway to detect dead connections.Server-Initiated Heartbeat
The Gateway sends heartbeat requests (opcode 1) approximately every 13.75 seconds:Client Response
Clients must respond with their current sequence number:Heartbeat Validation
The Gateway validates heartbeat sequence numbers:nullis always accepted- Integer sequence numbers are verified against the session’s current state
- Invalid sequences result in close code 4007 (Invalid Sequence)
gateway_handler.erl:verify_heartbeat_ack/2
Authentication
Identify (New Session)
To start a new session, send an Identify message (opcode 2):Identify Payload Fields
| Field | Type | Required | Description |
|---|---|---|---|
token | string | Yes | Authentication token |
properties | object | Yes | Client properties object |
properties.os | string | Yes | Operating system name |
properties.browser | string | Yes | Browser/client name |
properties.device | string | Yes | Device name |
presence | object | No | Initial presence state |
ignored_events | array | No | Event names to not receive |
flags | integer | No | Connection flags (default: 0) |
initial_guild_id | snowflake | No | Guild to prioritize loading |
Event names in
ignored_events are normalized to uppercase (e.g., "typing_start" becomes "TYPING_START").Identify Responses
Success: Receive a Ready event (opcode 0, event READY) Failure cases:- Close 4004: Authentication failed (invalid token)
- Close 4005: Already authenticated (sent Identify twice)
- Opcode 9: Invalid session (rate limited or other issue)
gateway_handler.erl:handle_identify/3
Ready Event
After successful authentication, the Gateway sends a Ready event:Store the
session_id to resume this session if the connection drops.Session Resumption
If your connection drops unexpectedly, you can resume the session to avoid re-receiving events.Resume Request
Send a Resume message (opcode 6) instead of Identify:Resume Payload
| Field | Type | Description |
|---|---|---|
token | string | Same token used for Identify |
session_id | string | Session ID from Ready event |
seq | integer | Last sequence number received |
Resume Responses
Success:- Gateway replays all missed events since
seq - Gateway sends a RESUMED event:
- Invalid Session
- Invalid Sequence
- Invalid Token
gateway_handler.erl:handle_resume/2
Event Replay
When resuming successfully, the Gateway:- Retrieves all events between
seqand current sequence - Dispatches them in order to the client
- Sends the RESUMED event
- Continues with new events
Presence Updates
Update your presence while connected using opcode 3:Status Values
| Status | Description |
|---|---|
online | Available and active |
idle | Away from keyboard |
dnd | Do Not Disturb |
invisible | Appear offline |
offline | Converted to invisible by Gateway |
The Gateway automatically converts
"offline" status to "invisible" (see gateway_handler.erl:adjust_status/1).Voice State Updates
Join or leave voice channels with opcode 4:channel_id to null.
Voice Update Rate Limiting
The queue is processed automatically every 100ms. If the queue exceeds 64 entries, the oldest entry is dropped. Implementation:gateway_handler.erl:handle_voice_state_update/3
Disconnection
Graceful Closure
Clients can close the connection using standard WebSocket close frames. The Gateway will:- Preserve the session for potential resumption
- Clean up compression contexts
- Update connection metrics
Server-Initiated Closure
The Gateway may close connections for various reasons (see Close Codes):Connection State Machine
Best Practices
Implement Exponential Backoff
Implement Exponential Backoff
When reconnecting after errors, use exponential backoff:
- First retry: 1-2 seconds
- Second retry: 2-4 seconds
- Third retry: 4-8 seconds
- Max: 60 seconds
Store Session State
Store Session State
Always persist:
- Session ID from Ready
- Last sequence number received
- Resume Gateway URL
Monitor Heartbeat Health
Monitor Heartbeat Health
Track heartbeat round-trip time and failures:
- Warn if RTT exceeds 10 seconds
- Reconnect if 3 consecutive failures
- The Gateway tracks this server-side too
Handle Rate Limits Gracefully
Handle Rate Limits Gracefully
If you receive close code 4008:
- Do NOT immediately reconnect
- Wait at least 60 seconds
- Review your event sending rate
Implementation References
Key source files for connection lifecycle:gateway_handler.erl- Main WebSocket handlersession_manager.erl- Session creation and lookupsession.erl- Session state managementconstants.erl- Timing and limit constants