Push, don't poll
Two public SSE endpoints carry every price update and trade in real time — the same streams the site renders.
Updated
GET /tokens/stream — global ticks
One event per token that traded in an indexer sync, plus a coarse-grained refresh signal. This is the stream behind the discover and portfolio lists.
| Event | Fires | Payload |
|---|---|---|
| tick | Per token per sync that saw a trade | PriceTick — the token's latest price state |
| refresh | Once per sync that wrote trades | A signal to re-fetch /tokens — cheaper than polling the list |
- tick
- Fires
- Per token per sync that saw a trade
- Payload
- PriceTick — the token's latest price state
- refresh
- Fires
- Once per sync that wrote trades
- Payload
- A signal to re-fetch /tokens — cheaper than polling the list
curl -N https://api.vectr.bot/tokens/streamGET /tokens/:address/stream — per-token candles
Streams one token's trades as they index and maintains the candle for the requested resolution. The stream behind the token-page chart.
| Event | Payload |
|---|---|
| bar | {id, quoteUsd, bars}: the USD bars that changed, including flat gap bars — upsert by time |
| trade | {trades}: the trades folded into those bars, oldest first |
| reset | {}, only when a resume missed too much to replay — drop local state and refetch /ohlcv |
- bar
- Payload
- {id, quoteUsd, bars}: the USD bars that changed, including flat gap bars — upsert by time
- trade
- Payload
- {trades}: the trades folded into those bars, oldest first
- reset
- Payload
- {}, only when a resume missed too much to replay — drop local state and refetch /ohlcv
| Param | Default | Notes |
|---|---|---|
| res | 5m | 1m | 5m | 15m | 1h | 4h | 1d — anything else falls back to 5m |
| from | — | Unix seconds; replay bars from that point (at most 600 buckets) before going live |
| Last-Event-ID | — | Request header — resume a dropped connection without a gap. bar and trade carry the id; EventSource sends it back for you |
- res
- Default
- 5m
- Notes
- 1m | 5m | 15m | 1h | 4h | 1d — anything else falls back to 5m
- from
- Default
- —
- Notes
- Unix seconds; replay bars from that point (at most 600 buckets) before going live
- Last-Event-ID
- Default
- —
- Notes
- Request header — resume a dropped connection without a gap. bar and trade carry the id; EventSource sends it back for you
// On a server: npm i eventsource
import { EventSource } from "eventsource";
const es = new EventSource("https://api.vectr.bot/tokens/0xTOKEN/stream?res=1m");
es.addEventListener("bar", (e) => {/* upsert JSON.parse(e.data).bars by time */});
es.addEventListener("trade", (e) => {/* append JSON.parse(e.data).trades to the tape */});
es.addEventListener("reset", (e) => {/* drop local state, refetch /ohlcv */});Browser CORS allows only Vectr's own sites, so an EventSource on a page from another origin is refused. Hold the stream on your server and relay it to your page.
Conventions worth knowing
Bars share the REST candle conventions: bucket = floor(ts / resolution), quiet buckets are flat at the previous close, volume is quote-asset notional. The same math serves REST, live streams and reconnect replay — a bar means the same thing on every path.
SSE, not WebSocket
These are plain server-sent events — one connection, server→client only. Any HTTP client that holds the connection open works; there is no socket protocol to implement.