Get a ticker's history
https://api.tickerbot.io/ v2/ tickers/ {ticker}/ historyReturns the signals of one ticker or a comma list of up to 50 in the path (a screen's matches, say) over time, all-time: up to 25 signals in columns, every ticker on one shared grid.
Path parameters
string[]requiredTicker symbol, or a comma-separated list (up to 50) on one aligned grid.
Query parameters
stringEarliest timestamp (inclusive), YYYY-MM-DD or ISO. At 1q and 1y it bounds the fiscal period end. Intraday requests default to a recent window (1m: 7 days, 1h: 60 days) — the cursor keeps walking further back window-by-window, or pass from to widen it up front.
stringLatest timestamp (inclusive), YYYY-MM-DD or ISO. At 1m/1h a bare date on from or to is the ET calendar day for stocks and ETFs, and the UTC day when the request includes crypto or FX.
stringPoint-in-time read: ONE result per ticker (the state at that instant) rather than a range. YYYY-MM-DD or a full ISO timestamp, the same meaning asof carries on /v2/tickers/{ticker}, /v2/scan and /v2/signals. Cannot be combined with from/to or cursor (400) — a point and a window are contradictory, and limit has no meaning under it. It also resolves WHICH COMPANY held the symbol at that instant: a ticker that changed hands returns the state of whoever traded it then, so /v2/tickers/SHLD/history?asof=2010-06-30 returns Sears Holdings' price and asof=2026-01-01 returns the Global X defense ETF. Returns the most recent result at or before the instant, so a date inside a trading gap gives the last result before it; on the 1d and 1w grids a timestamp returns the previous session's result, never that day's close. Also: next_cursor is always null (every requested ticker is on the one page). A ticker with no data on the grid at or before the instant (outside the minute tier, say) comes back as an empty array with _meta.coverage[ticker].rows: 0, never a 404. A bare date on the 1m/1h grid is accepted and means the last result of that day: the ET calendar day for stocks and ETFs, the UTC day for crypto and FX (the state reads 400 that combination; this grid read does not). The look-back is the grid's window: 1d walks back without limit, 1h 60 days and 1m 7 days before the instant. At interval=1q a quarter is visible from its available_at — when the market could first trade on it: 9:30 AM ET on the report date for a pre-market earnings release, else 9:30 AM ET of the next session; statements the session after filing — and a bare date means that day's 4 PM ET close, so you get the latest quarter that was public knowledge at the instant, with restatements after it excluded: /v2/tickers/AAPL/history?interval=1q&asof=2026-07-30 returns 2026-Q1, asof=2026-07-31T13:30:00Z 2026-Q2 (the June quarter was reported after the close on 2026-07-30). See availability. At interval=1y a fiscal year is visible from its available_at — 9:30 AM ET of the first session after the ORIGINAL annual report was filed — and a bare date means that day's 4 PM ET close: /v2/tickers/AAPL/history?interval=1y&asof=2025-10-31 returns fiscal 2024, asof=2025-11-03 fiscal 2025 (the 10-K was filed after the close on Friday 2025-10-31). Response time: under 1.5 s cold, under 0.6 s warm.
enumdefault 1dGrid granularity. 1w resamples the daily tier weekly (Monday-keyed); 1q is the fiscal-quarter grid; 1y is the fiscal-year grid of annual statements. This is the grid, not a state tier: there is no auto here and nothing blends — under asof you get the last result on this grid, and a column the grid does not carry is a 400.
1m | One minute. The finest stored tier; carries the intraday column subset for the most liquid tickers only — _meta.sources on a blended as-of read reports how many at that instant. |
1h | One hour. Stored tier, intraday column subset, full universe. |
1ddefault | One day. The full-history, full-column tier — the only grain that carries daily-only columns (SMAs, RSI, fundamentals). |
1w | One week, resampled: state columns take the week’s last observation, bars aggregate, results keyed by the Monday. |
1q | One fiscal quarter. Serves quarterly fundamentals on the fiscal grid; cannot mix with daily columns in one request. |
string[]Up to 25 columns: signals, your custom signals and OHLCV names, freely mixed. Omitted → the ticker-history default set (price, change_1d_pct, relative_volume, market_cap), intersected with what the interval carries. At 1q, columns is required and quarterly-only; at 1y, required and annual-only (the list is under Notes).
booleanOnly results where a boolean signal changed state. Accepted spellings: true/1/yes and false/0/no (case-insensitive) — anything else is a 400, never silently off. Requires at least one boolean signal (built-in boolean or custom signal); each returned result carries transitions: {column: "enter"|"exit"}, and _meta lists the driving columns. Strict truth: only literal true is "on", so null → true is an enter and true → null an exit (a backfill boundary reads as an edge). Edges need a prior observation — on the oldest page of a walk the first result has no predecessor and yields no edge. A flip is dated by the signal's history and does not move with the column list: one recorded on a non-trading carry entry keeps that date, with any bar columns null on that result (no bar exists there).
integerdefault 252Grid steps per page (shared across tickers). Max 1000 — an over-cap limit is clamped to 1000 (house convention, limit=10000 means "max"). Separately, tickers × limit may not exceed 25,000 results per page — over THAT cap is an explicit 400.
stringOpaque cursor from the previous response — every ticker pages backward in lockstep on the shared grid, no per-ticker gaps or duplicates.
Returns
as_ofstringServer time this response was assembled (ISO 8601).
intervalstringThe grid granularity served.
tickersarraySymbols in the response, echoed.
columnsarrayColumns in the response, echoed.
_metaobjectThis endpoint's own keys: per-ticker coverage (rows, and missing_bar_cells when a bar column is read on a state spine), non_trading_days_dropped, transitions_only / transition_drivers and on an intraday range read from_defaulted with a note. Shared keys: see the _meta reference.
countnumberResults in this page, across all tickers.
next_cursorstringOpaque token for the next page; null on the last page. Pass it back as cursor.
seriesobjectKeyed by ticker: an array of flat objects, chronological, each keyed t plus the columns you asked for.
Status codes
| Code | Meaning |
|---|---|
200 | Success — the response shape is documented under Returns above. |
400 | Bad interval/bounds, unknown signal (invalid_query), daily-only signal at an intraday interval, quarterly/daily or annual/daily signal mix, over the tickers × limit cap or transitions_only without a boolean signal. |
401 | Missing or invalid API key. |
Notes
- Path history:
GET /v2/series?tickers=NVDA,AMD(and its POST form) is the older spelling of this read. It keeps working, permanently, with the same response; its responses carry aLinkheader naming this path. - Signals and bars come from different stores that don't always line up; a missing cell is
null, never a dropped result, and_metareports each column's source and each ticker's coverage. - Names resolve by source, invisibly at the call site: every signal in the catalog reads its stored history, your own custom signals compile per result and behave exactly like built-ins, and
open/high/low/close/volume/vwap/trades(oro/h/l/c/v/vw/n) read OHLCV bars. 1m/1h/1dare stored tiers.1wis a real weekly resample: each signal samples the week's last observation, bars aggregate (open of first bar, max high, min low, close of last, summed volume and trades, volume-weightedvwap—nullfor a zero-volume week), results keyed by the week's Monday.1qserves quarterly fundamentals on the fiscal grid:eps,eps_estimate,eps_surprise,eps_surprise_pctand every statement column1yserves (below), under the same names and definitions, except the per-share ones (eps_basic,eps_diluted,shares_basic,shares_diluted; quarterly EPS iseps). Income and cash flow columns cover the quarter; balance sheet columns are at quarter end. Quarterly figures are as first reported, like1y: a quarter a later filing restated keeps its original figures, and the fiscal fourth quarter is the annual report's year minus the first three quarters as first reported. Where a company restated an earlier quarter before its annual report, the four quarters do not add up to the annual figure (MSFT fiscal 2016net_income: quarters 16,496M, annual 16,798M). Results are keyed by calendar quarter (2026-Q2) with each ticker's exactfiscal_period,reported(the date the quarter was announced,nullwhen unknown),available_at(when the market could first trade on it, ISO 8601) andavailable_at_source(what decided it:report_time,filing_dateorassumed).available_atis the axis a point-in-time backtest filters on, and whatasofgates on: a post-market report is dated the report day but tradable only from the next open. All three come from the same report: the earnings release when the quarter has one, else the statement filing. The three revenue breakdown lists (revenue_by_segment,revenue_by_geography,revenue_by_product, below) are quarterly columns too. Quarterly columns cannot mix with daily ones in one request — the grids are not joinable.1yserves annual financial statements, one result per fiscal year from fiscal 2010 on, keyed by the company's own fiscal-year label (t: "2025"; Walmart's fiscal 2026 ended on January 31, 2026). Each result carriesfiscal_year,fiscal_period(the year-end date),reported(the filing date of the ORIGINAL 10-K, 20-F or 40-F, from SEC EDGAR — a later filing that repeats or restates the year never moves it) andavailable_at(9:30 AM ET of the first session afterreported). Columns — income statement:revenue,cost_of_revenue,gross_profit,research_development,selling_general_administrative,depreciation_amortization,total_operating_expenses,operating_income,interest_income,interest_expense,total_other_income_expense,income_before_income_taxes,income_taxes,net_income(attributable to the company: the 10-K "Net income" line),net_income_consolidated(including noncontrolling interests),noncontrolling_interest_income,net_income_common(after preferred dividends),eps_basic,eps_diluted,shares_basic,shares_diluted(weighted averages),ebitda; balance sheet at year end:total_assets,total_current_assets,cash_and_equivalents,short_term_investments,receivables,inventories,property_plant_equipment_net,goodwill,intangible_assets_net,total_liabilities,total_current_liabilities,accounts_payable,debt_current,long_term_debt,total_equity,equity_attributable_to_parent,retained_earnings; cash flow:operating_cash_flow,investing_cash_flow,financing_cash_flow,capital_expenditures(negative, an outflow),dividends_paid(negative),change_in_cash,free_cash_flow(operating cash flow minus capital expenditures). Annual columns cannot mix with daily or quarterly ones in one request.- At
1y: money is in US dollars; foreign filers' figures arrive already converted by the data vendor (at about the fiscal-year-end rate). The figures are as first reported: each year shows what its original annual report said, dated by that filing. Where a later filing restated a year, the original figures stay; a line the original report did not state on the same basis is null for that year (most oftenebitda), never a later restated value. Per-share columns are on today's share basis (split-adjusted: AAPL fiscal 2010eps_dilutedis 0.54) and arenullfor ADRs, whose reports are per ordinary share, not per ADR (_meta.coveragesays so). A company with several share classes has one EPS figure (Berkshire Hathaway: per Class B share). Banks'revenueis gross (interest income plus non-interest income), not the "total net revenue" banks headline. The last fiscal year'srevenue_fy,net_income_fy,eps_diluted_fyandfy_period_endare also signals you can screen on. - Revenue breakdowns at
1qand1y:revenue_by_segment,revenue_by_geographyandrevenue_by_productare list columns, one list per fiscal period, read from the company's own SEC filings (10-K, 20-F, 40-F; 10-Q for quarters — the fourth quarter is inside the annual report and is not derived). Each element is{name, revenue, revenue_usd, share, currency, period_end, period_type, fiscal_year, fiscal_period}, the same element the signal of the same name carries for the latest period, in the filing's own order and with the company's own line names; a corporate or elimination line that brings the segments to the total carriesreconciling: trueand can be negative. A list is served only when its lines add up to the company's total revenue within 0.5%; otherwise the cell isnull, never an estimate.revenueandshareare in the reportingcurrency;revenue_usdconverts at the average Federal Reserve H.10 rate over the period and isnullfor a currency H.10 does not publish. A fiscal period the statement columns lack still gets a result when a breakdown was filed for it (its scalar columnsnull). Underasof, a breakdown is visible from 9:30 AM ET of the first session after its filing date._meta.sourcesnames thesefilings. Filings from 2011 on. transitions_only=truefilters results down to the state-change edges of the boolean signals — computed by the same shared rule that fires webhooks, so the two cannot disagree — with non-boolean signals riding along as context (the price at the flip). For a numeric threshold ("when did rsi_14 cross 70"), save it as a custom signal (rsi_14 > 70) and pass that withtransitions_only.- A company that changed its ticker reads its whole history under its current symbol:
METAfrom the 2012 IPO,FISVfrom 2003, with the earlier symbol named inprior_symbolson Tickers. A window that ends before the rename resolves to whoever held the symbol on its last day, the same way?asof=does on the ticker read:METAfrom mid-2021 until the rename is the Roundhill ETF that held the symbol then. - At
1q, the two sources land at different times:epsarrives with the earnings announcement while the statement columns (revenue,net_income,operating_cash_flow, …) arrive with the filing. So the most recent quarter routinely carries anepswithrevenue: null— a normal reporting lag, not a coverage gap.reporteddates the announcement;available_atsays when it could be traded. - On a mixed state+bars daily request, spine entries on non-trading days (weekends/holidays) are dropped and counted in
_meta.non_trading_days_dropped— they could never carry OHLCV and would read as gaps.transitions_onlyrequests are exempt: their output is already sparse, so carry entries are never dropped and a flip recorded on one keeps its original date no matter which columns ride along (bar columns arenullon such a result and count in_meta.coverage.*.missing_bar_cells).
More examples
Flips only: when did NVDA cross its 200-day, with price at the flip
curl "https://api.tickerbot.io/v2/tickers/NVDA/history?from=2026-04-05&columns=above_sma_200,close&transitions_only=true" \
-H "Authorization: Bearer YOUR_KEY"Quarterly fundamentals on the fiscal grid
curl "https://api.tickerbot.io/v2/tickers/NVDA/history?interval=1q&columns=eps,revenue&limit=2" \
-H "Authorization: Bearer YOUR_KEY"Annual statements on the fiscal-year grid
curl "https://api.tickerbot.io/v2/tickers/NVDA/history?interval=1y&columns=revenue,net_income,eps_diluted&limit=2" \
-H "Authorization: Bearer YOUR_KEY"