Concepts

As-of

One parameter, one rule, everywhere it appears. asof rewinds the whole computed table to a past moment — the state as it actually stood then, not as it looks now.

One rule across every endpoint

asof means the same thing on scan, on signal matches, and on a ticker read.

Pass asof and you get the row (or the match set) as it stood at that instant: who matched this scan, who matched this signal, or one ticker’s whole row — same parameter, same semantics. A YYYY-MM-DD date returns the state at that day’s close; a full ISO timestamp returns it at that intraday moment. _meta.resolution reports the granularity actually served (minute, hourly, or daily).

The three variants

Same parameter on a cross-section, a match set, and a single ticker.

Many tickersas-of scan:

curl -X POST https://api.tickerbot.io/v2/scan \
  -H "Authorization: Bearer YOUR_KEY" \
  -d '{"q":"above_sma_200","asof":"2026-03-03"}'

One signalas-of matches:

curl "https://api.tickerbot.io/v2/signals/at_52w_high?asof=2026-03-03" \
  -H "Authorization: Bearer YOUR_KEY"

One tickeras-of snapshot. Two spellings return the identical row, so use whichever reads better in your code:

curl "https://api.tickerbot.io/v2/tickers/AAPL?asof=2026-03-03" \
  -H "Authorization: Bearer YOUR_KEY"

# same response:
curl "https://api.tickerbot.io/v2/tickers/AAPL/history?asof=2026-03-03" \
  -H "Authorization: Bearer YOUR_KEY"

A bare YYYY-MM-DD gives the row at that day’s close; append a time (2026-03-03T14:30:00Z) for the intraday state.

The plan window

A depth gate, not a feature gate — the market convention.

asof reaches back 30 days on the Free plan and is unlimited on every paid plan. Beyond your window the request returns 403 asof_tier_required. This is the one place a plan bounds how far back you can look — every endpoint that takes asof shares the identical window.

Point-in-time is a different promise from series history, which is all-time on every plan. History of anything you can name is free and all-time; rewinding the whole market to a past cross-section is the paid capability.

Staleness: “the state AT that instant”

asof answers what was true then — not the last thing known.

The row served must be within the tier’s staleness window (14 days for daily) of the instant you asked for. If nothing that fresh exists — a delisted ticker, an instant before it started trading — the ticker 404s with a last_available pointer rather than handing back a stale row. When you want the last known state instead of the state at a moment, read /history/1d?limit=1.

Coverage: a null can mean “not yet backfilled”

Most fields reconstruct exactly; a few vendor-sourced ones are forward-only.

Price, technical indicators, and financial-statement fields reconstruct to the exact date. A few vendor-sourced fields (forward_pe, short_interest, ownership percentages, analyst estimates) are populated forward-only, so an older snapshot may return null for them while historical backfill is in progress. A null there means “not yet backfilled,” not “no value existed.”

News and events don't take asof

Archives with a real timestamp filter by time directly — there's nothing to reconstruct.

asof exists because scan, signals, and tickers reconstruct the computed state at a past instant. News and events don’t need it: each row already carries the real moment it happened (time_published, the event ts), so “as of a past date” is just a WHERE filter on that column (or since/until) — no asof parameter, no staleness window, no plan gate. That’s the one place the model differs, and it’s consistent: logs filter by their timestamp; reconstructed state takes asof.