Streams (SSE)
Server-Sent Events for one market or the whole list: book, best bid and offer, stats, oracle mark, trades, server built klines, chain head, fill counter.
Server-Sent Events are the simplest live feed: one HTTP request that never ends, readable with EventSource in a browser or curl -N on a shell. No key. TRUE keeps one shared poller per market for every subscriber, so your connection costs the venue nothing extra.
GET https://app.truefinance.ai/api/perps-dex/stream?market=BTCUSDC curl -N "https://app.truefinance.ai/api/perps-dex/stream?market=BTCUSDC&kline=1m,15m"
Events
Each event is an event: line and a JSON data: line. Everything is pushed only when it changed; the current state of each arrives on connect, so you can render before the first live change.
| event | payload | cadence |
|---|---|---|
bbo | best bid and offer with sizes | on change, polled at 350 ms |
orderbook | full book, depth 60, {bids:{price:size}, asks:{…}} | on change, polled at 600 ms |
stats | the 24h stats row | on change, about once a second |
mark | {market, mark_price}, the oracle mark | on change; the oracle moves about once a second |
trades | array of new fills only, never a replay | polled at 1 s |
kline | a server built bar for each interval in &kline=…; closed:true when it rolled | only when the bar changed |
block | chain head: block height and settle cadence | on change |
tape | venue fill counter {trades_24h, trades_today} | on change |
hb | heartbeat, {} | every 15 s, on every stream |
Kline intervals: 1s 1m 5m 15m 1h 4h 1d. A bar is {market, interval, start, open, high, low, close, volume, trades, closed, filled}. Bars are built from the oracle mark with volume carried from real fills, so a market with no trades still produces a moving bar.
Trades are deltas only: load the initial tape over REST, then append.
To receive only some events, add &events= with a comma separated list, for example &events=mark,kline for a chart. Without it you get every event; hb is always sent.
The list feed
GET https://app.truefinance.ai/api/perps-dex/stream?market=ALL stats for every market in one event, mark as one bundle {marks:{SYM:px}, ts, src:"pyth"|"oracle"} (oracle when Pyth has gone quiet) for every market, and tape. The stats bundle churns about once a second because 24h volume is a rolling window; the marks bundle is pushed only when a mark moved.
Reconnecting
The stream sends retry: 3000, so EventSource reconnects on its own after 3 s. Reconnect with backoff yourself if you use a raw HTTP client: 1 s doubling to 15 s. A reconnect gets the full current state again.
A quiet market can go minutes without a data event, so do not judge the connection by those. The hb event arrives every 15 s on every stream: if 40 s pass with no event at all, the connection is dead (a half-open socket after a network change looks open); close it and reconnect. During a deploy the server ends streams cleanly and answers new ones with 503 for a moment; back off and retry.
5,000 connections per server replica, 32 concurrent streams and 240 connects a minute per client IP. Beyond that: 429 (per IP) or 503 (capacity). Each server replica counts these on its own. A phone holds two streams, a browser tab three (market, markets list, chart).