Lab API Historical API
Alpha · Historical API Replay

Historical API: Point-in-Time Replay

Ask what GEX, gamma flip, VRP, narrative, max pain, or the full stock summary looked like at any minute in history - returned in the same response shape as the live API. Backed by 6.7 B option rows since April 2018.

What's different from the live API

Every endpoint you already know on the live API is mirrored here. Point your existing SDK at a different host, add one query parameter, and you have a backtest-ready data source. No new response shapes to learn - GEX, gamma flip, regime labels, narrative text, VRP percentiles, SVI surfaces and everything else come back in the exact same JSON you already parse.

The analytics run through the same code path as live - so any fix or refinement that lands on api.flashalpha.com shows up here on the next deploy. The only difference is the data store underneath: minute-level quotes and greeks going back to April 2018 instead of the live feed.

Host
historical.flashalpha.com
Auth
Same X-Api-Key as live. Alpha tier on every endpoint.
Quota
Shared with live daily bucket.

The at parameter

Every analytics endpoint takes a required at query parameter - the as-of timestamp. Treated as ET wall-clock (same clock as the stored data). Do not shift by UTC offset.

FormatExampleSemantics
yyyy-MM-ddTHH:mm:ss2026-03-05T15:30:00Minute-level as-of
yyyy-MM-dd2026-03-05Defaults to 16:00 ET (session close)

Intraday-accurate vs EOD-stamped

Not every underlying series is minute-resolution. Here's what moves at the minute you ask for, and what's stamped at the close of that trade day:

Data layerGranularityNotes
Option quotes + greeks (bid, ask, iv, δ, γ, θ, ν, ρ, vanna, charm)1 minute (9:30 → 16:00 ET)Last value per contract at or before at
Stock spot (bid, ask, mid)1 minuteSame
Open interestEODOne value per trade day, applied to all intraday at= on that day
SVI params, forward pricesEOD
Macro: VIX, VVIX, SKEW, MOVE, SPX, VIX9D/3M/6M, DGS10EOD
Realized-vol lookback closes (HV20/HV60)EODLast tick per day

Why this is OK: intraday GEX / DEX / VEX / CHEX shifts are driven by greek + spot changes; OI is dealer-positioning context and barely moves intraday anyway.

Coverage: GET /v1/tickers

The only historical-specific endpoint. Lists every symbol with historical coverage, the date range, and any gaps. Regenerated after every backfill run, so whatever comes back is the current ground truth for what you can query.

GET https://historical.flashalpha.com/v1/tickers

Auth: required (X-Api-Key, Alpha tier)

Query params: symbol=SPY (optional) - returns a single object instead of the wrapped list

curl -H "X-Api-Key: YOUR_API_KEY" \
  "https://historical.flashalpha.com/v1/tickers"

Response 200:

{
  "count": 1,
  "tickers": [
    {
      "symbol": "SPY",
      "coverage": {
        "first": "2018-04-16",
        "last":  "2026-04-02",
        "total_days": 2909,
        "healthy_days": 1972
      },
      "tables": {
        "stocks_days":    2009,
        "options_days":   1972,
        "option_eod_days": 2006,
        "svi_days":        1972
      },
      "gaps": {
        "missing_eod": 3,
        "missing_svi": 36,
        "uncovered_calendar": 3
      },
      "updated_at": "2026-04-14T07:07:36.55353"
    }
  ]
}
FieldMeaning
coverage.first / coverage.lastDate range where every data layer is healthy - you can query any minute inside this window
coverage.healthy_daysTrading days on which every data layer has data
tables.*_daysPer-layer day counts - useful when a single layer is lagging
gaps.missing_eodDays where EOD option data hasn't been pulled yet (usually resolves on the next backfill)
gaps.missing_sviDays without an SVI fit
gaps.uncovered_calendarNYSE trading days that were never pulled (genuine exchange-closed days like 2018-12-05 Bush funeral, 2025-01-09 Carter funeral)
updated_atUTC timestamp of the last coverage refresh

Available symbols. SPY is fully backfilled from 2018-04-16 through 2026-04-02 and extended on every refresh. Additional symbols are backfilled on demand - ask us to prioritize what you need. Live coverage is always queryable at GET /v1/tickers.

