1. sell-window

Historical sell-window API

Replay the daily sell-window answer for SPY, QQQ and IWM for any past session: sell or skip for four expiries and, on a sell, the trades with strikes from the archive chain. Same shape as live /v1/strategies/sell-window.

HISTORICAL
Symbols
SPY, QQQ, IWM
Windows
4 expiries per session
Plan
Alpha+
Format
JSON (REST)

Endpoint

GET/v1/strategies/sell-window/{symbol}?at=...
Host: historical.flashalpha.com Auth required (X-Api-Key) Rate Limited: Yes Plan: Alpha+

Parameters

NameInTypeRequiredDefaultDescription
symbolpathstringrequired-SPY, QQQ or IWM.
atquerydatetimerequired-As-of time, ET wall-clock: yyyy-MM-ddTHH:mm:ss, or a date only, which means 16:00 ET that day. A date-only at for today is rejected as a future time until the close.

Request

curl -H "X-Api-Key: YOUR_API_KEY" \
  "https://historical.flashalpha.com/v1/strategies/sell-window/SPY?at=2026-10-16T09:35:00"
import requests

resp = requests.get(
    "https://historical.flashalpha.com/v1/strategies/sell-window/SPY",
    params={"at": "2026-10-16T09:35:00"},
    headers={"X-Api-Key": "YOUR_API_KEY"}
)
resp.raise_for_status()
data = resp.json()
for w in data["windows"]:
    print(w["expiry"], w["action"], len(w.get("candidates", [])))
const resp = await fetch(
  "https://historical.flashalpha.com/v1/strategies/sell-window/SPY?at=2026-10-16T09:35:00",
  { headers: { "X-Api-Key": "YOUR_API_KEY" } }
);
if (!resp.ok) throw new Error(`HTTP ${resp.status}`);
const data = await resp.json();
for (const w of data.windows) console.log(w.expiry, w.action, (w.candidates ?? []).length);

Try it live

Replays archived data as of the at time you pick (ET wall-clock). Needs an Alpha plan API key.

GET

Response

Same shape as the live endpoint, not the strategy decision envelope.

{
  "symbol": "SPY",
  "session": "2026-10-16",
  "spot": 772.255,
  "quoted_at": "2026-10-16T13:35:00Z",
  "legs_indicative": false,
  "windows": [
    {
      "expiry": "2026-10-16",
      "days_to_expiry": 0,
      "action": "sell",
      "candidates": [
        {
          "structure": "short_put",
          "exit": "expiry",
          "legs": [
            {
              "side": "sell",
              "quantity": 1,
              "type": "put",
              "strike": 769,
              "delta": -0.19,
              "bid": 0.39,
              "ask": 0.4
            }
          ],
          "mid_credit": 0.395
        },
        {
          "structure": "short_strangle",
          "exit": "expiry",
          "legs": [
            {
              "side": "sell",
              "quantity": 1,
              "type": "call",
              "strike": 774,
              "delta": 0.302,
              "bid": 0.63,
              "ask": 0.64
            },
            {
              "side": "sell",
              "quantity": 1,
              "type": "put",
              "strike": 770,
              "delta": -0.264,
              "bid": 0.58,
              "ask": 0.59
            }
          ],
          "mid_credit": 1.22
        }
      ]
    }
  ],
  "endpoint_version": "2026.09.30"
}

Sending request…

See this endpoint on archived data

Send this exact request and the real response shows up here, right next to the example.

Real response for SPY at 09:35 ET on 2026-10-16, shortened to one window and two trades. Download the full response (JSON).

Response Fields

