WebSocket Info API Reference
Overview
The Reya DEX Trading WebSocket API v2 provides real-time streaming data for decentralized exchange operations on the Reya Network. This version offers user-friendly data structures with human-readable formats, removing blockchain-specific details while maintaining comprehensive trading functionality.
For placing and cancelling orders over WebSocket, see WebSocket Order Entry API Reference. The recommended integration runs both connections in parallel: that surface for order entry, this surface for market and account updates.
Server Endpoints
See Rate Limits for inbound message allowances, IP connection limits and recovery after a 4029 close. Pace subscription replay as well as steady-state traffic.
Production Environment
URL:
wss://ws.reya.xyz/Protocol: WSS
Description: Production WebSocket server for live trading on the order book
For integration testing against the same contract, use devnet1. See Environments for each environment's endpoints and signing values.
Channel Architecture
The API uses a hierarchical channel structure with clear separation between different data types:
Market Data Channels
/v2/perpMarkets/summary- Perp market summaries/v2/perpMarket/{symbol}/summary- Individual perp market summary/v2/spotMarkets/summary- Spot market summaries/v2/spotMarket/{symbol}/summary- Individual spot market summary/v2/market/{symbol}/perpExecutions- Market-specific perpetual executions/v2/market/{symbol}/depth- L2 order book depth snapshots for a specific market/v2/market/{symbol}/spotExecutions- Market-specific spot executions/v2/market/{symbol}/executionBusts- Market-specific execution busts (failed fills — spot + perp)/v2/assetOraclePrices- Asset Stork oracle prices
Wallet Data Channels
/v2/wallet/{address}/positions- Position updates/v2/wallet/{address}/orderChanges- Order change updates/v2/wallet/{address}/perpExecutions- Wallet-specific perpetual executions/v2/wallet/{address}/spotExecutions- Wallet-specific spot executions/v2/wallet/{address}/executionBusts- Wallet-specific execution busts (failed fills — spot + perp)/v2/wallet/{address}/accountBalances- Account balance updates/v2/wallet/{address}/transfers- Transfer history (account ledger) entries: deposits, withdrawals, transfers, stakes, spot legs, perp fees and rebates, liquidation penalties/v2/wallet/{address}/accounts- Account creation / ownership-change notifications for the wallet
Parameter Validation
Symbol Parameter
Pattern:
^[A-Za-z0-9]+$Examples:
BTCRUSDPERP,ETHRUSDPERP,WETHRUSD,WBTCRUSDDescription: Trading symbol supporting alphanumeric characters
Address Parameter
Pattern:
^0x[a-fA-F0-9]{40}$Example:
0x6c51275fd01d5dbd2da194e92f920f8598306df2Description: Ethereum wallet address (40 hexadecimal characters)
Message Structure
The Info surface uses one envelope shape for streamed channel data, plus a small set of control envelopes for subscription management. All envelopes share a type discriminator at the top level; the rest of the body is type-specific.
Channel Data Envelope (Server → Client)
type: Always
"channel_data"for data updatestimestamp: Server timestamp in milliseconds
channel: Specific channel identifier
data: Channel-specific payload (object or array)
Subscribe Envelope (Client → Server)
The id is an optional client-chosen correlation marker. The server does not echo it back in the confirmation and does not enforce uniqueness across in-flight subscribes; it is purely for client-side bookkeeping.
Subscribed Confirmation (Server → Client)
The contents field carries an initial snapshot for channels that provide one (e.g. /v2/market/{symbol}/depth); otherwise it is omitted. For /v2/wallet/{address}/orderChanges, contents carries the current open orders plus a snapshotSequenceNumber cursor. For /v2/wallet/{address}/transfers, contents.data carries the wallet's most recent ledger entries, newest first.
Unsubscribe Envelope (Client → Server)
Unsubscribed Confirmation (Server → Client)
Error Envelope (Server → Client)
The shape and the full set of possible message values are documented in Error Catalog below.
Heartbeats
The heartbeat / connection-liveness mechanism is documented in detail on its own page — see Heartbeats. Short version: protocol-level pings handle liveness automatically, no application-level code is required on the client.
Reconnecting & resyncing
Delivery depends on the channel class:
Stateful feeds — depth and
orderChanges— stay ordered and lossless while the connection is healthy. If your client cannot keep up, the connection closes with code1013(slow consumer — resubscribe for fresh snapshot). Reconnect and rebuild from a fresh snapshot.Latest-value feeds — including
assetOraclePrices— may skip intermediate updates and deliver the latest value per asset when your client falls behind. Do not use these channels as an every-tick ledger. If the client continues to fall behind, the connection closes with1013.
A service restart or required feed resynchronization closes the connection with code 1012. Treat the reason string as advisory: recovery for both 1012 and 1013 is the same:
Reconnect and re-send
subscribefor each channel.The
subscribedconfirmation'scontentscarries a fresh initial snapshot for channels that provide one (e.g./v2/market/{symbol}/depthreturns a fullSNAPSHOT). Rebuild from it and resume applyingUPDATEs.For
orderChanges, rebuild from the subscribed confirmation'scontents.dataopen-order snapshot andcontents.snapshotSequenceNumbercursor; subsequent rows havesequenceNumbergreater than that cursor. For other per-wallet channels (positions,accountBalances), reconcile current state from REST, then resume the stream.
Updates from the disconnected window are not replayed. A reconnect/resubscribe returns a new top-100 SNAPSHOT; it does not inject a mid-stream snapshot into the old connection. An ordered per-market depth reset can instead be delivered in-band as an ordinary UPDATE that removes old levels and adds the replacement bounded view. Apply it using the same absolute-quantity rules as any update.
FEED_RESET remains in the API 3.6.2 enum, but resynchronization currently uses close code 1012 instead. If you receive FEED_RESET, rebuild your local order view; it does not mean your orders were cancelled.
Channels Reference
1. Market Data Channels
/v2/perpMarkets/summary
Purpose: Real-time updates for all perp market summaries.
Subscription:
Message Structure:
/v2/perpMarket/{symbol}/summary
Purpose: Real-time updates for a specific perp market's summary.
Parameters:
symbol: Trading symbol (e.g.,BTCRUSDPERP,kBONKRUSDPERP)
Subscription:
Message Structure:
/v2/spotMarkets/summary
Purpose: Real-time updates for all spot market summaries
Subscription:
Message Structure:
/v2/spotMarket/{symbol}/summary
Purpose: Real-time updates for a specific spot market's summary
Parameters:
symbol: Trading symbol (e.g.,WETHRUSD)
Subscription:
Message Structure:
/v2/market/{symbol}/perpExecutions
Purpose: Real-time perpetual executions for a specific market
Parameters:
symbol: Trading symbol (e.g.,BTCRUSDPERP,ETHRUSDPERP)
Subscription:
Message Structure:
/v2/assetOraclePrices
Purpose: Real-time asset Stork oracle prices.
Subscription:
Message Structure:
/v2/market/{symbol}/depth
Purpose: Real-time L2 order book depth for a specific market — an initial top-100 snapshot per side followed by incremental updates to that bounded view
Parameters:
symbol: Trading symbol (e.g.,BTCRUSDPERP,SOLRUSDPERP)
Subscription:
Message Structure:
Snapshots vs updates — you must merge, not replace. The first message after you subscribe is a "type": "SNAPSHOT" of at most 100 best bid and 100 best ask levels. Every subsequent message is "type": "UPDATE" and carries only the price levels that changed — not the whole book. Maintain your own book and apply each UPDATE:
For each level in
bids/asks, upsert the level at thatpxto the newqty.A level with
qty: "0"means that price level was removed — delete it from your book.Levels not present in an UPDATE are unchanged — leave them.
Treating an UPDATE as a full snapshot will wipe your book on every tick and leave stale levels behind.
The boundary is part of the feed. A level leaving the top 100 is removed with qty: "0" even if orders still rest there on the exchange. A level entering the top 100 is added with its full current quantity. Changes entirely below the top-100 boundary produce no public depth update. For example, removing the best bid can promote the previous 101st bid; the update removes the old best and adds the promoted level. Apply the entire update before using the new view. Zero means "remove from my published view", not necessarily "no liquidity exists at this price".
There is no WS depth-size parameter. Do not combine a deeper REST snapshot with this stream to maintain a full book: levels outside the WS view are not kept current. REST GET /v2/market/{symbol}/depth?limit=N defaults to 100 levels per side and caps at 1,000; see REST OpenAPI contract.
Update message (only changed levels; qty: "0" removes a level):
/v2/market/{symbol}/spotExecutions
Purpose: Real-time spot executions for a specific market
Parameters:
symbol: Trading symbol (e.g.,WETHRUSD,WBTCRUSD)
Subscription:
Message Structure:
/v2/market/{symbol}/executionBusts
Purpose: Real-time execution busts (failed fills) for a specific market — covers both spot and perp
Parameters:
symbol: Trading symbol (e.g.,WETHRUSD,BTCRUSDPERP)
Subscription:
Message Structure:
2. Wallet Data Channels
/v2/wallet/{address}/positions
Purpose: Real-time position updates for a wallet
Parameters:
address: Ethereum wallet address (e.g.,0x6c51275fd01d5dbd2da194e92f920f8598306df2)
Subscription:
Message Structure:
/v2/wallet/{address}/orderChanges
Purpose: Real-time order change updates for wallet order-state tracking.
API 3.5.4 introduced avgFillPx on order updates and the open-orders snapshot after the first fill. The example and field list below include this field.
Parameters:
address: Ethereum wallet address
Subscription:
Subscribed Confirmation:
The subscribed confirmation returns the current open-orders snapshot in contents.data and the snapshot cursor in contents.snapshotSequenceNumber. Snapshot orders do not include sequenceNumber; the cursor represents the snapshot boundary. Subsequent channel_data order rows include sequenceNumber greater than snapshotSequenceNumber.
Message Structure:
/v2/wallet/{address}/perpExecutions
Purpose: Real-time perpetual execution updates for a wallet
Parameters:
address: Ethereum wallet address
Subscription:
Message Structure:
/v2/wallet/{address}/spotExecutions
Purpose: Real-time spot execution updates for a wallet
Parameters:
address: Ethereum wallet address
Subscription:
Message Structure:
/v2/wallet/{address}/executionBusts
Purpose: Real-time execution bust updates for a wallet — covers both spot and perp
Parameters:
address: Ethereum wallet address
Subscription:
Message Structure:
/v2/wallet/{address}/accountBalances
Purpose: Real-time account balance updates for a wallet
Parameters:
address: Ethereum wallet address
Subscription:
Message Structure:
/v2/wallet/{address}/transfers
Purpose: Transfer history (account ledger) entries for a wallet — the same entries GET /v2/wallet/{address}/transfers returns, one per account side of every on-chain transfer leg, signed from the account's view. Net deposits only: realized PnL and funding never appear. See Transfer History (Account Ledger).
Parameters:
address: Ethereum wallet address
Subscription:
The subscribed acknowledgement carries the wallet's most recent entries in contents.data, newest first (at most 30 for the whole wallet; zero-amount entries are not pushed). Every later frame carries one new entry.
Message Structure:
/v2/wallet/{address}/accounts
Purpose: Notifies when an account owned by the wallet is created, has its main/spot binding change, or (defensively) changes ownership. Lets you detect new accounts without polling.
Subscription:
Message Structure:
Error Catalog
For validation and subscription failures, the server emits an error envelope and keeps the connection open; only the offending operation is rejected. Exceeding the inbound message allowance instead closes the connection with 4029; see Rate Limits. Error envelopes share this shape:
The channel field is included when the error relates to a specific channel (e.g. an invalid subscribe target). It is omitted for frame-level errors that aren't tied to a particular channel.
Common message strings emitted by the server:
Invalid JSON
The frame body could not be parsed as JSON.
Fix the client serializer.
Invalid type
The frame's type field is not one of subscribe, unsubscribe, ping. (pong is server-only — clients don't send JSON pong frames.)
Verify the request type.
Invalid channel name
The subscribe / unsubscribe target does not match a known channel path or has malformed parameters (e.g. an invalid symbol or address).
Check the channel name against the Channels Reference and the Parameter Validation rules.
Error while fetching snapshot from {channel}
The initial snapshot could not be provided, so the subscription did not succeed.
Retry the subscribe after a short backoff. If the problem persists, contact support with the channel name and timestamp.
Subscribe rate limit exceeded — slow down
The connection or IP exhausted its separate subscription-request allowance. No snapshot is sent for the rejected request.
Retry with backoff and pace subscription replay across connections sharing the IP.
Data Types & Schemas
Enumeration Types
Connection Management
Reconnection Pattern
Reconnect with the usual exponential-backoff-with-jitter pattern. The Reya-specific steps — re-subscribe to every channel and reconcile missed events from REST (e.g. GET /v2/wallet/{address}/openOrders, GET /v2/wallet/{address}/perpExecutions) — are covered in Reconnecting & resyncing above.
For the meaning of WS close codes you'll see on onclose (1000, 1001, 1006, etc.), see What Happens When the Server Closes the Connection.
Service Restarts
Info service restarts close connections with code 1012; reconnect and re-subscribe for fresh snapshots. Order Entry uses close code 1001. Both are documented in Service restarts.
Python SDK Example
Worked examples are included in the Python SDK 3.6.1.0 under examples/websocket/. The directory is split by market type:
examples/websocket/perps/market_monitoring.py— subscribe to perp market summariesexamples/websocket/perps/prices_monitoring.py— subscribe to the price streamexamples/websocket/perps/wallet_monitoring.py— subscribe to wallet-scoped channels (positions, order changes, executions, balances)examples/websocket/spot/spot_executions.py— subscribe to spot execution streamsexamples/websocket/spot/depth_market_maker.py— bootstrap state via REST, then drive a market-maker loop off ofdepth,accountBalances,openOrders, andspotExecutionsupdates
After installing the pinned SDK, run from its checkout:
See each script's docstring for prerequisites (.env setup, funded accounts). The SDK's .env.example targets devnet1; for mainnet, replace those entries with the mainnet values.
Last updated