Skip to main content
WSS
The OHLCV WebSocket emits one frame per bar update for each (pool, timeframe) you subscribe to. You get mid-bar updates while a bar is open (is_closed: false) and a final update on close (is_closed: true). This is the right channel when you want to render a live chart or trigger logic on bar close. For one-shot history, use /api/v1/candles and /api/v1/candles/latest. For raw per-swap data, use WebSocket: swaps.

Endpoint and auth

Authenticate either via Bearer header (server) or query string (browser) — /ws/ohlcv accepts both, same as /ws/swaps:

Subscribe

After the connection is up the server sends a hello frame:
Then send a subscribe. Both pair_addresses and timeframes are required — the server will reply with {"error": "invalid subscribe: timeframes empty"} (or similar) if either is missing.
Server ack:
This first frame is the one-shot, backward-compatible path: a client that only ever sends it sees zero change from before. pairs is the distinct pool count, subjects is the number of live (pool, timeframe) pairs, and op mirrors status.
A subject is one (pair_address, timeframe) pair — the unit the stream actually fans out on. A subscribe of 3 pools × 2 timeframes is 3 pairs but 6 subjects.

Add / remove / unsubscribe (mid-stream)

Once you’re subscribed you can change the watched symbol set without reconnecting by sending more frames on the same socket. This is what lets a chart or watchlist UI swap the active pool, or add/drop timeframes, in place. Every mutating frame carries an op. Each (pair_address, timeframe) pair it expands to is a subject; the ack’s pairs/timeframes/subjects always report the new total live set after the op — not just the delta.

Add symbols

Ack with the new totals (now 2 pools × the union of timeframes):

Remove symbols

Unsubscribe (clear everything)

Replace the whole set

A later frame with op: "subscribe" (or with no op — absent defaults to subscribe) replaces the entire live set with the new one:
This reset behaviour is the opposite of the swaps WebSocket. On /ws/ohlcv, to widen the set you must use op: "add" — sending another subscribe (or an op-absent frame) discards what you had. The frame’s op field is what the server reads; the legacy type field is ignored.
The replace is atomic: if the new set would exceed the per-connection subject cap, the replace is rejected and your prior subscription stays fully intact.

Frame shape

Limits and errors

Two independent limits apply: Mid-stream errors are non-fatal — the socket stays open and a later valid frame still works. (Only an error on the initial subscribe frame closes the connection, as before.)
  • Bad frame / unknown op{ "error": "invalid subscribe: <detail>" } and the socket stays open. An unknown op comes back as { "error": "invalid subscribe: unknown op: <op>" }.
  • Per-frame pool cap{ "error": "invalid subscribe: too many pair_addresses; max 1000" }.
  • Per-connection subject cap → an add or subscribe-replace that would push the live set past the cap is rejected atomically — no partial apply, and your existing subjects keep delivering:

Minimal TypeScript client

If you’re rendering a live chart, key your local bar store by (pair_address, timeframe, timestamp) and overwrite the entry on every frame for that key — the latest frame is always the freshest snapshot of that bar. When is_closed: true arrives, that bar is final.

Changing the watched set at runtime

A watchlist or chart UI that switches the active pool sends add / remove on the same open socket — no reconnect. Helpers, and an ack handler that reads back the new live totals:
Use op: 'subscribe' (or an op-absent frame) only when you intend to reset the whole set — it discards the current subscription. To widen, always use op: 'add'. For reconnect strategy, gap-filling against /api/v1/candles, and keepalive guidance, see Reconnect & backpressure.

Programmatic spec

The full message contract for this channel — and the other two WebSocket streams — is published as an AsyncAPI 3.0 document you can feed into client generators, validators, or an LLM.
api_key
type:httpApiKey

?api_key=ohlcv_live_sk_… appended to the connection URL. Browser-friendly; the only option in environments where you can't set headers.

Subscribe / add / remove / unsubscribe
type:object

Op-tagged frame that mutates the live (pool x timeframe) set. The FIRST frame subscribes; later frames on the same socket can add/remove/unsubscribe or subscribe (reset) without reconnecting. op absent = subscribe = REPLACE.

Candle update
type:object

One bar update for a subscribed (pool, timeframe). NOTE: volume_sol is in lamports despite the name (divide by 1e9 for SOL); volume_token is in base units (divide by 10**quote_decimals).

Connect hello
type:object

Sent once on connect with a UUID client_id and the index inception timestamp.

Subscribe / add / remove ack
type:object

Sent after each successful op. status and op echo the op (subscribed/added/removed/unsubscribed). pairs/subjects are the new LIVE TOTALS after the op (not a delta). A subject = one (pool, timeframe) pair.

Stream error
type:object

Validation failure, auth issue, or server-side error. Connection usually stays open after a recoverable error.