Options Flow Outliers API - Cross-Symbol Scanner | FlashAlpha
  1. 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

GET /v1/flow/options/outliers
Auth required (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.

GET

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
generatedUtcstringGeneration timestamp
windowMinutesintegerEffective lookback window
trackedintegerSymbols/underlyings scanned
qualifiedintegerSymbols that met filters
limitintegerEffective output limit
outliers[]arrayOutlier rows: symbol, tradeCount, buyVolume, sellVolume, midVolume, netVolume, imbalancePct, skew, notional, netNotional, biggestTrade, biggestTradeUtc, biggestAgeSec, lastVwap, lastTradeUtc, lastTradeAgeSec
endpoint_version, data_as_ofstring, objectResponse envelope, see Response envelope.

Fields of outliers[]

Field Type Description
outliers[].symbolstringUnderlying symbol
outliers[].tradeCountnumberNumber of trades
outliers[].buyVolumenumberVolume classified as buyer-initiated
outliers[].sellVolumenumberVolume classified as seller-initiated
outliers[].midVolumenumberVolume printed at the mid
outliers[].netVolumenumberBuy volume minus sell volume
outliers[].imbalancePctnumberOutliers: imbalance (%)
outliers[].skewstringOutliers: skew
outliers[].notionalnumberOutliers: notional
outliers[].netNotionalnumberOutliers: net notional
outliers[].biggestTradenumberLargest single trade size
outliers[].biggestTradeUtcstringOutliers: biggest trade (UTC)
outliers[].biggestAgeSecnumberOutliers: biggest age seconds
outliers[].lastVwapnumberOutliers: last vwap
outliers[].lastTradeUtcstringOutliers: last trade (UTC)
outliers[].lastTradeAgeSecnumberOutliers: 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.
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.
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[] by skew or absolute netNotional over a rolling windowMinutes to 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 biggestAgeSec is small to surface large prints (biggestTrade) that just crossed
  • Screen out thin names - combine minTrades, tracked, and qualified with tradeCount so the list isn't dominated by illiquid noise
  • Separate conviction from churn - read netVolume against buyVolume/sellVolume/midVolume and notional to tell real accumulation from two-way volume
  • Refresh a watchlist each session - replace stale names with current outliers and drop those whose lastTradeAgeSec has grown large

Related reading

Complementary endpoints

Ready to build with FlashAlpha?

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

No credit card required Setup in 60 seconds Secure & reliable