Yellow BoxTrading APIv1 · pre-release

WebSocket Market Streams

WebSocket Market Streams Overview

Live prices, candles and statistics. Market streams are public — no API key, no signature, no login. Account events are on a separate, authenticated connection: User Data Streams Overview.

Endpoints

Form URL
Raw wss://trade-stream.yellowboxmarkets.com/ws
Raw, pre-subscribed wss://trade-stream.yellowboxmarkets.com/ws/XAUUSD@tick
Combined wss://trade-stream.yellowboxmarkets.com/stream?streams=XAUUSD@tick/BTCUSD@kline_1m

On the raw endpoint, payloads arrive exactly as documented below.

On the combined endpoint, every payload is wrapped:

JSON
{"stream":"XAUUSD@tick","data":{"e":"tick","E":1789012345678,"s":"XAUUSD","b":"2331.15","a":"2331.42","l":"2331.15","v":8,"bd":1,"ad":-1,"T":1789012345678}}

Streams in the streams= query parameter are separated by /. URL-encode the value if a symbol name contains a character that needs it.

Subscribe protocol

Send JSON text frames.

SUBSCRIBE

JSON
{"method":"SUBSCRIBE","params":["XAUUSD@tick","BTCUSD@kline_1m"],"id":1}
JSON
{"result":null,"id":1}

UNSUBSCRIBE

JSON
{"method":"UNSUBSCRIBE","params":["XAUUSD@tick"],"id":2}
JSON
{"result":null,"id":2}

LIST_SUBSCRIPTIONS

JSON
{"method":"LIST_SUBSCRIPTIONS","id":3}
JSON
{"result":["BTCUSD@kline_1m"],"id":3}

Request fields

Field Type Mandatory Description
method STRING YES SUBSCRIBE, UNSUBSCRIBE or LIST_SUBSCRIPTIONS.
params ARRAY of STRING conditional Stream names. Required for SUBSCRIBE / UNSUBSCRIBE.
id UNSIGNED INT YES Chosen by you. Echoed on the response so you can correlate. Reuse is allowed but makes correlation ambiguous.

Error frames

JSON
{"code":-1121,"msg":"Invalid symbol.","id":1}
JSON
{"code":-1120,"msg":"Invalid interval.","id":4}
JSON
{"code":-1101,"msg":"Too many parameters sent for this endpoint.","id":5}
Code When
-1121 A stream name whose symbol does not exist (exact case), or that is malformed or of an unknown stream type.
-1120 A kline_ stream with an unsupported interval.
-1101 The subscription would exceed 200 streams on the connection.
-1102 id, method or (for SUBSCRIBE / UNSUBSCRIBE) params missing or of the wrong type. When id itself is unusable the frame carries "id":null.
-1020 An unknown method.
-1130 The frame is not a JSON object. "id":null.

An error frame never closes the connection. UNSUBSCRIBE of a stream you are not subscribed to is a no-op and answers success.

A SUBSCRIBE with several params is all-or-nothing: if one name is invalid the whole frame is rejected and nothing is subscribed. Subscribe in small batches so one bad symbol does not cost you the rest.

Codes are the same ones documented in Error Codes.

Connection limits

Limit Value
Ping frame from the server every 3 minutes
Disconnect if no pong after 10 minutes without one
Maximum connection lifetime 24 hours
Streams per connection 200
Inbound messages per second 10
Concurrent connections per client IP 20
  • Reply to every WebSocket ping frame with a pong. Most client libraries do this automatically; verify yours does. A missed pong window costs you the connection.
  • You may send unsolicited pong frames as a heartbeat; they are ignored and do not count toward the message rate.
  • A connection is closed at 24 hours regardless of activity. Reconnect before then. Overlap the connections — open the new one, subscribe, then drop the old one — so you do not miss ticks.
  • Exceeding 10 inbound messages per second closes the connection immediately. Batch stream names into one SUBSCRIBE rather than sending one frame per stream.
  • Exceeding 200 streams returns -1101 and subscribes nothing.
  • A connection beyond the per-IP limit — or beyond the service's overall capacity — is refused before the WebSocket upgrade with HTTP 503 and -1008. Put your streams on fewer connections (up to 200 each) rather than opening one per symbol.
  • A plain HTTP request (no WebSocket upgrade) to a stream URL is answered HTTP 400 with -1020.
  • An inbound message larger than 64 KB closes the connection.
  • On the pre-subscribed and combined URLs, an invalid stream name in the URL is answered with one error frame (as above, "id":null) and the connection is then closed — nothing is subscribed.

The server closes a connection with these WebSocket close codes:

Close code Reason Cause
1000 connection lifetime reached The 24-hour lifetime elapsed (or the service is restarting).
1000 invalid stream name An invalid name in a pre-subscribed or combined URL.
1008 message rate exceeded More than 10 inbound messages in one second.
1009 frame too large An inbound message over 64 KB.

There are no rate-limit weight headers on WebSocket. Market streams do not consume REST request weight, which is exactly why you should use them instead of polling.

Reconnect guidance

Market streams carry no state and are not replayed. On reconnect:

  1. Re-subscribe to everything you had. LIST_SUBSCRIPTIONS on the new connection is the way to verify, not to discover.
  2. Refresh anything you were accumulating from the stream: candles from GET /v1/klines, and any last-price cache from GET /v1/ticker/price.
  3. Assume you missed ticks during the gap. Never derive position state from the tick stream — read it from GET /v1/positions.

Reconnect with backoff and jitter. A fleet of bots reconnecting in lockstep after a restart is self-inflicted load.