Flow Signals API - Unusual Options Flow Feed - FlashAlpha Lab API
Lab API Flow Signals

Flow Signals API

Scored, classified unusual-flow feed for one underlying. Sweep vs block, NBBO aggressor, opening/closing bias, directional intent, and a transparent 0-100 score with component breakdown and chain enrichment.

Endpoint

GET /v1/flow/signals/{symbol}
Auth required (X-Api-Key) Rate Limited: Yes Alpha plan+

Parameters

Name In Required Default Description
symbol path yes - Underlying symbol
minScore query no 0 Drop signals below this score (0-100)
intent query no all Filter by bullish / bearish / neutral
structure query no all Filter by block / sweep. A lone block-sized print is a block; sweep = ≥2 same-side prints on one contract within ~500ms
windowMinutes query no 240 Look-back window in minutes (1-10080)
limit query no 50 Max signals returned (1-500)
expiry query no all expiries Filter the chain to a single expiry (yyyy-MM-dd)
curl -H "X-Api-Key: YOUR_API_KEY" \
  "https://lab.flashalpha.com/v1/flow/signals/NVDA?minScore=70&structure=sweep&windowMinutes=240"
import requests

resp = requests.get(
    "https://lab.flashalpha.com/v1/flow/signals/NVDA",
    params={"minScore": 70, "structure": "sweep", "windowMinutes": 240},
    headers={"X-Api-Key": "YOUR_API_KEY"}
)
data = resp.json()
for sig in data["signals"]:
    print(f"{sig['ts']} {sig['structure']:>5} {sig['right']} {sig['strike']} "
          f"score={sig['score']} intent={sig['intent']} premium=${sig['premium']:,.0f}")
const params = new URLSearchParams({
  minScore: 70, structure: "sweep", windowMinutes: 240
});
const resp = await fetch(
  `https://lab.flashalpha.com/v1/flow/signals/NVDA?${params}`,
  { headers: { "X-Api-Key": "YOUR_API_KEY" } }
);
const data = await resp.json();
data.signals.forEach(s =>
  console.log(`${s.ts} ${s.structure} ${s.right}${s.strike} score=${s.score} ${s.intent}`)
);

Response

{
  "symbol": "NVDA",
  "as_of": "2026-05-21T16:30:45Z",
  "window_minutes": 240,
  "expiry": null,
  "underlying_price": 900.25,
  "chain": {
    "call_wall": 950.0,
    "put_wall": 850.0,
    "max_pain": 900.0,
    "gamma_flip": 905.0
  },
  "count": 1,
  "signals": [
    {
      "ts": "2026-05-21T15:58:12Z",
      "expiry": "2026-05-23",
      "strike": 950.0,
      "right": "C",
      "side": "buy",
      "price": 12.40,
      "size": 1500,
      "premium": 1860000.0,
      "dte": 7,
      "structure": "sweep",
      "aggressor": "above_ask",
      "open_close_bias": "opening_bias",
      "open_close_confidence": 0.43,
      "contract_net_oi_delta": 4200,
      "intent": "bullish",
      "score": 87,
      "conviction": "high",
      "tags": ["sweep", "opening", "whale", "golden"],
      "score_breakdown": {
        "premium": 22, "size_vs_oi": 18, "aggressor": 14,
        "sweep": 12, "opening_bias": 9, "tenor": 12
      },
      "enrichment": {
        "iv": 0.62,
        "delta": 0.28,
        "gamma": 0.0041,
        "iv_vs_atm": 0.08,
        "moneyness": "OTM",
        "estimated_delta_notional": 37810500.0,
        "hypothetical_gex_impact_if_opening": 4984267.88
      }
    }
  ]
}

Per-signal fields

