- Live API Reference
- Trade Flow Data
- Options
- Outliers
Options Flow Outliers API
Cross-symbol option-flow outliers ranked by absolute net notional, with imbalance, skew, biggest trade, and last-trade age.
Endpoint
X-Api-Key)
Rate Limited: Yes
Plan: Alpha+
Parameters
| Name | In | Type | Required | Default | Description |
|---|---|---|---|---|---|
limit |
query | integer | 20 | Rows returned, clamped to 1..200. Non-numeric values return a 400 problem-details body. |
|
minTrades |
query | integer | 20 | Minimum trades for a symbol to qualify. Non-numeric values return a 400 problem-details body. Values below 1 are treated as 1. | |
windowMinutes |
query | integer | 240 | Lookback window, clamped to 1..10080. Non-numeric values return a 400 problem-details body. |
Request
curl -H "X-Api-Key: YOUR_API_KEY" \
"https://lab.flashalpha.com/v1/flow/options/outliers?limit=20&minTrades=50&windowMinutes=240"import requests
resp = requests.get(
"https://lab.flashalpha.com/v1/flow/options/outliers",
headers={"X-Api-Key": "YOUR_API_KEY"}
)
resp.raise_for_status()
data = resp.json()
print(f"{data['qualified']} of {data['tracked']} symbols qualified")const resp = await fetch(
"https://lab.flashalpha.com/v1/flow/options/outliers",
{ headers: { "X-Api-Key": "YOUR_API_KEY" } }
);
if (!resp.ok) throw new Error(`HTTP ${resp.status}`);
const data = await resp.json();
console.log(data.qualified + " of " + data.tracked + " symbols qualified");Try it live
Runs on live market data and uses 1 request from your daily quota.
Response
{
"generatedUtc": "2026-10-30T13:45:51.3547636Z",
"windowMinutes": 240,
"tracked": 5586,
"qualified": 671,
"limit": 20,
"outliers": [
{
"symbol": "SPX",
"tradeCount": 2627,
"buyVolume": 2461,
"sellVolume": 7112,
"midVolume": 41416,
"netVolume": -4651,
"imbalancePct": 48.6,
"skew": "MILD_SELL",
"notional": 1184772836,
"netNotional": -108069946,
"biggestTrade": 1200,
"biggestTradeUtc": "2026-10-30T13:34:00Z",
"biggestAgeSec": 711,
"lastVwap": 232.36,
"lastTradeUtc": "2026-10-30T13:45:54.931Z",
"lastTradeAgeSec": 0
},
{
"symbol": "SPY",
"tradeCount": 144603,
"buyVolume": 435733,
"sellVolume": 378071,
"midVolume": 131431,
"netVolume": 57662,
"imbalancePct": 7.1,
"skew": "FLAT",
"notional": 235462027,
"netNotional": 14363848,
"biggestTrade": 9994,
"biggestTradeUtc": "2026-10-30T13:34:00Z",
"biggestAgeSec": 711,
"lastVwap": 2.49,
"lastTradeUtc": "2026-10-30T13:45:55.557Z",
"lastTradeAgeSec": 0
}
],
"endpoint_version": "2026.09.30",
"data_as_of": {
"node": "fa4",
"equity_feed": "2026-10-30T13:45:58.109Z",
"equity_options_feed": "2026-10-30T13:45:57Z",
"index_feed": "2026-10-30T13:45:56.132Z",
"index_options_feed": "2026-10-30T13:45:54Z",
"futures_feed": "2026-10-30T13:45:53.139Z",
"futures_options_feed": "2026-10-30T13:45:49.971Z",
"flow_feed": "2026-10-30T13:45:00Z",
"oi_feed": "2026-10-29T20:00:00Z",
"macro_feed": "2026-10-29T21:00:20Z"
}
}Sending request…
See this endpoint on live data
Send this exact request and the real response shows up here, right next to the example.
Response Fields
| Field | Type | Description |
|---|---|---|
generatedUtc | string | Generation timestamp |
windowMinutes | integer | Effective lookback window |
tracked | integer | Symbols/underlyings scanned |
qualified | integer | Symbols that met filters |
limit | integer | Effective output limit |
outliers[] | array | Outlier rows: symbol, tradeCount, buyVolume, sellVolume, midVolume, netVolume, imbalancePct, skew, notional, netNotional, biggestTrade, biggestTradeUtc, biggestAgeSec, lastVwap, lastTradeUtc, lastTradeAgeSec |
endpoint_version, data_as_of | string, object | Response envelope, see Response envelope. |
Fields of outliers[]
| Field | Type | Description |
|---|---|---|
outliers[].symbol | string | Underlying symbol |
outliers[].tradeCount | number | Number of trades |
outliers[].buyVolume | number | Volume classified as buyer-initiated |
outliers[].sellVolume | number | Volume classified as seller-initiated |
outliers[].midVolume | number | Volume printed at the mid |
outliers[].netVolume | number | Buy volume minus sell volume |
outliers[].imbalancePct | number | Outliers: imbalance (%) |
outliers[].skew | string | Outliers: skew |
outliers[].notional | number | Outliers: notional |
outliers[].netNotional | number | Outliers: net notional |
outliers[].biggestTrade | number | Largest single trade size |
outliers[].biggestTradeUtc | string | Outliers: biggest trade (UTC) |
outliers[].biggestAgeSec | number | Outliers: biggest age seconds |
outliers[].lastVwap | number | Outliers: last vwap |
outliers[].lastTradeUtc | string | Outliers: last trade (UTC) |
outliers[].lastTradeAgeSec | number | Outliers: last trade age seconds |
Errors
| Status | Error | When |
|---|---|---|
400 | - | A query value has the wrong type, or a required value is missing. The body is an RFC 7807 problem-details object with errors.<param>. |
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 Alpha. The body includes current_plan and required_plan. |
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. |
502 | - | Upstream flow data source unavailable. |
About
Surfaces the option universe's most directional names by absolute net notional, with extra context fields (imbalancePct, skew, biggest-trade timing) that the leaderboard doesn't carry. Filter out thin tape with minTrades. Refreshes about every 30 seconds.
Common Use Cases
- Run an unusual-activity scanner - rank
outliers[]byskewor absolutenetNotionalover a rollingwindowMinutesto surface the most anomalous names - Filter for one-sided tape - threshold on
imbalancePct(e.g. > 0.5) to keep only symbols with decisively buy- or sell-skewed flow - Catch fresh big trades - flag rows where
biggestAgeSecis small to surface large prints (biggestTrade) that just crossed - Screen out thin names - combine
minTrades,tracked, andqualifiedwithtradeCountso the list isn't dominated by illiquid noise - Separate conviction from churn - read
netVolumeagainstbuyVolume/sellVolume/midVolumeandnotionalto tell real accumulation from two-way volume - Refresh a watchlist each session - replace stale names with current outliers and drop those whose
lastTradeAgeSechas grown large
Related
Related reading
- Flow Signals API: scoring unusual options activity - how outliers turn into a ranked unusual-activity score
- Build an unusual-options-activity scanner (Python) - wire these outliers into a working scanner
Complementary endpoints
- Options Leaderboard - the ranked buyers/sellers view without the extra anomaly fields
- Options Summary - drill into a single outlier symbol's totals
- Options Recent - the raw prints behind an outlier's flow
- Flow Signals - scored unusual-activity layer built on this flow
Unlock DEX, VEX and CHEX with Basic
Everything in Free, plus:
- DEX, VEX and CHEX exposure
- Full max pain
- ETF & index symbols SPY, QQQ, SPX, VIX
Go full-chain with Growth
Everything in Basic, plus:
- Full-chain GEX Every expiration
- 0DTE analytics
- Exposure summary & AI narrative
- CME futures & live screener
Add history and vol surfaces with Alpha
Everything in Growth, plus:
- Historical API replay Since 2017
- SVI vol surfaces
- VRP analytics
- Greeks surfaces Vanna, charm, volga and speed grids