← tickerbot.io
View as markdown

Ticker state

GEThttps://api.tickerbot.io/v2/tickers/{ticker}

The full ticker row, every signal on the schema page, for one symbol or a comma list of up to 50. Right now, or with asof, as of any past date.

string[]required

One symbol, or a comma-separated list of up to 50 for a batch response keyed by symbol. Case-insensitive. Equities are bare symbols (AAPL); every other class carries a prefix — rates (R:SOFR), crypto (X:BTCUSD), fx (X:EURUSD). Bare BTC/ETH are US-listed ETFs, not spot crypto. See Tickers.

string

Optional. Target moment as YYYY-MM-DD (that day's close) or an ISO timestamp (that intraday moment) — the same read as it stood then, unlimited depth. Full contract under As of a past date.

enumdefault auto

Grain the past state is reconstructed at: 1m, 1h, 1d, or auto (default). Only valid alongside asof — a live read with interval is a 400. Details under As of a past date.

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.
1dOne day. The full-history, full-column tier — the only grain that carries daily-only columns (SMAs, RSI, fundamentals).
autodefaultLet the server pick the finest grain whose columns and ticker coverage both work out, resolving upward on a miss. Reported in _meta.interval.
as_ofstring

Server time this response was assembled (ISO 8601).

tickerstring

The symbol you asked for, normalised. Single form only.

dataobject

The full ticker row — every signal on the [schema page](/docs/schema). On the list form, an object keyed by symbol, one full row each.

requestedstring[]

List form only — the canonical symbols asked for, de-duplicated, in request order.

countnumber

List form only — how many of `requested` were found.

not_foundstring[]

List form only — the requested symbols we do not track, in request order. An empty array when every symbol was found.

_metaobject

With `asof` only: how the read was resolved — the interval served and requested, whether rows blend intervals, sources and frozen fields. See the as-of read below.

200
Success — the response shape is documented under Returns above.
400
Invalid ticker format, malformed asof, or interval on a live read — interval selects the grain a PAST state is reconstructed at, so it is only valid alongside asof.
401
Missing or invalid API key.
404
Ticker not tracked, or no historical row at or before the requested date.
  • Numeric signals carry their current value and every boolean its current state, so one call answers both "what is it" and "what is it doing".
  • For the same row as of a past date, add ?asof= — see Ticker state (as-of). It means the same thing on the list form.
  • The list form is the batch read: requested echoes the canonical symbols, count is how many were found, data holds one full row per found symbol, and not_found lists the rest in request order. A symbol we do not track is simply absent from data — it never fails the request. Symbols are de-duplicated and canonicalised (aapl → AAPL).
  • For the catalog — which symbols exist and what they are — use GET /v2/tickers. It is identity-only and never returns state.
  • The row's branding_icon_url and branding_logo_url are image endpoints on this API (GET /v2/tickers/{ticker}/icon, /logo): request them with the same Authorization: Bearer header and you get the image bytes with their Content-Type. Null when the issuer has no image on file.
A holdings list in one call
curl "https://api.tickerbot.io/v2/tickers/AAPL,MSFT,X:BTCUSD,ZZZNOTREAL" \
  -H "Authorization: Bearer YOUR_KEY"
Response
{
  "as_of": "2026-09-08T14:22:03.118Z",
  "requested": ["AAPL", "MSFT", "X:BTCUSD", "ZZZNOTREAL"],
  "count": 3,
  "data": {
    "AAPL":     { "ticker": "AAPL",     "name": "Apple Inc.",            "asset_class": "stocks", "price": 304.765, "change_1d_pct": -1.13, "rsi_14": 41.83, "...": "(full row)" },
    "MSFT":     { "ticker": "MSFT",     "name": "Microsoft Corporation", "asset_class": "stocks", "price": 512.21,  "change_1d_pct": 0.42,  "rsi_14": 55.10, "...": "(full row)" },
    "X:BTCUSD": { "ticker": "X:BTCUSD", "name": "Bitcoin / US Dollar",   "asset_class": "crypto", "price": 118402.5, "change_1d_pct": 2.07, "rsi_14": 61.44, "...": "(full row)" }
  },
  "not_found": ["ZZZNOTREAL"]
}

Ticker state (as-of)

GEThttps://api.tickerbot.io/v2/tickers/{ticker}?asof=

The whole wide ticker row as of a past date: booleans, indicators, and the fundamentals known then.

string[]required

One symbol, or a comma-separated list of up to 50 — the list form answers data keyed by symbol, with each symbol's reconstruction under _meta by symbol. Case-insensitive. Equities are bare symbols (AAPL); every other class carries a prefix — rates (R:SOFR), crypto (X:BTCUSD), fx (X:EURUSD). Bare BTC/ETH are US-listed ETFs, not spot crypto. See Tickers.

stringrequired

Target moment as YYYY-MM-DD or full ISO timestamp YYYY-MM-DDTHH:MM:SSZ. A date returns the row at the close of that day; a timestamp returns the row at that moment. A single-ticker read MERGES PER SIGNAL: each signal comes from the finest grain that carries it and has a row at or before the instant, so price can be the 17:45 value while rsi_14 is that morning's daily figure. The row is a blend — _meta.interval is the finest grain present (not the whole row's age), _meta.blended flags it, and _meta.sources / _meta.column_intervals give the breakdown. The response returns the most-recent snapshot within the staleness window (14 days for daily) — the SAME rule as /v2/scan?asof= and /v2/signals/{signal}?asof=, unified 2026-07-27: asof means "the state AT that instant" everywhere. A ticker with no fresh-enough state (delisted, data gap) 404s with last_available and a pointer at the series endpoint for "last known state". Unlimited depth.

