{"data":{"name":"Rogue Realtime","protocol":"rogue.realtime.v1","transport":"WebSocket","endpoint":"/api/realtime/ws?room=<room_uuid>","authentication":{"subprotocols":["rogue.realtime.v1","rogue.ticket.<one_use_ticket>"],"native_header":"Authorization: Bearer <one_use_ticket>","query_credentials":false,"ticket_seconds":60,"renew_after_seconds":40,"renewal_frame":{"t":"auth","token":"<fresh_ticket>"}},"client_frames":{"$schema":"https://json-schema.org/draft/2020-12/schema","oneOf":[{"type":"object","properties":{"t":{"type":"string","const":"ping"}},"required":["t"],"additionalProperties":false},{"type":"object","properties":{"t":{"type":"string","const":"sync"}},"required":["t"],"additionalProperties":false},{"type":"object","properties":{"t":{"type":"string","const":"auth"},"token":{"type":"string","maxLength":4096}},"required":["t","token"],"additionalProperties":false},{"type":"object","properties":{"t":{"type":"string","const":"presence"},"data":{"type":"object","propertyNames":{"type":"string","maxLength":64},"additionalProperties":{}}},"required":["t","data"],"additionalProperties":false},{"type":"object","properties":{"name":{"type":"string","pattern":"^[A-Za-z0-9_.:-]{1,80}$"},"data":{},"to":{"minItems":1,"maxItems":128,"type":"array","items":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"}},"t":{"type":"string","const":"event"}},"required":["name","data","t"],"additionalProperties":false},{"type":"object","properties":{"operation_id":{"type":"string","format":"uuid","pattern":"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"},"expected_version":{"type":"integer","minimum":0,"maximum":9007199254740991},"operations":{"minItems":1,"maxItems":32,"type":"array","items":{"oneOf":[{"type":"object","properties":{"op":{"type":"string","const":"set"},"key":{"type":"string","pattern":"^[A-Za-z0-9_-][A-Za-z0-9_.:-]{0,127}$"},"value":{}},"required":["op","key","value"],"additionalProperties":false},{"type":"object","properties":{"op":{"type":"string","const":"remove"},"key":{"type":"string","pattern":"^[A-Za-z0-9_-][A-Za-z0-9_.:-]{0,127}$"}},"required":["op","key"],"additionalProperties":false},{"type":"object","properties":{"op":{"type":"string","const":"increment"},"key":{"type":"string","pattern":"^[A-Za-z0-9_-][A-Za-z0-9_.:-]{0,127}$"},"by":{"type":"number"}},"required":["op","key","by"],"additionalProperties":false}]}},"t":{"type":"string","const":"state"}},"required":["operation_id","operations","t"],"additionalProperties":false}]},"server_frames":{"hello":"{t,protocol,connection_id,subject,role,expires_at,state:{version,values},connections:[{connection_id,subject,kind,info,role,presence}],server_time}","snapshot":"{t,state:{version,values},connections,server_time}","presence":"{t,action:'join'|'update',connection:{connection_id,subject,kind,info,role,presence},server_time} or {t,action:'leave',connection_id,server_time}","event":"{t,name,data,from:{subject,kind,connection_id,info},server_time}","state":"{t,operation_id,version,changes:[{key,value}|{key,removed:true}],from,server_time}","ack":"{t,operation_id,version,changes,duplicate?}","authenticated":"{t,expires_at,role}","pong":"{t,server_time}","error":"{t,code,message,operation_id?}"},"close_codes":{"1009":"Frame too large","1011":"Connection failure","4401":"Lease expired or invalid; request a fresh ticket","4403":"Policy changed or connection kicked","4404":"Room deleted","4429":"Room, connection or backpressure limit"},"reconnect":"Fetch a fresh one-use ticket and accept a new full snapshot. Do not replay ephemeral events or uncertain state mutations automatically. State operation receipts are bounded to 600 seconds or 256 entries per room.","ordering":"Frames are ordered per live connection. State commits are serialized per room; compare expected_version for read-modify-write operations. No cross-room ordering or event history.","presence":"Ephemeral per connection, automatically removed at disconnect/lease expiry. A user may have multiple connections.","limits":{"ticket_seconds":60,"renew_after_seconds":40,"guest_session_seconds":86400,"frame_bytes":32768,"presence_bytes":2048,"event_bytes":16384,"info_bytes":1024,"messages_per_second":30,"message_burst":60,"state_operations":32,"value_bytes":16384,"receipt_seconds":600,"receipts":256,"queued_bytes":2097152,"free":{"rooms":10,"connections":16,"state_bytes":262144,"state_keys":256,"fanout_bytes_per_second":1048576},"pro":{"rooms":100,"connections":128,"state_bytes":1048576,"state_keys":2048,"fanout_bytes_per_second":4194304}}}}