Options Flow

Real-time flow intelligence from Unusual Whales and Quiver Quant: unusual options flow, dark-pool prints, gamma exposure, max pain, off-exchange volume, borrow cost, and short interest. Detect smart-money positioning and institutional flows across the options and securities-lending markets.

What's inside#

This product surfaces six complementary flow datasets that power sophisticated traders' decision-making:

  • Unusual options flow — live alerts on large, unusual premium transactions (calls/puts, IV-implied moves, unusual-whales scoring)
  • Gamma exposure (GEX) — aggregate gamma and delta exposure per expiration, updated daily; see which prices are gamma-neutral or pinned
  • Max pain — max-pain price per options expiration (the price that triggers max theoretical loss for option holders)
  • Dark-pool prints — institutional block trades + ATS volume from FINRA feeds, cross-ticker or per-ticker
  • Off-exchange volume — daily dark-pool and ATS volume as a % of total volume (Quiver Quant source)
  • Short interest & borrow cost — FINRA bi-monthly short-interest snapshots (shares, % of float, days to cover, 30-day change) and securities-lending fee rates (annualized, from Unusual Whales)

All data is sourced from Unusual Whales (options, GEX, max pain, dark pool, borrow cost) and Quiver Quant (congressional trades, off-exchange, short interest). Caching is short (60–600 seconds) to preserve freshness while protecting vendor budgets.

Access#

4 credits/call. Pro plan ($499/mo) or higher. Alternatively, add the $79/mo Options Flow add-on to Starter or Pro (includes 100,000 monthly credits ≈25k flow calls).

Endpoints#

MethodPathDescription
GET/api/v3/intel/options_flowRecent unusual options flow (cross-ticker, limit 1–200, default 50). Returns {items, count}.
GET/api/v3/intel/options_flow/{ticker}Per-ticker unusual flow alerts (limit 1–200, default 25). Returns {ticker, items, count}.
GET/api/v3/intel/gex/{ticker}Aggregate gamma/delta exposure for a ticker. Returns {ticker, data, is_stale}.
GET/api/v3/intel/max_pain/{ticker}Max-pain price per options expiration. Returns {ticker, items} (expiration → max-pain price).
GET/api/v3/intel/darkpool/{ticker}Per-ticker dark-pool prints (limit 1–200, default 50). Returns {ticker, items, count}.
GET/api/v3/intel/darkpool/recentRecent dark-pool prints across all tickers (limit 1–200, default 50). Returns {items, count}.
GET/api/v3/intel/off_exchange/{ticker}Daily off-exchange (dark pool + ATS) volume (limit 1–200, default 30). Returns {ticker, items, count}.
GET/api/v3/intel/short_interest/{ticker}FINRA bi-monthly short-interest report. Returns {ticker, short_interest_shares, short_interest_pct_of_float, days_to_cover, short_interest_change_pct_30d}.
GET/api/v3/intel/borrow_cost/{ticker}Securities-lending borrow fee + utilization (annualized rate, short-shares available). Returns {ticker, fee_rate, rebate_rate, short_shares_available, data_source_pending}.
GET/api/v3/intel/vol_surface/{ticker}OptionMetrics IvyDB standardized implied-volatility surface, joined from a plain ticker (symbol → secid). Per maturity (days = 30/60/91/182/365) and delta node, per call/put (cp_flag), the interpolated impl_volatility and its dispersion — the clean skew + term-structure grid. ?date= picks a session, ?days= pins one maturity. Lagged academic archive (currently 2011) — omit ?date= for the latest-available surface. Returns {ticker, secid, date, available_dates, rows, n}.
GET/api/options/{ticker}Legacy. Options summary (Silver first, UW fallback): IV rank/percentile, put/call ratio, open interest, GEX, max pain, chain. Returns {ticker, iv_rank, iv_percentile, put_call_ratio, open_interest_total, gamma_exposure, max_pain, chain, as_of_ts}.

Examples#

Example 1: Unusual options flow (bash + curl)#

Pull the latest cross-ticker unusual options flow (4 credits per call).

Shell
1curl -H "Authorization: Bearer $TENGU_API_KEY" \2  "https://firm.tengu.co/api/v3/intel/options_flow?limit=10&min_premium=100000"3 4# Response envelope:5# {6#   "ok": true,7#   "timestamp": "2024-12-16T14:22:00Z",8#   "items": [9#     {10#       "ticker": "TSLA",11#       "expiration": "2024-12-20",12#       "strike": 250.0,13#       "option_type": "call",14#       "side": "buy",15#       "premium": 450000.0,16#       "iv_move": 3.5,17#       "volume": 850,18#       "score": 87,19#       "timestamp": "2024-12-16T14:15:30Z"20#     },21#     {22#       "ticker": "NVDA",23#       "expiration": "2024-12-20",24#       "strike": 150.0,25#       "option_type": "put",26#       "side": "sell",27#       "premium": 320000.0,28#       "iv_move": -2.1,29#       "volume": 650,30#       "score": 82,31#       "timestamp": "2024-12-16T14:10:45Z"32#     }33#   ],34#   "count": 235# }

