Wormhole Gateway

The Wormhole Gateway is Local Universe's WebSocket protocol for receiving real-time events — messages, presence updates, system changes, and more — without polling the REST API.

Connecting

Connect to the Wormhole Gateway via WebSocket:

wss://wormhole.localuniverse.io/v1

Payload Structure

All gateway messages follow this structure:

{
  "op": 0,
  "d": {},
  "s": 1,
  "t": "MESSAGE_CREATE"
}
  • Name
    op
    Type
    integer
    Description

    The opcode for this payload.

  • Name
    d
    Type
    any
    Description

    The event data. Structure varies by opcode/event type.

  • Name
    s
    Type
    integer
    Description

    Sequence number for dispatch events (op 0). Used for resuming.

  • Name
    t
    Type
    string
    Description

    Event name for dispatch events (op 0). Null for other opcodes.


Opcodes

OpcodeNameDirectionDescription
0DISPATCHReceiveDispatches an event (see Gateway Events)
1HEARTBEATSendSent every interval to maintain the connection
2IDENTIFYSendStarts a new session by providing an auth token
3PRESENCE_UPDATESendUpdate the client's presence status
5WARP_STATE_UPDATESendUpdate the client's warp state (enter/leave planet)
9INVALID_SESSIONReceiveThe session is invalid; reconnect and re-identify
10HELLOReceiveSent immediately after connecting with heartbeat interval
11HEARTBEAT_ACKReceiveAcknowledges a heartbeat was received

Connection Lifecycle

1. Connect and receive HELLO

After connecting, the gateway immediately sends a HELLO payload containing the heartbeat interval:

{
  "op": 10,
  "d": {
    "heartbeat_interval": 45000
  }
}

2. Send IDENTIFY

After receiving HELLO, send an IDENTIFY payload with your auth token:

{
  "op": 2,
  "d": {
    "token": "Bearer eyJhbGciOiJIUzI1NiIs..."
  }
}

3. Receive READY

The gateway responds with a READY dispatch event containing your session information:

{
  "op": 0,
  "t": "READY",
  "s": 1,
  "d": {
    "session_id": "abc123",
    "user": { },
    "presences": [],
    "warp_states": [],
    "systems": [],
    "equipment": null,
    "inventory": [],
    "read_states": []
  }
}

4. Receive initial state

After READY, the gateway dispatches individual events to populate initial state:

  • CHANNEL_CREATE — one per DM/group DM channel the user belongs to
  • SYSTEM_CREATE — one per system the user is a member of (includes channels, members, roles, presences, and warp states)

5. Receive live events

From this point on, the gateway dispatches events as they happen in real time. See Gateway Events for the full list.


Heartbeating

To keep the connection alive, send a HEARTBEAT (op 1) every heartbeat_interval milliseconds (default: 45000ms / 45 seconds).

{
  "op": 1,
  "d": null
}

The gateway will respond with a HEARTBEAT_ACK (op 11). If you don't receive an ACK before your next heartbeat is due, the connection may be zombied — close it and reconnect.


Updating Presence

Send a PRESENCE_UPDATE (op 3) to change your online status:

{
  "op": 3,
  "d": {
    "status": "online",
    "custom_status": "Building something cool"
  }
}
  • Name
    status
    Type
    string
    Description

    One of: online, away, dnd, invisible, offline.

  • Name
    custom_status
    Type
    string?
    Description

    Optional custom status text. Set to null to clear.


Warp State

Send a WARP_STATE_UPDATE (op 5) to enter or leave a planet channel:

{
  "op": 5,
  "d": {
    "channel_id": "1344387816333352652"
  }
}

Set channel_id to null to leave the current planet. When entering a planet, the gateway will respond with a WARP_SERVER_UPDATE dispatch event containing connection details for the voice/game server:

{
  "op": 0,
  "t": "WARP_SERVER_UPDATE",
  "d": {
    "token": "voice_token_here",
    "channel_id": "1344387816333352652",
    "endpoint": "wss://voice.localuniverse.io",
    "session_id": "abc123"
  }
}

Invalid Session

If your session becomes invalid, the gateway sends an INVALID_SESSION (op 9). Close the connection and start a new one with a fresh IDENTIFY.

{
  "op": 9,
  "d": {
    "message": "Session expired"
  }
}

Was this page helpful?