- Live API Reference
- Strategy Signals
- sell-window
sell-window API
Should you sell options today? Built from more than 5 million backtests, sell-window answers that every session for SPY, QQQ and IWM: sell or skip for four expiries, from the same day to about one month out. On a sell, it lists the trades with strikes, quotes and the exit rule.
Endpoint
X-Api-Key)
Rate Limited: Yes
Plan: Basic now, Growth from Dec 1
Parameters
| Name | In | Type | Required | Default | Description |
|---|---|---|---|---|---|
symbol | path | string | required | - | SPY, QQQ or IWM. Any other symbol returns every window as unavailable. |
Request
curl -H "X-Api-Key: YOUR_API_KEY" \
"https://lab.flashalpha.com/v1/strategies/sell-window/SPY"import requests
resp = requests.get(
"https://lab.flashalpha.com/v1/strategies/sell-window/SPY",
headers={"X-Api-Key": "YOUR_API_KEY"}
)
resp.raise_for_status()
data = resp.json()
for w in data["windows"]:
print(w.get("expiry"), w["action"], len(w.get("candidates", [])))const resp = await fetch(
"https://lab.flashalpha.com/v1/strategies/sell-window/SPY",
{ 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
Runs on live market data and uses 1 request from your daily quota.
Response
A sell day: each window carries an action and, on sell, the trades to place.
{
"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 live 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).
On a skip day there is nothing to do, and each window carries only its expiry and action. A real response from SPY on 2026-11-05:
{
"symbol": "SPY",
"session": "2026-11-05",
"windows": [
{
"expiry": "2026-11-05",
"days_to_expiry": 0,
"action": "skip"
},
{
"expiry": "2026-11-12",
"days_to_expiry": 7,
"action": "skip"
},
{
"expiry": "2026-11-18",
"days_to_expiry": 13,
"action": "skip"
},
{
"expiry": "2026-12-04",
"days_to_expiry": 29,
"action": "skip"
}
],
"endpoint_version": "2026.09.30",
"data_as_of": {
"node": "fa4",
"equity_feed": "2026-11-05T14:11:16.332Z",
"equity_options_feed": "2026-11-05T14:11:16Z",
"index_feed": "2026-11-05T14:10:58.1024266Z",
"index_options_feed": "2026-11-04T22:00:00Z",
"futures_feed": "2026-11-05T14:11:13.291Z",
"futures_options_feed": "2026-11-05T14:11:13.337Z",
"flow_feed": null,
"oi_feed": "2026-11-04T21:00:00Z",
"macro_feed": "2026-11-04T21:15:01Z"
}
}Response Fields
This endpoint has its own shape, not the strategy decision envelope.
| Field | Type | Description |
|---|---|---|
symbol | string | The symbol, upper case. |
session | string | yyyy-MM-dd. The trading session the answer applies to. |
spot | number | Underlying mid the strikes were picked against. Present when a window sells. |
quoted_at | string | UTC time of the quotes behind the strikes. Present when a window sells. |
legs_indicative | boolean | true 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[] | array | Always 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[].expiry | string | yyyy-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_expiry | integer | Calendar days from session to expiry. |
windows[].action | string | sell: 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[] | array | Present only when action is sell. The trades to consider, in a fixed order. |
candidates[].structure | string | The trade type. See structures and exits. |
candidates[].exit | string | expiry or tp50. See structures and exits. |
candidates[].legs[] | array | The contracts of one unit of the trade. |
legs[].side | string | sell or buy. |
legs[].quantity | integer | Contracts per unit of the trade (2 for the sold body of put_bwb, otherwise 1). |
legs[].type | string | call or put. |
legs[].strike | number | Strike price. |
legs[].delta | number | The contract's own delta when the answer was served (negative for puts). |
legs[].bid, legs[].ask | number | The contract's quote when the answer was served. |
candidates[].mid_credit | number | Net 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 | string, object | Response 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.
| Window | Target | Accepted range |
|---|---|---|
| Same day | 0 days | 0 days |
| About one week | 7 days | 4 to 10 days |
| About two weeks | 14 days | 11 to 17 days |
| About one month | 30 days | 25 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
| Value | Field | Meaning |
|---|---|---|
short_put | structure | Sell one put. |
short_call | structure | Sell one call. |
short_strangle | structure | Sell one call and one put. |
short_straddle | structure | Sell one call and one put near the money. |
tail_hedged_put | structure | Short put with a far out-of-the-money put bought below it. |
put_credit_spread | structure | Sell one put and buy a lower-strike put. |
put_bwb | structure | Put broken-wing butterfly: buy one put above, sell two, buy one further below, for a credit. |
expiry | exit | Hold to expiration. |
tp50 | exit | Close 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.
Errors
| Status | Error | When |
|---|---|---|
401 | - | Missing or invalid X-Api-Key. The body is empty; check the status code before parsing JSON. |
403 | tier_restricted | Your plan is below the one required: Basic through November 2026, Growth from December 1, 2026. |
429 | Quota exceeded | Daily quota used up. Retry-After gives the seconds until the reset at 00:00 UTC. Rejected requests (including 403) count toward the quota. |
About
More than 5 million backtests led to this endpoint. It answers one question: is this a session to sell options? The answer is set from the previous session's close and stays fixed for the whole session. Strikes, deltas and quotes come from the chain at the moment you call.
In the backtest on SPY, QQQ and IWM from January 2018 to October 2026, following it had a maximum drawdown of $255,105 against $958,924 for the same trades sold every session, and a Sharpe ratio of 0.76 against 0.61, on about a third of the trades. See every trade in the backtest.
The session switches at the close (16:00 ET, 13:00 ET on early-close days). Before the close the answer is for the current session. After the close and on closed days it is for the next session.
Plans: Basic or higher through November 2026, Growth or higher from December 1, 2026. Backtesting: on Alpha, the historical API returns the answer for any past session with ?at=, so you can reproduce it on your own fills and sizing. A paper bot follows this endpoint every session and posts its results on our Discord.
The skip call applies to new trades, so it cannot protect positions already open when a sudden shock hits. This is data, not investment advice.
Common Use Cases
- Daily routine - call once after the open and act only on windows where
actionissell - Pick a trade - read
candidates[]for ready strikes, deltas, bid/ask andmid_creditinstead of building the legs by hand - Compare expiries - see the same-day, one-week, two-week and one-month windows side by side
- Manage the exit -
exittells you whether the backtest held to expiration or took profit at 50% of the credit - Replay a past session - call the historical endpoint with
at=<session>T09:35:00to see the strikes at the backtests' entry time - Handle gaps - treat
unavailablelike a skip
Related
Related reading
- sell-window: a blueprint for selling options - how the windows work and how to follow them
- sell-window backtest - every recommended trade from 2018 to 2026, with a builder
- When not to sell options - the study that started this research
Complementary endpoints
- Historical sell-window - the same answer for a past session, with strikes at 09:35 ET
- Strategy Signals overview - the other strategy endpoints
- Yield Enhancement - rank covered calls and cash-secured puts on any symbol
- Tail Pricing - how rich or cheap the downside tail is for one expiry