← tickerbot.io
View as markdown

Get bars

GEThttps://api.tickerbot.io/v2/bars/{ticker}/{interval}

OHLCV bars from 1-second through monthly. The prices underneath the table.

string[]required

Ticker symbol, or a comma-separated list (up to 50) for a bulk response keyed by symbol.

enumrequired

Bar interval. 2h/4h roll up hourly bars; 1w/1mo roll up daily bars into calendar weeks (Monday start) and months — the bar's t is the bucket start (UTC), and with asof the last bucket is the week/month to date.

1sOne-second bars. Bars only, active universe, back-filled on demand.
1mOne minute. The finest stored tier; carries the intraday column subset and ~1,100 of ~13,700 tickers.
5mFive-minute bars. Bars only.
15mFifteen-minute bars. Bars only.
30mThirty-minute bars. Bars only.
1hOne hour. Stored tier, intraday column subset, full universe.
1dOne day. The full-history, full-column tier — the only grain that carries daily-only columns (SMAs, RSI, fundamentals).
1wOne week, resampled: state columns take the week’s last observation, bars aggregate, rows keyed by the Monday.
string

Window start (inclusive): YYYY-MM-DD, ISO timestamp, or epoch-ms. Combines with to for an explicit window; page within it using cursor. Mutually exclusive with asof and before (400).

string

Window end (inclusive): a bare YYYY-MM-DD means through the end of that day, same as series. Mutually exclusive with asof and before (400).

string

Point-in-time: the most recent bar whose period had **closed** at or before that moment. A bare YYYY-MM-DD means that day's close. A full timestamp means the last FINISHED bar — at 10:00 ET on a Wednesday the day's close has not happened, so 1d returns Tuesday's bar. Returns one bar unless you also pass limit, which gives the last limit closed bars. Mutually exclusive with before/cursor (400). Unlimited depth.

boolean

Default true: prices are split-adjusted — restated after each later split, as the tape is, so a series is continuous across a split. false returns the price as it printed that day (a name that later did a 1:10 reverse split reads 21.4 adjusted and 2.14 on the tape), which is what a broker fill or a chart from that time shows. Volume scales the other way. Un-adjusted on read from the splits table; the store is untouched.

enumdefault all

Sub-hour intervals only. all (default) includes pre- and post-market bars. regular keeps bars whose start is in 09:30–16:00 ET (DST-aware). Why you might want it: the vendor buckets trades by SIP report time, and late-reported off-exchange (Form T) prints on thin names can land 20 min to hours late in a pre-market minute — a $1.70 print at 08:13 ET on a $3.85 stock. Daily high/low are untouched by those. limit counts after the filter; paging still works.

integerdefault 100

Most-recent N bars. Max 1000 — an over-cap value is clamped, not an error.

string

Return the N bars ending strictly before this date/timestamp — back-paging. Mutually exclusive with cursor (they are the same control — a 400 when both are sent).

string

Continuation token from a prior response's next_cursor; sugar for before (sending both is a 400; a blank cursor= counts as absent), and the way to page inside a from/to window.

as_ofstring

Server time this response was assembled (ISO 8601).

tickerstring

The symbol you asked for.

intervalstring

The bar size served.

adjustedboolean

Whether the bars are split-adjusted — `true` unless you passed `adjusted=false`.

sessionstring

The session filter applied: `all` (default) or `regular` (09:30–16:00 ET, sub-hour intervals only).

countnumber

Bars returned in single-symbol mode; the number of SYMBOLS in bulk mode.

coveragestring

Why the page looks the way it does: `covered` when bars were found, `no_data` when the vendor has none for the window, `not_in_minute_tier` when a sub-hour interval was asked of a symbol the minute store does not carry.

next_cursorstring

Opaque token for the next page; `null` on the last page. Absent on bulk (comma-list) requests, which are unpaged. Absent on bulk requests — page bulk symbol-by-symbol.

notestring

Present only when there is something to disclose about how the page was served: the first on-demand fetch for an untiered symbol (explains the latency; later calls are stored), or a `1s` page served from the local store because the provider could not be reached. Bulk responses carry `notes[symbol]` instead.

notesobject

Bulk (comma-list) requests only: the per-symbol disclosures, keyed by symbol, in place of `note`.

barsarray

OHLCV bars, chronological, in the compact array shape. Bulk requests key this by symbol instead.