Field Type Description
tsstringISO 8601 timestamp of the print (or first leg of a sweep)
expiry / strike / rightstring / number / stringContract key (right is C or P)
sidestringUpstream aggressor classification: buy, sell, or mid
price / size / premiumnumberpremium = price × size × 100
dtenumberDays to expiry
structurestringblock (lone block-sized print) or sweep (≥2 same-side prints on one contract within ~500ms)
aggressorstringNBBO aggressor strength at trade: above_ask / at_ask / mid / at_bid / below_bid
open_close_biasstringContract-level OI-simulator bias: opening_bias, closing_bias, or unknown
open_close_confidencenumberOI simulator's confidence weight
contract_net_oi_deltanumberSimulator's signed net intraday OI delta for the contract
intentstringDirectional intent: bullish, bearish, or neutral
scorenumberComposite score 0-100, ordered highest first
convictionstringScore bucket label (e.g. high)
tagsstring[]Any of sweep, block, opening, closing, 0dte, whale (premium ≥ $1M), golden (top decile in response and score ≥ 70)
score_breakdownobjectSub-components that sum to score: premium, size_vs_oi, aggressor, sweep, opening_bias, tenor
enrichment.iv / delta / gammanumber, nullableGreeks from the settled chain snapshot at the signal's strike
enrichment.iv_vs_atmnumber, nullableSignal IV minus ATM IV for the expiry
enrichment.moneynessstringITM / ATM / OTM / unknown
enrichment.estimated_delta_notionalnumber, nullableDelta-weighted dollar notional for the print (delta-equivalent shares × spot)
enrichment.hypothetical_gex_impact_if_openingnumber, nullableStandalone gamma-$ this print would add if opening and fully dealer-absorbed. Not applied to the live chain

Top-level fields

FieldDescription
window_minutesEcho of the requested look-back window
expiryEcho of the requested expiry filter (or null if all expiries)
underlying_priceSpot at request time (0 when the settled chain snapshot is unavailable)
chain.call_wall / put_wall / max_pain / gamma_flipSettled-chain reference levels, computed once per request
countNumber of signals returned (after filters and limit)
signalsArray of signals, highest score first

How scoring works

Every block-sized print in the window is coalesced into a signal, classified, and scored on a 0-100 scale. score_breakdown returns the component contributions that sum to score. The components map to the trade characteristics they're named after:

  • premium - contribution from the print's dollar premium
  • size_vs_oi - contribution from print size relative to the contract's existing open interest
  • aggressor - contribution from NBBO aggressor strength; the score weights conviction in the trade's own direction
  • sweep - contribution when the print is part of a same-side sweep across ≥2 quotes within ~500ms
  • opening_bias - contribution when the OI simulator's contract-level bias says the position is being opened rather than unwound
  • tenor - contribution from the contract's DTE

Weights are server-tunable, so absolute component contributions may shift over time, but the components keep summing to score and overall signal ordering stays stable across tuning changes. The golden tag fires only when the score is in the response's top decile and at least 70 absolute, so a weak window may yield none at all.

Notes & caveats

  • open_close_bias is a contract-level signal from the OI simulator's net intraday delta. It is not a per-print opening/closing label - individual trades inside the same contract carry the same bias.
  • intent collapses to neutral whenever open_close_bias is closing_bias (direction can't be attributed on unwinds) or when the trade side is mid. The side field (buy/sell/mid) is distinct from the NBBO aggressor label.
  • structure is always block or sweep. single is reserved and not currently emitted, so filtering structure=single returns nothing.
  • enrichment.* fields are null and moneyness is "unknown" when the signal's contract isn't in the settled chain snapshot (illiquid / just-listed).
  • hypothetical_gex_impact_if_opening is explicitly conditional - the standalone gamma-$ this single print would add if opening and fully dealer-absorbed. It is not applied to the live chain (which already folds in intraday OI), so don't sum it against /v1/flow/gex.
  • If the settled chain snapshot is unavailable for the symbol, the feed degrades rather than 404s: scoring still runs on trade + OI-simulator context, but underlying_price is 0, all chain levels are null, and every enrichment block is null/"unknown".

Common Use Cases

  • Unusual options activity feed - drop into a watchlist as a "smart-money tape," filtered by minScore and structure=sweep
  • Directional alerting - fire on intent=bullish or intent=bearish signals with conviction=high and the opening tag
  • Flow-confirmed trade triggers - pair with a directional signal and require a same-side high-score sweep before sizing in
  • Catalyst hunting - scan for the whale tag (≥$1M premium) to surface name-specific positioning before the move
  • Score-component research - use score_breakdown to back-test which components drove the best forward returns on your universe

Ready to build?

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