Skip to main content
The UpsideMAX WebSocket API delivers real-time push streams for market data and account state without polling. Once you open a connection to wss://upsidemax.xyz/ws (Devnet: wss://dev.upsidemax.xyz/ws), the server pushes updates as they occur — book channels push as the book changes, and timed channels such as ticker and allMarkets push about once a second. Account channels such as order updates and fills are subscribed by wallet address; there is no authentication step.

What the stream covers, and what it does not

Decide per data type whether you can rely on the stream or must query. “No event” never means “no change” — it can also mean a dropped connection, a missed subscription, or a channel that does not carry that data at all. Not available on any channel — query the read API when you need them:

Balances and positions arrive as full snapshots

userAccount pushes a complete snapshot, never a delta, on two paths: a frame is pushed when the account has a fill, and every other change — deposits, funding settlement, mark-price moves — is picked up by a timed push within 3 seconds. Two consequences:
  • A fill and the account frame that reflects it arrive on different channels, and their arrival order is not guaranteed. Never assume an unchanged account frame means the fill did not happen, and never treat an account frame as proof that a fill occurred — the timed path pushes even when nothing changed.
  • Because each frame is a full snapshot, a missed frame self-heals — overwrite local state wholesale and do not attempt to apply deltas.
When you need account state as of now — before sizing an order, or to reconcile after a timeout — query userAccount rather than waiting for the next frame.

Reconnection

1

Reconnect and replay your subscriptions

The server keeps no connection state: when a connection closes, every subscription is released. Your client reconnects on its own — use exponential backoff — then re-subscribes to every channel. Keep the current subscription set on the client so you can replay it.
2

Take the re-delivered snapshots as truth

Snapshot-bearing channels replay on resubscribe: l2Book, openOrders, and userAccount send a full snapshot, trades up to 100 recent trades, orderUpdates and userFills 10 rows each. candle sends no snapshot — query candleSnapshot for the gap. Replace local state from the snapshots rather than merging.
3

Deduplicate the overlap

Snapshots can overlap the increments that follow. Deduplicate on the identity for that stream: tid for trades, bar open time t for candles, order ID for orders, execution ID for fills. l2Book frames are full snapshots, so applying one twice is harmless.
4

Reconcile anything the gap may have hidden

A disconnect can hide events that no snapshot replays — a fill older than the 10 rows, or a funding settlement. After a gap of any length, reconcile positions and balances from userAccount and fills from userFills before acting.
Ordering is guaranteed within a channel, not across channels. Do not infer causality between, say, an orderUpdates fill and a userAccount frame from arrival order — correlate on identifiers and timestamps.

Connection lifecycle

1

Open the WebSocket connection

Establish a WebSocket connection to wss://upsidemax.xyz/ws, sending a User-Agent header.
A connection with no User-Agent is rejected with 403 before it reaches the API. The rejection carries no body and no API error code, so it looks like an outage rather than a missing header. Any non-empty value works — most WebSocket libraries set one by default, but some send none unless you ask, and an empty string is treated as missing.
2

Subscribe to channels

Send a subscribe message for each channel you want to receive. You can subscribe to multiple channels on the same connection. See Subscription for the message format.
3

Receive push messages

The server pushes messages to you as events occur. Each message includes a channel field that identifies its source so you can route it to the correct handler.
4

Answer the server's Ping

The server sends a WebSocket Ping control frame every 30 seconds; your client answers with a Pong. Browsers and standard WebSocket libraries reply automatically. A custom socket client must answer each Ping (opcode 0x9) with a Pong (opcode 0xA) carrying the same payload; without a Pong for about 60 seconds, the server closes the connection without a Close frame, which the client observes as an abnormal closure (1006). No application-level heartbeat message exists or is needed.

Available channels

The table below summarises every channel available on the WebSocket API. No channel requires an authentication step: account-scoped channels are addressed by the wallet address in the subscription.

Reconnection

Reconnection is implemented by the client; the server does not reconnect for you and keeps no state across connections. When a connection closes, all of its subscriptions are released, so after reconnecting you must re-subscribe to every channel you held before. Keep the current subscription set on the client and replay it after each reconnect. Use exponential backoff between attempts so that reconnects do not pile up while the server is unavailable.
The WebSocket endpoint does not guarantee message ordering across different channels. If you need causal ordering between, for example, openOrders and orderUpdates, correlate messages using their ts timestamps and order ID fields.

Channel quick-reference

l2Book

Full order book snapshots pushed whenever the book changes — bids and asks with price, size, and order count.

bbo

Best bid and best ask only — lower bandwidth than l2Book for top-of-book use cases.

trades

All public trades for a contract as they execute on-chain.

candle

Live OHLCV candle updates at any supported interval, with closed-bar events.

orderUpdates

Incremental order state changes — placed, filled, cancelled, and TP/SL events.

openOrders

One snapshot of all active orders on subscribe — pair it with orderUpdates for later changes.

userFills

Every fill involving your account — whether you were the taker or the maker.

ticker

24-hour rolling statistics for a contract — change, high, low, volume, funding rate, mark and oracle price.

allMarkets

Oracle price, mark price, and 24-hour volume for every contract in a single frame.

userAccount

The full account view — collateral, positions, and margin — pushed on fills and on a timer instead of polled.

config

Lightweight notifications when contract configuration changes — new listings, freezes, or parameter updates.