Analytics endpoints

Every live analytics endpoint is mirrored with the addition of a required at. Paths, query params, and response shapes are identical to the live docs - don't re-document them here. Click through for the per-endpoint reference:

VRP date-bounding matters. VRP percentile and z-score only consider history prior to at, so at any historical point the percentile reflects only what was knowable at that moment. No future leakage in backtests.

Example: replay March 16, 2020 (COVID crash, -12% close)

curl -H "X-Api-Key: YOUR_API_KEY" \
  "https://historical.flashalpha.com/v1/exposure/summary/SPY?at=2020-03-16T15:30:00"
{
  "symbol": "SPY",
  "underlying_price": 246.01,
  "as_of": "2020-03-16T15:30:00",
  "gamma_flip": 270.92,
  "regime": "negative_gamma",
  "exposures": {
    "net_gex":  -2633970601,
    "net_dex": -169419489077,
    "net_vex":  152461756844,
    "net_chex":   -13122349
  },
  "interpretation": {
    "gamma":  "Dealers short gamma - moves amplified, trend following likely",
    "vanna":  "Vol up = dealers buy delta - downside dampened if vol spikes",
    "charm":  "Time decay pushing dealers to sell - pressure into close"
  }
}

Real dealer positioning, at 15:30 ET on the day SPY closed -12%. Not a re-derived reconstruction - these are the minute-level greeks as they were at that moment, run through today's analytics.

Data freshness

Every field is one of three kinds: minute-level (changes every bar), EOD-stamped (one value per trade day applied to all intraday at= queries), or not stored at minute granularity (returns 0 or null).

FieldGranularitySample value at intraday at=
Stock and option bid / ask / mid / last1 minutereal number
Implied vol per contract (BSM)1 minutereal number
Greeks (delta, gamma, theta, vega, rho, vanna, charm)1 minutereal number
Open interestEODreal integer (most recent EOD snapshot)
svi_vol per contractEOD-aligned at= only; intraday returns null - use implied_volnull with svi_vol_gated: "backtest_mode"
SVI parameters, forward prices, ATM IV, RV ladderEODreal number (most recent EOD)
Macro (VIX, VVIX, SKEW, MOVE, SPX, VIX9D/3M/6M, DGS10)EODreal number (most recent EOD)
VRP percentile / z-scoreEOD; first ~60 trading days of any new window return null by design (leak-free)real number after warm-up; null inside warm-up
Contract and aggregate volumeNot stored0 (integer)
bidSize, askSize on optionquoteNot stored0 (integer)
Prior-day OI deltas (oi_change)Not storednull
narrative.data.top_oi_changesNot stored[] (empty array)
vrp.macro.hy_spreadNot stored historicallyhard-coded 3.5
CME VIX futures, CNN Fear & GreedNot storednull

The Sample value column is what codegen consumers and JSON-shape-aware code (test fixtures, mocks, OpenAPI schemas) should expect when binding against the response. For 0DTE analytics (gamma walls, pin probability, full greek coverage on near-zero-DTE chains), call at=YYYY-MM-DD for the EOD snapshot. Intraday minute-level greeks for very-short-DTE contracts are sparse, so aggregate exposures may read as 0 at minute resolution; the EOD call returns the close-of-session 0DTE picture in full.

How coverage grows

New trading days and new symbols are added by a gap-aware backfill on a schedule. The coverage window on /v1/tickers reflects what you can query right now; it extends forward on each refresh. To verify a specific date inside the window, hit any analytics endpoint at that date — a 200 confirms the day is queryable.

Latency & caching

Point-in-time reads are fast (~50–300 ms typical). Composite endpoints that rebuild surfaces on demand - /v1/adv_volatility and /v1/stock/{symbol}/summary - can take ~500–1500 ms on a cold request for a new (symbol, at). Cache at your proxy or client for repeat queries on the same tuple - responses are deterministic for a given at, so they're safe to cache indefinitely.

Try it live

Point-and-replay - pick an endpoint, pick a minute in history, hit Replay. Works with your existing API key.

Ready to build?

Get your free API key and start pulling live options data in 30 seconds.