Wire
Binary WebSocket. Each frame is
[type_byte][msgpack_payload]. One byte selects the
message; the body is whatever the payload decodes to.
Frame codes
| Code | Dir | Message |
|---|---|---|
| 0x01 | C → S | INIT_REQUEST |
| 0x02 | S → C | INIT_RESPONSE |
| 0x03 | C → S | SPIN_REQUEST |
| 0x04 | S → C | SPIN_RESPONSE |
| 0x05 | C → S | OPEN_REQUEST |
| 0x06 | S → C | OPEN_RESPONSE |
| 0x07 | C → S | STEP_REQUEST |
| 0x08 | S → C | STEP_RESPONSE |
| 0x09 | C → S | CLOSE_REQUEST |
| 0x0a | S → C | CLOSE_RESPONSE |
| 0x0b | C → S | PROMO_ACCEPT |
| 0x0c | S → C | PROMO_ACCEPT_RESPONSE |
| 0xfe | C → S | PING |
| 0xfd | S → C | PONG |
| 0xff | S → C | ERROR |
Request payloads
init: { sid }
spin: { sid?, mode?, betIndex?, priceMultiplier?, params? }
open: { sid?, mode?, betIndex?, priceMultiplier?, params? }
step: { sid?, action: { type, ... } }
close: { sid? }
promo: { sid?, accept: bool } Response payloads
init: { sid, balance, currency, currencyDecimals, allowedBets, defaultBetIndex,
modes: [{ id, label?, stakeMultiplier, declaredRtp? }],
promo?: { id, bet, remaining, total?, label?, validTo? },
resume?: { roundId, modeId, bet, ops, actionLog, awaiting?, openedAt? },
demo? }
spin: { roundId, ops, balance, bet, win, multiplier, type,
promo?: { remaining, done } }
open: { roundId, ops, balance, bet, awaiting? }
step: { ops, awaiting? } // no money moves
close: { roundId, ops, balance, win, multiplier, type }
promo: { ok, promo?: { id, bet, remaining, total? } }
error: { code, message } // see /errors Awaiting hint
awaiting is the pause signal on a complex round.
Present after open / step → the orchestrator stays open and the
client must send STEP. Absent → the round is terminal and the
client must send CLOSE.
awaiting = {
type: "pick_cell", // enforced; mismatched STEP → INVALID_ACTION
options?: [0, 1, 2, ... 24], // optional whitelist
deadline?: 30000, // optional ms before autoclose
prompt?: "Pick a tile",
} Ops
ops is an opaque list of visual instructions. Math
authors define the shape; the client replays them. The
orchestrator never inspects ops — it forwards them verbatim.