Charts
Goal: a candlestick chart for any indexed token on Arc or Robinhood Chain that loads in one call, pages backwards for history, and updates live.
const A = "https://api.getchord.xyz/v1";const { candles, tf, source } = await fetch(`${A}/tokens/chart/${addr}?tf=1h`).then((r) => r.json());// candles: [{ t, o, h, l, c, v }] oldest first, up to 200Timeframes: 1m · 5m · 15m · 1h · 4h · 1d · 1w. v is USD volume in the bucket. source: "db" means Chord’s own tape. A 404 UNKNOWN_TOKEN means the address is neither on a curated list nor a side of an indexed pool.
Page into history
Section titled “Page into history”Pass the oldest t you have as before; each page is 200 candles.
async function older() { const first = candles[0]?.t; const page = await fetch(`${A}/tokens/chart/${addr}?tf=1h&before=${first}`).then((r) => r.json()); candles.unshift(...page.candles);}Subscribe to the same token and timeframe on the WebSocket. The open candle is re-sent as it changes; closed: true seals it.
ws.send(JSON.stringify({ op: "sub", channel: "candles", token: addr, tf: "1h" }));ws.onmessage = (e) => { const m = JSON.parse(e.data); if (m.op !== "candle" || m.token !== addr || m.tf !== "1h") return; const last = candles.at(-1); if (last && last.t === m.candle.t) Object.assign(last, m.candle); else candles.push(m.candle);};Switching timeframes: unsubscribe the old tf, fetch the new, subscribe the new. Eight channels per connection is enough for a chart, a tape and the price feed.
Trade markers
Section titled “Trade markers”For a connected wallet, GET /portfolio/{wallet}/trades?chain=5042 returns its buys and sells (t, side, usd, tokenAmt, token, tx); filter by token and draw markers at t. For the whole market, GET /tokens/trades/{address}?min=1000 gives the large prints.
A bucket with no trades has no candle. Draw the gap or carry the last close forward — but do not invent a bar; the API does not.