← tickerbot.io
View as markdown

State over time

GEThttps://api.tickerbot.io/v2/series

Any signals for any tickers on one shared time grid — up to 50 tickers by 25 columns per call.

string[]

Comma-separated symbols, up to 50 (POST accepts a JSON array). Exactly one of tickers or ticker is required; when both are passed, ticker wins — so sending both silently narrows the request to one symbol.

string

Single-symbol form — /v2/series?ticker=AAPL is ticker history in its canonical spelling. Exactly one of ticker or tickers is required.

string[]

Up to 25 columns (POST accepts an array): OHLCV names, signals, and your custom signals, 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. fields accepted as an alias.

enumdefault 1d

Grid granularity. 1w resamples the daily tier weekly (Monday-keyed); 1q is the fiscal-quarter grid.

1mOne minute. The finest stored tier; carries the intraday column subset and ~1,100 of ~13,700 tickers.
1hOne hour. Stored tier, intraday column subset, full universe.
1ddefaultOne 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.
1qOne fiscal quarter. Serves quarterly fundamentals on the fiscal grid; cannot mix with daily columns in one request.
string

Earliest timestamp (inclusive), YYYY-MM-DD or ISO. 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.

string

Latest timestamp (inclusive), YYYY-MM-DD or ISO.

string

Point-in-time read: ONE row 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, /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 row of whoever traded it then, so tickers=SHLD&asof=2010-06-30 returns Sears Holdings' price and asof=2026-01-01 returns the Global X defence ETF. Returns the most recent row at or before the instant, so a date inside a trading gap gives the last row before it. At interval=1q the anchor is the date the quarter was REPORTED (earnings release / filing), not fiscal period end — you get the latest quarter that was public knowledge at the instant, with restatements after it excluded.

integerdefault 252

Grid 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 rows per page — over THAT cap is an explicit 400.

string

Opaque cursor from the previous response — every ticker pages backward in lockstep on the shared grid, no per-ticker gaps or duplicates.

boolean

Only rows 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 row 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 row has no predecessor and yields no edge. A flip is dated by the state table and does not move with the column list: one recorded on a non-trading carry row keeps that date, with any bar columns null on that row (no bar exists there).

as_ofstring

Server time this response was assembled (ISO 8601).

intervalstring

The grid granularity served.

tickersarray

Symbols in the response, echoed.

columnsarray

Columns in the response, echoed.

countnumber

Rows per ticker in this page.

next_cursorstring

Opaque token for the next page; `null` on the last page. Pass it back as `cursor`.

_metaobject

Per-column `sources` (`bars`, `state`, or `custom` for your own signals; `earnings`/`statements` at 1q) and per-ticker `coverage`, plus `non_trading_days_dropped` / `transitions_only` / `from_defaulted` when they apply. `deprecated_columns` lists any column you named under its pre-2026-09-07 spelling that was served under its current name (`requested`, `use`, `note`).

seriesobject

