Streams
One WebSocket delivers trades, prices, wallet activity, launches and graduations about half a second after each checkpoint. Resume after short gaps with a sequence number.
Works onSui
Connect
Subscribe with {"op":"subscribe","topics":[...]}. Send your key as a Bearer header, or as {"op":"auth","key":"..."} in your first message. No key works too, with smaller limits.
wss://yolo.casa/api/v1/streamhttps://yolo.casa/api/v1/stream/sse?topics=launchesTry it
Opens a real connection from your browser.
Connect to watch events arrive. No key needed.
Topics
| Topic | Event | What you get |
|---|---|---|
| trades:<coinType> | trade | Every trade of one coin. |
| price:<coinType> | price | One coin's price, at most two ticks a second. |
| wallet:<address> | trade | Trades made by one wallet. |
| launches | launch | Every new launchpad coin. |
| launches:<launchpad> | launch | New coins on one launchpad. |
| graduations | graduation | Coins that bonded and left their curve. |
| large_trades | trade | Trades of $10,000 or more. |
| large_trades:<usd> | trade | Trades of at least this many dollars, 1000 or more. |
| firehose | trade | Every trade, launch and graduation. Funded keys only. |
| prices | price | Every coin's price ticks. Funded keys only. |
Limits
| No key | Free key | Funded key | |
|---|---|---|---|
| Connections | 2 | 3 | 20 |
| Topics per connection | 10 | 100 | 2,000 |
| Wallets watched | 3 | 25 | 500 |
| Firehose and all prices | No | No | 1 credit a minute |
Example client
Reconnects on silence and resumes from the last event it saw.
// Node 22+ or any browser. Reconnects and resumes after short gaps.
const topics = ['large_trades:5000', 'launches'];
let epoch = null, seq = 0;
function connect() {
const ws = new WebSocket('wss://yolo.casa/api/v1/stream');
let alive = Date.now();
ws.onopen = () => {
// Optional: a key raises the limits. Leave it out to stay anonymous.
if (process.env.YOLO_API_KEY)
ws.send(JSON.stringify({ op: 'auth', key: process.env.YOLO_API_KEY }));
ws.send(JSON.stringify({
op: 'subscribe', topics,
...(epoch ? { resume: { epoch, seq } } : {}),
}));
};
ws.onmessage = (e) => {
alive = Date.now();
const m = JSON.parse(e.data);
if (m.type === 'hello') epoch = epoch ?? m.epoch;
if (m.type === 'resume_failed') { epoch = m.epoch; seq = m.seq; /* refetch over REST */ }
if (m.type === 'event') { seq = m.seq; console.log(m.channel, m.topics, m.data); }
};
// The server pings every 15 s. Silence for 45 s means the link is dead.
const watch = setInterval(() => { if (Date.now() - alive > 45_000) ws.close(); }, 5_000);
ws.onclose = () => { clearInterval(watch); setTimeout(connect, 1_000); };
}
connect();Reconnecting
Every event has a sequence number. The server pings every 15 seconds; reconnect after 45 seconds of silence. On reconnect, pass the last epoch and seq you saw as resume to receive what you missed, for gaps of up to about two minutes. A resume_failed reply means the gap is gone: refetch over REST.
Clients that fall too far behind are closed with code 4008. Other close codes: 4001 invalid key, 4009 key revoked, 4029 connection limit, 4000 server restart. Server-Sent Events resume with Last-Event-ID.