Api reference
Protocol
Envelope, handshake, channels, RPC, and state sync format.
Protocol
Envelope
{
"v": 1,
"t": "message.type",
"rid": "optional-request-id",
"room": "optional-room-id",
"p": {}
}v: protocol version (1)t: message type (required)rid: request/response correlation id (optional)room: room id (optional)p: payload (optional)
Handshake
Client first message is always JSON handshake:
{
"v": 1,
"codecs": ["msgpack", "json"],
"project_id": "demo-project",
"token": "...",
"session_id": "optional"
}Server does:
- protocol version validation
- auth check (based on auth mode)
- codec negotiation (
msgpackpreferred if both support) handshake.okresponse
Handshake flow
Channels
Logical channels over WebSocket:
reliable(default)unreliable(drop-allowed under pressure)
State Sync Messages
state.snapshotfull state withseqandchecksumstate.patchincremental ops (set/del)state.ackclient ackstate.resyncclient asks fresh snapshot
Patch payload:
{
"seq": 43,
"ops": [
{ "op": "set", "path": "/counter", "value": 4 },
{ "op": "del", "path": "/foo" }
]
}Room message payload contract
When sending custom room messages (t = "room.message"), payload shape is:
{
"type": "player.move",
"data": { "x": 10, "y": 4, "seq": 18 }
}Binary variant (t = "room.message.bytes") uses:
{
"type": "voice.chunk",
"data_b64": "..."
}Common call types
- room:
room.join_or_create,room.leave,room.list,room.message - matchmaking:
matchmaking.enqueue,matchmaking.dequeue - state:
state.snapshot,state.patch,state.ack,state.resync - rpc:
rpc.request,rpc.response
Unknown rid is rejected by RPC tracker.
Typed Envelope Validation
const : unknown = { : 1, : 'state.patch', : { : 10, : [] } };
if (()) {
.(.);
}