enumdefault auto

Grain the past state is reconstructed at: 1m, 1h, 1d, or auto (default). Same name and values as Series, Bars, Scan and Signals — one vocabulary for "which grain" across the API. auto merges PER COLUMN: each column comes from the finest grain that stores it and has a row for this ticker, so price can be the 17:45 value while rsi_14 is that day's daily figure. An explicit grain turns the merge OFF — every column comes from that one tier, or you get a 400/404 naming what is missing. Pin it when you need a row that actually existed at one instant, or one comparable to a scan row. Only valid alongside asof — a live read with interval is a 400.

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.
1dOne day. The full-history, full-column tier — the only grain that carries daily-only columns (SMAs, RSI, fundamentals).
autodefaultLet the server pick the finest grain whose columns and ticker coverage both work out, resolving upward on a miss. Reported in _meta.interval.
as_ofstring

The moment you asked about — the date's close, or the timestamp you passed.

tickerstring

The symbol you asked for, normalised.

_metaobject

How the row was reconstructed: `interval` is the finest grain present, `blended` says whether it mixes grains, `sources` / `column_intervals` give the per-grain breakdown, and `frozen_fields` names the signals that are NOT historized — they are present in `data` carrying their CURRENT values.

dataobject

The full ticker row as it stood at that instant — every signal on the [schema page](/docs/schema).

200
Success — the response shape is documented under Returns above.
400
bad_request — asof missing or not YYYY-MM-DD / YYYY-MM-DDTHH:MM:SSZ.
401
Missing or invalid API key.
404
not_found — the ticker has no historical state at or before the requested date.
  • This is GET /v2/tickers/{ticker} with ?asof= — the same endpoint as the live read, the second tense of the same page because point-in-time is its own question. It is the sibling of Market-wide scan (as-of) and Ticker matches (as-of), under one staleness rule — see As-of queries.
  • For a ticker's values *over time*, use Series instead: as-of answers "what did the row look like at t", series answers "how did it evolve".
  • A missing or malformed asof returns 400 bad_request; a date with no fresh-enough state returns 404 not_found with last_available — the row must be within the staleness window (14 days for daily), the same rule as every other asof surface (unified 2026-07-27).
  • The returned data.date may be earlier than the requested asof (weekend/holiday/gap) — it is the latest daily state within the window on or before that date. See the example: asof=2026-03-01 (a Sunday) returns the 2026-02-27 row.
  • frozen_fields are not historized; they're snapshots of the *current* value. The other signals are correct as of the requested date.
  • Identity follows the symbol's holder at that date. When a different company held the symbol then (a reused symbol, e.g. SHLD in 2010 was Sears, today an ETF), name, cik and composite_figi are that holder's, held_at_asof is true with its tenure_start/tenure_end, _meta.identity names it, and the current holder's sector, industry, asset_type, exchange, asset_class and ticker_category come back null rather than mislabelling the old company. _meta.frozen_fields is empty on such a read.