200
Success — the response shape is documented under Returns above.
400
Invalid interval; no, malformed, or more than 50 symbols; invalid or contradictory range controls (asof with before-paging, before with cursor, from/to combined with either, from after to, or a malformed bound); a non-positive-integer limit; or an invalid cursor.
401
Missing or invalid API key.
  • Bars are the historical stock data: daily bars run back to each ticker's first day of coverage (2003 for the oldest equities; see Tickers for depth by class), delisted names keep their bars, and intraday bars run from 1-second up. History is not only price: ?asof= on any state read rewinds a whole row, and Series pulls any columns over time on one grid.
  • Supports point-in-time (asof) and back-paging (before/limit). 1d and 1h cover the full universe with full history; sub-hour intervals cover the active universe and back-fill on demand. Pass a comma-separated symbol list for a bulk response keyed by symbol.
  • Prices are split-adjusted at every interval, and re-adjusted retroactively when a later split lands: a bar from before a 1-for-10 reverse split shows the tape price times 10, so a stock that closed at $2.14 that day reads $21.40 once the split is in. There is no unadjusted option today. To match a fill from your broker, scale by the splits dated after that bar; /v2/events?kind=split lists them.
  • Sub-hour bars (1s through 30m) include pre-market and after-hours prints, bucketed by the SIP report time rather than the execution time. On thin names an off-exchange trade can be reported an hour or more after it executed, so a pre-market bar can carry a wick far from where the market was in that minute. 1d high/low counts regular-session trades only, per SIP rules, so the daily bar never shows those wicks. Compute intraday statistics such as MAE/MFE from regular-session bars (09:30 to 16:00 ET); there is no session filter today.
  • Bars is its own family on purpose, alongside Series: sub-hour intervals, fetch-on-miss coverage, and the compact chart-ready shape live here. To get OHLCV *joined with* indicator or boolean signals on one grid, read series with columns=close,rsi_14,… instead.
  • Available at all intervals. The asof point-in-time param is unlimited-depth — see As-of queries.
  • 2h/4h are rollups of the hourly store and 1w/1mo of the daily store (calendar buckets, t = bucket start), so they carry the same universe and depth as 1h and 1d. Added in v2.32.0 — until then only the dashboard chart could draw them.
  • 1d/1h cover the full universe with full history. Sub-hour (1m/5m/15m/30m) is pre-loaded for the active universe (the minute tier); a symbol outside it is served on demand: the first call fetches from the provider (~3–10s) and stores the result, later calls are sub-second. Each on-demand request fills up to 31 days ending at to/before/now — page further back with next_cursor. That first response carries a note saying so. /coverage reports the same as minute_tier.on_demand — included:false there is not "no data".
  • 1s (1-second) bars are served on demand: from our store when it already covers the request through the latest session, otherwise passed through from the provider and served in the same call (the store is filled by earlier requests, so a full page of older stored bars is never mistaken for the latest ones). Second data is not bulk-backfilled — it accumulates as it is requested. Best paired with a tight before+limit window. When the vendor pass-through is unavailable, the response says so: a note (single-symbol) / notes[symbol] (bulk) flags that the range came from the local store only and may be under-covered.
  • coverage is covered, no_data (universe-wide interval with nothing for the symbol), or not_in_minute_tier — a gap is always explicit, never a silent empty array.
  • Paging is before + limit, with cursor/next_cursor as sugar. Accepts epoch-ms or YYYY-MM-DD; bars come back oldest-first.
  • For an explicit historical window, pass from/to (inclusive; same bound semantics as series) and page inside it with cursor. from/to does not combine with asof (point-in-time) or before (tail-paging) — contradictory range controls are a 400, never a silent pick.
  • The response echoes adjusted and session, so a cached page is self-describing.
  • Path history: this was /v2/tickers/{ticker}/bars/{interval} until 2026-09-14. That spelling keeps serving forever as an alias — same handler, same response, no deprecation headers.
Bulk: 5-minute bars for several symbols
curl "https://api.tickerbot.io/v2/bars/AAPL,MSFT/5m?limit=2" \
  -H "Authorization: Bearer YOUR_KEY"
Response
{
  "as_of": "2026-08-11T22:47:23.948Z",
  "interval": "5m",
  "count": 2,
  "bars": {
    "AAPL": [ { "t": 1786487400000, "o": 304.975, "h": 304.984, "l": 304.955, "c": 304.975, "v": 890 },
              { "t": 1786487700000, "o": 304.975, "h": 304.975, "l": 304.975, "c": 304.975, "v": 2622 } ],
    "MSFT": [ { "t": 1786487400000, "o": 501.9,   "h": 501.9,   "l": 501.846, "c": 501.846, "v": 617 },
              { "t": 1786487700000, "o": 501.845, "h": 501.845, "l": 501.82,  "c": 501.82,  "v": 826 } ]
  },
  "coverage": { "AAPL": "covered", "MSFT": "covered" }
}