Keyed by ticker: an array of flat rows, chronological, each keyed `t` plus the columns you asked for.

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 signal mix, over the tickers × limit cap, or transitions_only without a boolean signal.
401
Missing or invalid API key.
  • The join across the OHLCV bar store and the indicator and boolean state tables that would otherwise take N history calls and a hand-rolled merge. Those two stores genuinely disagree — state has rows on non-trading days, intraday bars can lag behind state — so the endpoint owns the alignment policy: a missing cell is null, never a silently dropped row, and _meta reports per-column sources plus per-ticker coverage so a gap is always visible.
  • Column names resolve by source, invisibly at the call site: open/high/low/close/volume/vwap/trades (or o/h/l/c/v/vw/n) read licensed OHLCV bars; every signal on the schema page reads the state tables; your own custom signals compile per-row and behave exactly like built-ins.
  • With no columns the default set matches the deprecated Ticker history — a bare /v2/series?ticker=AAPL IS ticker history in its canonical spelling.
  • 1m / 1h / 1d are stored tiers. 1w is 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-weighted vwap — null for a zero-volume week), rows keyed by the week's Monday.
  • 1q serves quarterly fundamentals (eps, eps_estimate, eps_surprise, eps_surprise_pct, revenue, gross_profit, free_cash_flow) on the fiscal grid — rows keyed by calendar quarter (2026-Q2) with each ticker's exact fiscal_period and reported, the date the quarter was announced (null when unknown). reported is the axis a point-in-time backtest filters on: the quarter's numbers were not knowable before it. Quarterly columns cannot mix with daily ones in one request — the grids are not joinable.
  • transitions_only=true filters rows 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). Numeric-threshold flips ("when did rsi_14 cross 70") are an as-of question, not a transitions one.
  • For charting, Bars is its own family on purpose: sub-hour intervals (1s–30m), fetch-on-miss coverage, and the compact array shape live there. Series is the analytical read; bars is the chart read.
  • Both GET and POST are supported — POST takes the same parameters in a JSON body and accepts real arrays for tickers/columns.
  • All-time — series history is never windowed.
  • At 1q, the two sources land at different times: eps arrives with the earnings announcement while statement signals (revenue, gross_profit, free_cash_flow) arrive with the filing. So the most recent quarter routinely carries an eps with revenue: null — a normal reporting lag, not a coverage gap. reported dates the announcement.
  • ticker (singular) and tickers are both accepted; when both are present, ticker wins.
  • Caps: 50 tickers, 25 columns, limit ≤ 1000, tickers × limit ≤ 25,000 rows per page. Over-cap tickers, columns, and tickers × limit are explicit 400s; an over-cap limit alone is clamped to 1000 (house convention — limit=10000 means "max").
  • On a mixed bars+state daily request, spine rows 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_only requests are exempt: their output is already sparse, so carry rows are never dropped and a flip recorded on one keeps its original date no matter which columns ride along (bar columns are null on such a row and count in _meta.coverage.*.missing_bar_cells). Before 2026-08-10, adding a bar column re-dated such flips to the next trading day.
  • Ticker history and Signal history return the same data for one ticker / one signal in their original envelopes — kept stable for existing integrations. New integrations should read series.
Flips only: when did AAPL cross its 200-day, with price at the flip
curl "https://api.tickerbot.io/v2/series?ticker=AAPL&columns=above_sma_200,close&transitions_only=true&from=2026-02-18" \
  -H "Authorization: Bearer YOUR_KEY"
Response
{
  "as_of": "2026-08-11T23:23:33.317Z",
  "interval": "1d",
  "tickers": ["AAPL"],
  "columns": ["above_sma_200", "close"],
  "count": 2,
  "next_cursor": null,
  "_meta": {
    "sources": { "above_sma_200": "state", "close": "bars" },
    "coverage": { "AAPL": { "rows": 2, "missing_bar_cells": 0 } },
    "transitions_only": true,
    "transition_drivers": ["above_sma_200"]
  },
  "series": {
    "AAPL": [
      { "t": "2026-03-30", "above_sma_200": false, "close": 246.63, "transitions": { "above_sma_200": "exit" } },
      { "t": "2026-03-31", "above_sma_200": true,  "close": 253.79, "transitions": { "above_sma_200": "enter" } }
    ]
  }
}
Quarterly fundamentals on the fiscal grid
curl "https://api.tickerbot.io/v2/series?ticker=AAPL&columns=eps,revenue&interval=1q&limit=2" \
  -H "Authorization: Bearer YOUR_KEY"
Response
{
  "as_of": "2026-08-11T23:23:33.317Z",
  "interval": "1q",
  "tickers": ["AAPL"],
  "columns": ["eps", "revenue"],
  "count": 2,
  "next_cursor": "eyJiZWZvcmVfdHMiOiIyMDI2LVExIn0",
  "_meta": {
    "sources": { "eps": "earnings", "revenue": "statements" },
    "coverage": { "AAPL": { "rows": 2 } }
  },
  "series": {
    "AAPL": [
      { "t": "2026-Q1", "fiscal_period": "2026-03-31", "reported": "2026-04-30", "eps": 2.01, "revenue": 111184000000 },
      { "t": "2026-Q2", "fiscal_period": "2026-06-30", "reported": "2026-07-30", "eps": 1.91, "revenue": null }
    ]
  }
}