Protocol Reference

Every client-to-server message is a JSON text frame with a required method field.

Invalid JSON, missing required fields, or unknown methods may disconnect the client with a structured error.

Client messages

subscribe

Subscribes the client to a coin or stream.

Subscribe to order book diffs for a coin:

{"method":"subscribe","coin":"BTC"}

The coin value must be a non-empty string.

Subscribing twice to the same coin is safe and idempotent.

Subscribe to mempool transactions:

{"method":"subscribe","stream":"mempool"}

Currently, the only valid stream value is mempool.

If the mempool stream is not enabled on the server, the server replies with a non-disconnecting mempool_unavailable error.

unsubscribe

Unsubscribes from a coin or stream.

{"method":"unsubscribe","coin":"BTC"}
{"method":"unsubscribe","stream":"mempool"}

esp

Upgrades the connection to binary protocol mode.

{"method":"esp","version":1}

The version field must match the server binary protocol version.

Current binary protocol version: 1.

If the version does not match, the client is disconnected with the version_mismatch error.

prime

Enables additional binary streams after esp.

{"method":"prime"}

After prime, the client can receive:

  • Ping frames
  • Timing metrics
  • Server error events

prime must be sent after esp.

Calling prime before esp disconnects the client with the not_esp error.

unprime

Disables the additional prime streams.

{"method":"unprime"}

Like prime, this must be called after esp.

JSON mode

JSON mode is the default mode before esp is sent.

In this mode, server-to-client frames are text frames containing newline-delimited JSON order book diffs.

A single WebSocket frame may contain multiple JSON lines separated by \n.

Example:

{"coin":"BTC","time":"...","side":"A","px":"72223.0","sz":"0","oid":123,"user":"0x..."}
{"coin":"BTC","time":"...","side":"B","px":"72182.0","sz":"0.3","oid":456,"user":"0x..."}

JSON mode is intended for quick testing and inspection.

For production integrations, use binary mode.

Binary mode

After esp, all server-to-client data frames are binary WebSocket frames.

The first byte of every frame is a tag that identifies the frame type.

All multi-byte integers are little-endian.

TagTypeSizeWhen it is received
0Block33 bytesAfter every block applied by the node
1TinyOrderVariableFor each order book diff on a subscribed coin
2MetricVariableAfter every block, only after prime
3Ping9 bytesRoughly every 5 ms, only after prime
4MempoolTxVariableFor each mempool transaction, when subscribed

Block frame

Tag:

0

Size:

33 bytes

Block frames are emitted after every block applied by the node.

Layout:

offset  size  field              notes
────────────────────────────────────────────────────────────
0       1     tag                Always 0
1       8     ts_ms              Block timestamp, ms since UNIX epoch
9       8     height             Block height
17      8     wall_ts_us         Node-local wall clock, µs since epoch
25      8     apply_duration_us  Time spent applying the block

Node-side block latency can be calculated as:

wall_ts_us - (ts_ms * 1000)

TinyOrder frame

Tag:

1

Size:

Variable

TinyOrder frames are emitted for order book diffs on subscribed coins.

All strings are length-prefixed with a single u8 byte.

The following fields are encoded as UTF-8 decimal strings and should be parsed as text:

  • coin
  • price
  • qty
  • user

Layout:

offset  size       field
────────────────────────────────────────────────────────────
0       1          tag = 1
1       8          oid, u64 little-endian
9       1          is_buyer, 1 = buy, 0 = sell
10      1          status, 1 = open, 0 = canceled
11      1 + N      coin, for example "BTC"
...     1 + N      price, for example "72223.0"
...     1 + N      qty, for example "0.3"
...     1 + N      user, hex address

Both opens and cancels arrive as TinyOrder frames.

A full cancel is represented as:

status = 0
qty = "0"

Partial fills are not surfaced as separate events. Instead, the resting order quantity changes.

MempoolTx frame

Tag:

4

Size:

Variable

MempoolTx frames are emitted for mempool transactions when the client is subscribed to the mempool stream.

These frames can be large because the payload is length-prefixed with a u32.

Layout:

offset  size    field
────────────────────────────────────────────────────────────
0       1       tag = 4
1       8       receive_ts_us, node first saw the tx, µs since epoch
9       32      tx_hash, raw 32-byte hash
41      4       payload_len, u32 little-endian
45      N       payload, signed-action bundle as raw JSON

Error frames

Errors are delivered as JSON text frames.

Example:

{"channel":"errors","code":"<code>","message":"<human readable>"}

The code field is a stable contract and can be used programmatically.

The message field is intended for humans and may change.

CodeMeaningDisconnects?
invalid_jsonText frame was not valid JSONYes
missing_methodJSON frame had no method fieldYes
unknown_methodMethod value is not recognizedYes
missing_paramRequired coin, stream, or version field is missingYes
empty_coinSubscribe was called with an empty coin stringNo
unknown_streamStream value is not supportedNo
mempool_unavailableMempool stream is not enabled on this serverNo
version_mismatchesp version does not match the server versionYes
not_espprime or unprime was called before espYes

After prime, clients may also receive informational server error events. These do not necessarily indicate a client-side issue.

What's next?