Connect
Open a WebSocket towss://api.metastreams.io/v1/stream, with your key in the Authorization header of the handshake.
A request without WebSocket upgrade headers gets a plain-text
4xx instead of an upgrade.
Browsers cannot set the Authorization header on a WebSocket, so connect from your backend.
Frames
Every frame is a JSON text message.From you
From the server
Subscription IDs
The server assigns each subscription asubscriptionId and returns it on the subscribe ack. Every update carries the ID of the subscription it belongs to. Use the ID to route updates in your client and to unsubscribe exactly.
An unsubscribe without a subscriptionId closes every subscription you hold on that channel, and its ack carries no ID.
Ordering
- A subscription’s ack always arrives before its first update.
- An unsubscribe’s ack always arrives after that subscription’s last update.
Channels
Every REST read that changes over time has a channel that pushes the same objects.
A streamed candle or token has exactly the shape its REST read returns: OHLCV candles and Token details. A streamed trade has the shape Token trades and Identity trades return, minus some fields per subscription mode: see
spot.trades. Each channel’s reference page lists every filter, every update field and every error.
A stream costs no request budget after its handshake, so it is the cheaper way to follow anything that changes more than once a minute.
Snapshot, then stream
A stream sends only what happens after you subscribe. To show a complete view, combine the two:- Subscribe first, and buffer the updates that arrive.
- Read the snapshot from the REST endpoint.
- Apply the buffered updates on top of the snapshot, then apply new updates as they arrive.
Errors
A refused frame gets anerror frame. It uses the same codes as the REST API. An error about a subscribe frame echoes that frame’s id. A frame the server cannot parse, and a refused unsubscribe, get an error with no id.
An error frame never closes the connection.
Keeping the connection alive
Send{"action": "ping"} every 30 seconds or so. If no pong arrives within a few seconds, treat the connection as dead and reconnect.
When the server closes the connection
Subscriptions do not survive a reconnect. After you reconnect, send your subscribe frames again and fill the gap with a fresh snapshot.
Reconnect loop
These loops resubscribe after every close, reconnect straight away after1001, back off after anything else, and stop only on 401.