Skip to main content
Get price history has two modes, and picking the wrong one is the usual cause of a chart that scrolls forever. A plain window answers “what happened between these two times”. countBack answers “give me the N bars before this point” — the scroll-back page — and it outranks from when both are sent.
1

Ask for the default window

With no range at all, the route answers the most recent 500 bars or so. It is the fastest way to get something on screen.
Bars come back as { t, o, h, l, c, v } with t in epoch seconds.
2

Narrow it to a window

from and to are epoch seconds, inclusive at both ends.
The window’s width is capped in bars by limits.maxBars from the limits route — the same number that caps countBack. Ask for a wider span at a finer timeframe and you are asking for more bars than the route will serve.
3

Page backwards with countBack

countBack asks for the last N bars at or before to. This is the call a chart makes when the user drags the view left.
Set to to the timestamp of the oldest bar you currently hold and ask again for the next page. countBack outranks from, so send to and countBack and leave from out of it.
4

Hand over to the stream

Once the backfill is on screen, open a bar stream for the same instrument and timeframe. On every connect the stream replays a full snapshot and then applies live bar events, so the two views converge without you reconciling them.

The two signals that end a scroll-back

Both are present only when they are true, so treat an absent field as false. A chart that ignores noData keeps asking for pages that will never exist. A chart that ignores stale shows a weekend as if the market were open.

Spread expressions

The instrument may be an arithmetic expression over instruments rather than a single symbol — ES-NQ, 1/ESU6, (ES+NQ)/2. An exact catalog match always wins over arithmetic: the slash pair BTC/USD is the symbol, never a division. The same expression resolves under symbol details as type spread, with no tick and no quote surface, and it streams like any other instrument — though any single leg’s refusal refuses the whole spread.

When history refuses

On futures the 503 body carries a typed code, and the three are different problems: Anything else is market_data_unavailable.

The pattern, in one line

Fetch the limits once, resolve the symbol once, backfill a window, then stream — and page back with countBack until noData says stop. Everything else is presentation.

Where to go deeper