Unusual Whales API - Ticker Flow endpoints

Layer mapping: L1 LOAD-BEARING. Five endpoints under TickerController that surface per-ticker flow at different cuts: recent feed, per-expiry rollup, per-strike rollup, per-strike intraday timeseries, and the per-ticker flow-alerts feed.

For SPY hunter, these are the SPY-scoped equivalents of the cross-market endpoints in uw-api-option-trade and uw-api-tide. They live at /api/stock/SPY/... instead of the controllers covered elsewhere.

1. Endpoint matrix

#PathPurpose
1GET /api/stock/{ticker}/flow-recentRecent flow records (rolling feed)
2GET /api/stock/{ticker}/flow-alertsPer-ticker flow-alerts feed (SAME as uw-api-option-trade /flow-alerts filtered to one ticker)
3GET /api/stock/{ticker}/flow-per-expiryFlow rolled up by expiry
4GET /api/stock/{ticker}/flow-per-strikeFlow rolled up by strike (daily)
5GET /api/stock/{ticker}/flow-per-strike-intradayFlow per strike at minute granularity

2. Base contract

PropertyValue
Base URLhttps://api.unusualwhales.com
AuthAuthorization: Bearer <token> header
Response envelope{ "data": [...] }
Status codes200, 422, 500
Numeric formatStrings - coerce to float

3. GET /api/stock/{ticker}/flow-recent

Recent flow records for a ticker (rolling feed).

Query parameters (inferred from sibling endpoints): date, limit, newer_than, older_than, min_premium.

Use: baseline per-ticker feed. For SPY, lower-priority than the more-aggregated /per-strike endpoints because per-trade SPY flow is huge.

4. GET /api/stock/{ticker}/flow-alerts

Per-ticker version of the uw-api-option-trade /flow-alerts feed. Same record shape (9 rule names, cluster aggregation), just pre-filtered to one ticker.

Use: for SPY hunter, prefer this over the global /api/option-trades/flow-alerts?ticker_symbol=SPY - identical results, simpler URL.

5. GET /api/stock/{ticker}/flow-per-expiry

Flow rolled up by expiry.

Query parameters (inferred): date.

Response per row (inferred): expiry, call_premium, put_premium, call_volume, put_volume, side-split fields.

Use (L1): “what expiries are getting the flow today on SPY?“. 0DTE typically dominates SPY flow - quantify that dominance.

6. GET /api/stock/{ticker}/flow-per-strike

Flow rolled up by strike, daily summary.

Query parameters (inferred): date.

Response per row (likely same shape as #7 below, just one row per strike rather than per timestamp).

Use (L1): end-of-day positioning summary by strike.

7. GET /api/stock/{ticker}/flow-per-strike-intraday (LOAD-BEARING)

Flow per strike at minute granularity through the trading day. This is the load-bearing endpoint of the family.

Query parameters:

ParamTypeRequiredDefaultNotes
datedatenolast trading date-
filterenumnoNetPremiumNetPremium, Volume, Trades

Response per row:

FieldTypeDescription
strikedecimalOption strike
tickerstringUnderlying
timestampISO 8601Minute timestamp
datedateTrading day
call_premium, call_premium_ask_side, call_premium_bid_sidedecimalCall $ by aggressor side
call_volume, call_volume_ask_side, call_volume_bid_sideintCall contracts by side
call_tradesintCall trade count
put_premium, put_premium_ask_side, put_premium_bid_sidedecimalPut $ by side
put_volume, put_volume_ask_side, put_volume_bid_sideintPut contracts by side
put_tradesintPut trade count

Why it’s load-bearing. Per-strike, per-minute, with ASK/BID splits = the SPY hunter sees:

  • Which strikes are getting flow right now (gamma walls forming in real time, not just yesterday’s static positioning).
  • At which side (ask = aggressive buy, bid = aggressive sell).
  • In calls vs puts (directional thesis).

Derived features:

FeatureDefinition
spy_atm_strike_call_ask_premium_1mLatest minute, ATM strike, call premium hitting ask
spy_otm_call_ask_premium_5m_sum5-min rolling sum, OTM call ask-side $
spy_strike_with_max_net_premiumStrike currently leading the flow
spy_pinning_strike_estimateStrike with highest call+put activity (likely pin)

The ask-side OTM call premium feature is the canonical contrarian fade target per 2026-05-22-uw-historical-findings: when this spikes, treat as fade signal, not confirmation.

8. Cross-endpoint workflow for SPY hunter

RTH every minute:
  -> GET /api/stock/SPY/flow-per-strike-intraday?filter=NetPremium
     (load-bearing - the primary minute-level feed)
  -> GET /api/stock/SPY/flow-alerts?newer_than=...&max_dte=0&min_premium=10000
     (the pre-classified cluster feed for SPY)

Session start:
  -> GET /api/stock/SPY/flow-per-expiry
     (which expiries dominate today)
  -> GET /api/stock/SPY/flow-per-strike?date=T-1
     (yesterday's end-of-day positioning by strike)

9. Nautilus integration shape

  • Custom data classes: UWFlowPerStrikeMinute, UWFlowAlertCluster, UWFlowPerExpiryDay.
  • Polling Actor: UWTickerFlowActor polls /flow-per-strike-intraday (every minute) + /flow-alerts (every 30s).
  • Signal Actor computes per-strike + per-side derived features.

10. Known gaps

  • /flow-recent response schema not fully fetched - first fetch needs to confirm. Probably duplicates /api/option-contract/{id}/flow but at ticker scope.
  • /flow-per-expiry and /flow-per-strike response schemas inferred from sibling shape.
  • No streaming/WebSocket for any of these - polling only.

11. Source URLs

  • https://api.unusualwhales.com/docs/operations/PublicApi.TickerController.flow_alerts
  • https://api.unusualwhales.com/docs/operations/PublicApi.TickerController.flow_per_expiry
  • https://api.unusualwhales.com/docs/operations/PublicApi.TickerController.flow_per_strike
  • https://api.unusualwhales.com/docs/operations/PublicApi.TickerController.flow_per_strike_intraday
  • https://api.unusualwhales.com/docs/operations/PublicApi.TickerController.flow_recent

cortana-north-star uw-api-option-trade uw-api-option-contract uw-api-gex-greeks uw-api-tide 2026-05-22-uw-historical-findings 2026-05-15-mk3-setup-hunter-architecture