Liquidity API
Per-expiry execution score (0-100), ATM bid-ask spread %, OI-weighted spread %, ATM OI depth, plus chain-level OI-weighted score and best/worst expiry.
Endpoint
X-Api-Key)
Rate Limited: Yes
Growth plan+
Parameters
| Name | In | Required | Default | Description |
|---|---|---|---|---|
symbol |
path | yes | - | Underlying symbol |
curl -H "X-Api-Key: YOUR_API_KEY" \
"https://lab.flashalpha.com/v1/liquidity/SPY"
import requests
resp = requests.get(
"https://lab.flashalpha.com/v1/liquidity/SPY",
headers={"X-Api-Key": "YOUR_API_KEY"}
)
data = resp.json()
print(f"Chain score: {data['chain_execution_score']}")
const resp = await fetch(
"https://lab.flashalpha.com/v1/liquidity/SPY",
{ headers: { "X-Api-Key": "YOUR_API_KEY" } }
);
const data = await resp.json();
console.log("Chain score: " + data.chain_execution_score);
Response
{
"symbol": "SPY",
"underlying_price": 597.50,
"as_of": "2026-05-29T15:30:00Z",
"chain_execution_score": 78,
"best_expiry": "2026-05-30",
"worst_expiry": "2027-01-15",
"thin_expiry_count": 1,
"expiries": [
{ "expiration": "2026-05-30", "dte": 1, "atm_spread_pct": 0.45, "weighted_spread_pct": 1.10, "atm_oi": 48200, "execution_score": 86, "label": "tight" },
{ "expiration": "2026-06-18", "dte": 20, "atm_spread_pct": 0.78, "weighted_spread_pct": 1.95, "atm_oi": 31400, "execution_score": 68, "label": "normal" }
]
}
Key Response Fields
| Field | Description |
|---|---|
chain_execution_score | OI-weighted average of per-expiry execution_score across the chain (0-100). |
best_expiry / worst_expiry | Expirations with the highest / lowest execution_score. |
thin_expiry_count | Number of expiries labelled illiquid. |
expiries[].atm_spread_pct | Average bid-ask spread % at the strike closest to spot, across the side(s) that quote. null when neither side quotes. |
expiries[].weighted_spread_pct | OI-weighted bid-ask spread % across contracts in the expiry that both carry OI (> 0) and quote a valid spread (ask > bid > 0). null when no contract satisfies both. |
expiries[].atm_oi | Sum of call+put OI at the strike closest to spot. |
expiries[].execution_score | 0-100. Composite: 70% spread-tightness (exp-decay) + 30% ATM-OI depth (5000 contracts saturates). Same formula as /v1/exposure/zero-dte's liquidity.execution_score. |
expiries[].label | Discrete bucket derived from execution_score: tight (≥75) / normal (≥50) / wide (≥20) / illiquid (<20). |
Errors
| Status | Description |
|---|---|
403 | Requires Growth plan or higher |
404 | Symbol not found or no options data |
About
Returns a per-expiry execution score (0-100) alongside ATM bid-ask spread %, OI-weighted spread %, and ATM OI depth, plus a chain-level OI-weighted score and the best/worst expiry. Each expiry carries a label: tight (≥75) / normal (≥50) / wide (≥20) / illiquid (<20).
The score is heuristic - read the label and direction of the number rather than treating any threshold as a hard tradability rule. Expirations with all-zero OI or only one-sided quotes still appear; they typically score 0 and label illiquid. Read chain_execution_score alongside best_expiry to judge whether "best" actually means tradable.
Common Use Cases
- Route to the cleanest expiry by selecting
best_expiry(or the highest per-expiryexecution_score) before sending a multi-leg order - Gate a watchlist on
chain_execution_scoreso only names with a tradable chain reach the order stage - Skip
label: illiquidexpiries to keep slippage out of backtests and live fills - Size and price limit orders off
expiries[].atm_spread_pctandweighted_spread_pctrather than crossing the full quoted spread - Confirm depth at the working strike with
expiries[].atm_oibefore scaling order size - Alert on
thin_expiry_countrising orchain_execution_scorefalling to catch degrading liquidity before it bites - Sanity-check a "best" expiry by reading
worst_expiryalongside it, since "best" can still be untradeable on thin names
Related
Related reading
- SVI liquidity filtering: a real-data experiment - why filtering thin contracts before fitting a surface changes the result
Complementary endpoints
- Option Quote - the per-contract bid/ask/OI behind each expiry's spread and depth figures
- Screener - filter the universe down to names that pass a liquidity threshold
- Volatility - read IV and term structure on the expiries that score as executable
- SVI Parameters - the calibrated surface fit you should run only on liquid expiries
Ready to build?
Get your free API key and start pulling live options data in 30 seconds.