FieldTypeDescription
symbolstringThe symbol, upper case.
sessionstringyyyy-MM-dd. The trading session the answer applies to.
spotnumberUnderlying mid the strikes were picked against. Present when a window sells.
quoted_atstringUTC time of the quotes behind the strikes. Present when a window sells.
legs_indicativebooleantrue when the quotes are from before that session's 09:35 ET entry: call again at or after 09:35 ET for the strikes to trade. Present when a window sells.
windows[]arrayAlways four entries, in this order: the same-day expiry, then the expiries closest to one week, two weeks and one month out. See how windows are chosen.
windows[].expirystringyyyy-MM-dd. The listed expiry this window trades. Absent when no listed expiry falls in the range or the data is missing.
windows[].days_to_expiryintegerCalendar days from session to expiry.
windows[].actionstringsell: a session to sell at this expiry. skip: stand aside, no new trade. unavailable: no answer (a symbol outside coverage or a missing day of data); treat it like a skip.
windows[].candidates[]arrayPresent only when action is sell. The trades to consider, in a fixed order.
candidates[].structurestringThe trade type. See structures and exits.
candidates[].exitstringexpiry or tp50. See structures and exits.
candidates[].legs[]arrayThe contracts of one unit of the trade.
legs[].sidestringsell or buy.
legs[].quantityintegerContracts per unit of the trade (2 for the sold body of put_bwb, otherwise 1).
legs[].typestringcall or put.
legs[].strikenumberStrike price.
legs[].deltanumberThe contract's own delta when the answer was served (negative for puts).
legs[].bid, legs[].asknumberThe contract's quote when the answer was served.
candidates[].mid_creditnumberNet credit per share at mid: sold mids minus bought mids, times quantity. Multiply by 100 for one unit in dollars.
endpoint_version, data_as_of, archive_as_ofstring, objectResponse envelope, see Response envelope.

How windows are chosen

Each window trades the listed expiry closest to its target, counted in calendar days after the session.

WindowTargetAccepted range
Same day0 days0 days
About one week7 days4 to 10 days
About two weeks14 days11 to 17 days
About one month30 days25 to 35 days

When a window sells, the listing is the option chain's at the moment of the answer, as the backtests chose it at entry. Otherwise it is the previous close's listing.

Structures and exits

ValueFieldMeaning
short_putstructureSell one put.
short_callstructureSell one call.
short_stranglestructureSell one call and one put.
short_straddlestructureSell one call and one put near the money.
tail_hedged_putstructureShort put with a far out-of-the-money put bought below it.
put_credit_spreadstructureSell one put and buy a lower-strike put.
put_bwbstructurePut broken-wing butterfly: buy one put above, sell two, buy one further below, for a credit.
expiryexitHold to expiration.
tp50exitClose once the position can be bought back for half of the credit or less, otherwise hold to expiration.

How strikes are picked

Strikes are picked from the chain with the contract rules from our backtests: only out-of-the-money contracts with a bid above zero, a bid/ask spread of at most 20% of the mid and open interest of at least 250. Among those, the contract whose delta is closest to the candidate's target and within 0.05 of it is used; ties go to the tighter spread, then the higher open interest. A candidate whose legs cannot all be found in the chain is left out.

Choosing at

  • Entry-time strikes. Our backtests entered at 09:35 ET, so at=<session>T09:35:00 returns strikes picked at that time by the same contract rules.
  • Date only. A date-only at means 16:00 ET that day.
  • Sell or skip. The answer is set from the previous session's close by a rule that came out of more than 5 million backtests. From the live launch on, the action, expiry and candidate list match what the live endpoint answered at that time. For earlier dates they are rebuilt from the archive with the same rules.
  • Strikes, deltas and quotes. They come from the archive chain at at.

Errors

StatusErrorWhen
400invalid_atat is malformed, in the future, or a time that does not exist in ET (the daylight-saving gap).
401-Missing or invalid X-Api-Key. The body is empty; check the status code before parsing JSON.
403tier_restrictedYour plan is below Alpha. The body includes current_plan and required_plan.
429Quota exceededDaily quota used up. Retry-After gives the seconds until the reset at 00:00 UTC. Rejected requests (including 403) count toward the quota.
503warming_upThe signal is warming up and is not available yet. Try again later.

What This Unlocks

  • Replay a session - see what the live endpoint would have answered, with the strikes at 09:35 ET.
  • Reproduce the backtest - take each sell window, enter the listed legs and follow the listed exit. Compare with ours.
  • Check fills - compare mid_credit with the bid and ask on each leg for any past day.
  • Audit your own entries - line up a trade you made against the window that was open that day.

Related reading