WebSocket API Reference
Low-level WebSocket protocol reference for NoLag real-time communication. All messages use MessagePack binary encoding.
Connection
| Property | Value |
|---|---|
| Endpoint | wss://broker.nolag.app/ws |
| Encoding | MessagePack binary frames |
| Heartbeat | Empty binary packet (0 bytes) every 30 seconds, both directions |
Authentication
The first message sent after connecting must be an authentication request. The server enforces a 10-second timeout for the auth response. If no valid auth message is received within that window, the connection is closed.
{
"type": "auth",
"token": "at_live_<key_id>.<secret>",
"reconnect": false,
"projectId": "..."
}| Field | Type | Description |
|---|---|---|
type | string | Always "auth" |
token | string | Access token in the format at_live_<key_id>.<secret> |
reconnect | boolean | Set to true to trigger subscription restoration after a reconnect |
projectId | string | The project identifier |
Client to Server Messages
1. subscribe
Subscribe to a topic to begin receiving messages.
{
"type": "subscribe",
"topic": "app/room/topic",
"qos": 1,
"filters": ["f1"],
"loadBalance": false,
"loadBalanceGroup": "group-1"
}| Field | Type | Required | Description |
|---|---|---|---|
type | string | Yes | Always "subscribe" |
topic | string | Yes | Human-readable slug format: app/room/topic |
qos | number | No | Quality of Service level: 0, 1 (default), or 2 |
filters | string[] | No | Filter array. Max 100 entries. Characters /, #, + are not allowed. |
loadBalance | boolean | No | Enable load balancing to distribute messages across clients |
loadBalanceGroup | string | No | Group name for load balancing |
2. unsubscribe
Stop receiving messages from a topic.
{
"type": "unsubscribe",
"topic": "app/room/topic"
}3. publish
Publish a message to a topic.
{
"type": "publish",
"topic": "app/room/topic",
"data": { "your": "payload" },
"qos": 1,
"echo": true,
"filter": "f1"
}| Field | Type | Required | Description |
|---|---|---|---|
type | string | Yes | Always "publish" |
topic | string | Yes | Target topic in slug format |
data | object | Yes | The message payload |
qos | number | No | Quality of Service level: 0, 1 (default), or 2 |
echo | boolean | No | Set to false to prevent the message from being delivered back to the sender |
filter | string | No | Route the message only to subscribers whose filter set includes this value |
4. setFilters
Replace the entire filter set for a subscription. Sending an empty array acts as a wildcard, meaning all messages will be received.
{
"type": "setFilters",
"topic": "app/room/topic",
"filters": ["f1"]
}5. presence
Announce or update presence data for a room.
{
"type": "presence",
"roomId": "room-slug",
"data": { "status": "online" }
}6. getPresence
Request the current presence list for a room.
{
"type": "getPresence",
"roomId": "room-slug"
}7. ack
Acknowledge receipt of a single message. Required when the server sends a message with requiresAck: true.
{
"type": "ack",
"msgId": "uuid"
}8. batchAck
Acknowledge receipt of multiple messages at once. Required when the server sends messages with requiresAck: true.
{
"type": "batchAck",
"msgIds": ["id1", "id2"]
}9. lobbySubscribe
Subscribe to a lobby to receive aggregated presence events across multiple rooms.
{
"type": "lobbySubscribe",
"lobbyId": "lobby-slug"
}10. lobbyUnsubscribe
Unsubscribe from a lobby.
{
"type": "lobbyUnsubscribe",
"lobbyId": "lobby-slug"
}11. getLobbyPresence
Request the current presence data for an entire lobby.
{
"type": "getLobbyPresence",
"lobbyId": "lobby-slug"
}Server to Client Messages
1. message
Delivers a published message to the client.
{
"type": "message",
"topic": "...",
"data": { "your": "payload" },
"msgId": "uuid",
"requiresAck": true,
"isReplay": false,
"filter": "f1"
}| Field | Type | Description |
|---|---|---|
msgId | string | Present when message logging is enabled on the topic |
requiresAck | boolean | When true, the client must respond with an ack or batchAck |
isReplay | boolean | Set to true when the message is being replayed after a reconnect |
filter | string | The filter value the message was published with |
2. subscribed
Confirms a successful subscription.
{
"type": "subscribed",
"topic": "...",
"loadBalance": false
}3. unsubscribed
Confirms a successful unsubscription.
{
"type": "unsubscribed",
"topic": "..."
}4. filtersUpdated
Confirms that the filter set for a subscription has been updated.
{
"type": "filtersUpdated",
"topic": "...",
"filters": ["f1"]
}5. presence
Notifies the client of a presence change in a room (join, leave, or update).
{
"type": "presence",
"event": "join",
"data": {
"actorTokenId": "...",
"presence": { "status": "online" },
"joinedAt": 1716000000
}
}The event field is one of: "join", "leave", or "update".
6. presenceList
Returns the full list of present actors in a room. Sent in response to a getPresence request.
{
"type": "presenceList",
"roomId": "...",
"data": [
{ "actorTokenId": "...", "presence": { "status": "online" }, "joinedAt": 1716000000 }
]
}7. lobbySubscribed
Confirms a lobby subscription and includes the current presence snapshot.
{
"type": "lobbySubscribed",
"lobbyId": "...",
"presence": {
"room1": {
"actor1": { "status": "online" }
}
}
}8. lobbyUnsubscribed
Confirms a lobby unsubscription.
{
"type": "lobbyUnsubscribed",
"lobbyId": "..."
}9. lobbyPresence
Notifies the client of a presence event within a lobby.
{
"type": "lobbyPresence",
"event": "join",
"lobbyId": "...",
"roomId": "...",
"actorId": "...",
"data": { "status": "online" }
}10. lobbyPresenceList
Returns the full presence data for a lobby. Sent in response to a getLobbyPresence request.
{
"type": "lobbyPresenceList",
"lobbyId": "...",
"presence": { "room1": { "actor1": { "status": "online" } } }
}11. replayStart
Indicates the beginning of a message replay sequence after reconnection.
{
"type": "replayStart",
"count": 247,
"oldestTimestamp": "...",
"newestTimestamp": "..."
}12. replayEnd
Indicates the end of a message replay sequence.
{
"type": "replayEnd",
"replayed": 247
}13. hydration
Sent automatically on subscribe when a webhook is configured for the topic. Contains initial state data.
{
"type": "hydration",
"topic": "...",
"data": { "initialState": "..." }
}14. error
Reports an error to the client.
{
"type": "error",
"error": "rate_limit_exceeded",
"code": 42910,
"topic": "..."
}15. disconnect
Informs the client that the server is closing the connection, along with the reason.
{
"type": "disconnect",
"reason": "token_invalid"
}QoS Levels
| Level | Name | Description |
|---|---|---|
0 | At most once | Fire and forget. No delivery guarantee. |
1 | At least once | Acknowledged delivery. Messages may be delivered more than once. |
2 | Exactly once | Guaranteed single delivery. |
Reconnection
When a client reconnects after a disconnect, it should send the auth message with reconnect: true. The server will restore previous subscriptions and replay any messages that were missed during the disconnect.
Reconnection flow
- Client reconnects and sends
authwithreconnect: true. - Server responds with
restoredSubscriptions, an array of objects containing:pattern,loadBalance,loadBalanceGroup, andfilters. - Server sends a
replayStartmessage with the total count and timestamp range. - Server delivers all missed messages (with
isReplay: true). - Server sends a
replayEndmessage confirming how many messages were replayed.
Backoff strategy
| Parameter | Value |
|---|---|
| Base delay | 5 seconds |
| Max delay | 30 seconds |
| Multiplier | 1.5x |
Each failed reconnection attempt increases the delay by the multiplier, up to the maximum. For example: 5s, 7.5s, 11.25s, 16.875s, 25.3s, 30s, 30s, ...