Overview
Connect to the public WebSocket, read the envelope, handle reconnects and limits.
What you get
The Market Stream is a public WebSocket that pushes live token data. xAxios indexes and processes on-chain data, and sends you the result as plain JSON: what a token is worth, every trade and liquidity move behind it, and every token the chain mints. No key, no signup, no SDK. Any WebSocket client in any language works.
- Endpoint:
wss://api.xaxios.com/v1/stream - Every message, in both directions, is a single JSON object.
- Chains: Solana and Robinhood Chain. On a token channel you can leave
chainoff and we read it from the address, so a base58 address is Solana and a0xaddress is Robinhood Chain. - Times are UTC unix timestamps in seconds. Money and token amounts carry six decimals, so a fraction of a cent survives. Percentages are whole numbers, so
3.01means 3.01%. Prices are rounded to eight significant digits rather than to decimal places, because a token can trade at0.000000001234. - A field is
nullwhen we have nothing to report for it. It never means zero.
Channels
Five channels, each with its own page. A token channel takes addresses; a chain channel takes a chain and follows every token on it. A state channel replays the latest to you the moment you subscribe; an event channel sends what happens while you are connected.
Send { "method": "streams" } and the server lists them back with a one-line description each, so a client can discover a new channel without redeploying.
Connect and subscribe
Open the socket and send a subscribe. You get an acknowledgement first, then the events for that subscription.
Stop a subscription with the same message and method: 'unsubscribe'. Closing the socket releases everything you had open.
Try it live
Connect from this page. Pick a channel, keep the sample token or paste your own, and watch the events arrive. Your browser talks to the stream directly, so what you see here is exactly what your own client would get.
Messages you send
Four methods. subscribe and unsubscribe take a channel and up to 20 addresses at once, or a chain on the chain-scoped channels. ping answers with a pong. streams lists every channel.
Adding and dropping tokens
Subscriptions build up on the connection. Start with one token, add more whenever you need them, and drop the ones you stopped showing. Each message only touches the addresses it names, so the rest keep running untouched.
After those three messages you are watching the first and third tokens. Subscribing again to something you already have is answered with another subscribed rather than counted twice, so a client that retries after a lost acknowledgement stays correct. Unsubscribing from something you do not have is not an error either: you asked to not be subscribed, and you are not.
Each token counts once against the cap of 20 per connection, whichever channel it is on, and dropping one frees its slot straight away.
Events you receive
Every event is one JSON object with the same envelope. Each one carries an id of ours, the type tells you what it is, and data carries the channel payload. When the event answers a request you sent an id with, it comes back as requestId.
subscribed always arrives before the data it acknowledges. On a state channel, snapshot is what we already hold, sent the moment you subscribe, and update is every change after that. Event channels send only update, one per thing that happened.
Data arrives on change
A token that is not trading produces no events. Quiet tokens can go minutes without one, and an address we do not track sends nothing at all. Silence means no change, not a broken connection: useping to tell the two apart.Staying connected
We send a WebSocket ping every 30 seconds. Your client library answers it on its own, and a connection that misses a round is closed. In a browser you cannot see those pings, so send your own ping every 20 to 30 seconds: if no pong comes back within a few seconds, the connection is gone even when no close event fired.
Subscriptions live on the connection. After a reconnect, send them again, and back off between attempts so a restart on our side does not turn into a stampede. What happens further upstream is our problem, not yours: if a feed we depend on drops, we reconnect and resubscribe underneath you, your seq keeps counting, and you are asked to do nothing.
Watch the seq
seq counts events per subscription, starting at 1. If it jumps, you missed something. On a state channel the next update carries the full state anyway, so a gap costs you history, never correctness; on an event channel a gap is events you will not see again.Errors
An error is an event like any other, with type: 'error' and an error.code you can branch on. Send an id with your request and it comes back on the error as requestId, so you know which message failed. Only too_many_connections closes the socket.
Limits
The stream is free and open, so the limits exist to keep one client from crowding out the rest.
Twenty tokens on one connection, five connections per client: a hundred tokens in all, which is what a dashboard needs. Spread them across the five rather than opening a connection per token, and unsubscribe from what you stopped showing. A client that stops reading what we send is disconnected once the backlog grows past what we are willing to hold for it.