wss://ws.paramx.xyz/v1 (devnet: wss://ws.paramx.xyz/devnet/v1). Every message is a JSON text frame.
Subscribing
Client to server:book, top_of_book and trades also take instrument_ids, meaning every contract of those instruments, including tiles that are listed later. It counts as one subscription. It sends no snapshot, so load the current books from GET /v1/books?instrument_id= after subscribing.
Channels
book
book
After subscribing, the full book of each contract, then the full book again after every change. There are no deltas to apply.
top_of_book
top_of_book
The same, for the best bid and ask only.
trades
trades
The exchange’s public tape, one message per executed trade. There are no addresses;
taker_side is the side that took liquidity.underlying_trades
underlying_trades
The last trade on subscribe, then every trade of the underlying.
account
account
An account’s events: see Account events.
{"op": "subscribed" | "unsubscribed", "channel", …}, echoing the subscription’s key field, and {"op": "pong"}.
Errors: {"error": {"code", "message"}}, e.g. INVALID_INPUT or TOO_MANY_SUBSCRIPTIONS.
Ordering and gaps
seq: every data message carries its connection’s seq: 1, 2, 3…, with no gaps. The server never skips a message (it disconnects a client that falls too far behind), so a gap means you missed something: reconnect, subscribe again, and reload from REST. Acknowledgements, pongs and errors don’t carry seq.
version: books and top of book carry a version that only rises per contract. Keep the newest per contract and drop anything older; a snapshot sent on subscribe can arrive after a newer live update.
Limits and keepalive
- 2,000 subscriptions per connection, and at most 20 of them accounts;
- 20 connections per IP;
- a client that falls 8 MB behind is disconnected.
Origin header must come from app.paramx.xyz. Server-side clients send none.