Example 2: GEX + max pain (Python requests)#

Fetch gamma exposure and max pain for a ticker (4 credits per endpoint).

Python
1import os, requests2 3# 1. Get gamma exposure for AAPL (4 credits)4r = requests.get(5    "https://firm.tengu.co/api/v3/intel/gex/AAPL",6    headers={"Authorization": f"Bearer {os.environ['TENGU_API_KEY']}"},7    timeout=30,8)9r.raise_for_status()10gex = r.json()11print(f"GEX data for {gex['ticker']}")12print(f"  date: {gex['data'].get('date')}")13print(f"  gamma_long: {gex['data'].get('gamma_long')}")14print(f"  gamma_short: {gex['data'].get('gamma_short')}")15print(f"  delta_exposure: {gex['data'].get('delta_exposure')}")16print(f"  is_stale: {gex.get('is_stale')}")17 18# 2. Get max pain (4 credits)19r = requests.get(20    "https://firm.tengu.co/api/v3/intel/max_pain/AAPL",21    headers={"Authorization": f"Bearer {os.environ['TENGU_API_KEY']}"},22    timeout=30,23)24r.raise_for_status()25max_pain = r.json()26print(f"\nMax pain for {max_pain['ticker']}")27for item in max_pain.get("items", []):28    print(f"  {item['expiration']}: ${item['max_pain_price']}")

Example 3: Implied-volatility surface (skew + term structure)#

Pull the standardized OptionMetrics IvyDB vol surface for a ticker — the clean grid behind risk-reversals, butterflies and the ATM term structure. The archive is a lagged academic slice (currently 2011), so omit ?date= for the latest-available surface; the served date and the covered date range come back in the response.

Shell
1curl -H "Authorization: Bearer $TENGU_API_KEY" \2  "https://firm.tengu.co/api/v3/intel/vol_surface/AAPL?days=30"3 4# Response structure:5# {6#   "ok": true,7#   "timestamp": "2024-12-16T14:23:00Z",8#   "ticker": "AAPL",9#   "secid": 106276,10#   "date": "2011-12-30",11#   "requested_date": null,12#   "mode": "latest_available",13#   "days_filter": 30.0,14#   "available_dates": { "start": "2011-01-03", "end": "2011-12-30", "n": 252 },15#   "link": { "secid": 106276, "link_start": "1996-01-02", "link_end": "2023-12-29", "link_score": 1 },16#   "n": 8,17#   "rows": [18#     { "days": 30.0, "delta": -10.0, "cp_flag": "P", "impl_volatility": 0.3421, "dispersion": 0.0184 },19#     { "days": 30.0, "delta": -25.0, "cp_flag": "P", "impl_volatility": 0.3018, "dispersion": 0.0121 },20#     { "days": 30.0, "delta": 50.0, "cp_flag": "C", "impl_volatility": 0.2607, "dispersion": 0.0093 },21#     { "days": 30.0, "delta": 25.0, "cp_flag": "C", "impl_volatility": 0.2489, "dispersion": 0.0110 }22#   ],23#   "note": "Standardized IvyDB surface node = (days, delta, cp_flag): interpolated impl_volatility + its dispersion. Calls carry positive delta (10/25/50/75), puts negative (-75/-50/-25/-10).",24#   "source": "warehouse:bronze.optionmetrics_vsurf+bronze.optionmetrics_link"25# }
Python
1import os, requests2 3# Read the 30-day skew: implied vol by delta node4r = requests.get(5    "https://firm.tengu.co/api/v3/intel/vol_surface/AAPL",6    params={"days": 30},7    headers={"Authorization": f"Bearer {os.environ['TENGU_API_KEY']}"},8    timeout=30,9)10r.raise_for_status()11surf = r.json()12print(f"{surf['ticker']} 30d surface as of {surf['date']} "13      f"(archive covers {surf['available_dates']['start']}..{surf['available_dates']['end']})")14for node in surf["rows"]:15    print(f"  {node['cp_flag']} delta {node['delta']:+.0f}: IV {node['impl_volatility']:.2%}")