Sign up

Products

Status

Options Flow

Options and securities-lending intelligence: unusual options flow, the options chain with Greeks, implied-volatility analytics, gamma exposure, max pain, dark-pool prints, off-exchange volume, short interest and borrow cost. Live routes show positioning now; history routes show how it built up.

What's inside

This product groups seven kinds of flow data:

  • Unusual options flow: live alerts on large premium transactions (calls and puts, sweep flag, side-of-book sentiment), a warehouse history of flow aggregates, and daily options volume with put/call ratio.
  • Options chain and implied volatility: a chain snapshot with per-contract Greeks, implied volatility and open interest; live IV rank, skew and term structure; and a standardized academic volatility surface (lagged archive).
  • Options tide and net premium: the whole market's, a sector's or an ETF's options net-premium tide through a session, one ticker's per-minute net premium, and a daily options-volume archive per ticker.
  • Dealer positioning: aggregate gamma and delta exposure (GEX), the current session's GEX by strike, daily per-strike GEX history, and max pain per expiration.
  • Dark pool and off-exchange: individual dark-pool prints (live and history, with the NBBO at print time) and daily off-exchange volume as a share of total volume.
  • Short selling: FINRA bi-monthly short interest, the daily consolidated short-volume tape, and multi-year short-selling history.
  • Borrow cost and securities lending: the live securities-lending fee, rebate and utilization, and its daily history; daily lending supply and demand back to 2003; and daily broker borrow fees and shares available.

Live routes read the options-flow feed (flow, dark-pool prints, GEX, max pain, options volume), the alternative-data feed (off-exchange volume) and the market-data feed (options chain, FINRA short interest). History routes read the warehouse capture of those feeds and licensed research archives. Live responses are cached briefly: 60 seconds for flow, dark-pool prints and the options chain, up to 10 minutes for off-exchange volume, and 6 hours for FINRA short interest, which settles twice a month.

Access

Note:

4 credits/call. Pro plan ($499/mo) or higher. On Starter, add the $79/mo Options Flow add-on instead (includes 100,000 monthly credits ≈25k flow calls). Pro and above already include this product.

Every route on this page is GET and costs 4 credits.

Freshness policy

The live flow, dark-pool, off-exchange and GEX routes accept freshness (off, live or strict; default off):

ValueBehavior
offServes the data with its age: as_of (newest record), age_hours and is_stale.
liveReturns 503 with error code data_stale instead of serving a stale feed.
strictSame as live on these routes. They grade one signal, the age of the newest record, so the two policies refuse in the same cases.

It applies to /api/v3/intel/options_flow, /api/v3/intel/options_flow/{ticker}, /api/v3/intel/darkpool/recent, /api/v3/intel/darkpool/{ticker}, /api/v3/intel/off_exchange/{ticker} and /api/v3/intel/gex/{ticker}. On the flow, dark-pool and off-exchange routes, is_stale is null when the feed returned no records: an empty feed is unknown, not stale. GEX publishes daily and is flagged stale when its newest row is more than 5 calendar days old. A 503 refusal is not charged. Retry with freshness=off only if you are prepared to accept stale data explicitly.

Endpoints

Unusual options flow

MethodPathMCP toolDescription
GET/api/v3/intel/options_flowintel_options_flowRecent unusual options flow across the market. ?limit= (1-200, default 50), ?min_premium= (USD, 0-100,000,000, default 50,000), ?freshness=. Returns {items, count, as_of, age_hours, is_stale}.
GET/api/v3/intel/options_flow/{ticker}intel_options_flow_tickerUnusual flow alerts for one ticker. ?limit= (1-200, default 25), ?freshness=. Returns {ticker, items, count, as_of, age_hours, is_stale}.
GET/api/v3/intel/options_flow_history/{ticker}intel_options_flow_historyHow flow evolved: the ~60-second warehouse capture behind the live flow route. Requires ?date= or ?start= (with optional ?end=); at most 7 days per request (422 otherwise). ?min_premium= (USD, 0 or more), ?side= (bullish or bearish), ?limit= (1-5000, default 1000). Coverage begins 2026-05-10.
GET/api/v3/intel/options_volume/{ticker}intel_options_volumeDaily options volume and put/call ratio for one ticker. ?limit= (1-200, default 30 days).

Options chain and implied volatility

MethodPathMCP toolDescription
GET/api/v3/intel/options_chain/{ticker}intel_options_chainLive options-chain snapshot for an underlying (AAPL, BRK.B, I:SPX): per contract delta, gamma, theta, vega, implied volatility, open interest, last quote and last trade (each with its own UTC timestamp: quote_ts, last_trade_ts) and the day bar with its date (day_as_of, which for an illiquid strike can be days old). ?expiration_date= (YYYY-MM-DD), or a range with ?min_expiration= / ?max_expiration=; ?min_strike= / ?max_strike=; ?contract_type= (call or put); ?limit= (1-2500, default 250), nearest expiry first. Returns {ticker, contracts, count, pages_fetched, complete, truncated, source, mode, as_of, fetched_at, underlying_price, underlying_as_of}; when the answer was cut, truncation_reason and hint say where. A dead feed is a 503 (not charged); a symbol that is not listed today is a 404 (underlying_not_listed); an empty 200 carries result: "empty_but_healthy" and underlying_listed.
GET/api/v3/intel/options_contract/{option_ticker}intel_options_contractLive quote and trade tape for one contract: pass the OCC ticker options_chain returns as contract_symbol (O:SPY260924C00660000; the O: is optional). ?limit= (1-1000, default 100, applied to quotes and to trades), ?include= (quotes, trades, or both). Returns the contract's terms, quotes (bid, ask, sizes, midpoint, exchanges) and trades (price, size, exchange, condition codes), newest first, each with a UTC timestamp, plus components, as_of and fetched_at. A tape that failed is null, never []. An empty answer carries contract_listed; an unlisted contract with no activity is a 404.
GET/api/v3/intel/iv_analytics/{ticker}intel_iv_analyticsIV rank (current IV and its 1-year rank, with a plain-language read), skew (risk reversal per delta) and term structure (IV and implied move per expiry, labelled backwardation or contango), in one call. ?date= (YYYY-MM-DD, omit for the latest session), ?limit= (1-400, default 60 rows per block). Each block degrades independently.
GET/api/v3/intel/vol_surface/{ticker}intel_vol_surfaceStandardized 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 and term-structure grid. ?date= picks a session, ?days= pins one maturity, ?limit= (1-2000, default 500). Lagged academic archive (currently 2011): omit ?date= for the latest-available surface. Returns {ticker, secid, date, available_dates, rows, n}. For today's volatility use iv_analytics.

Dealer positioning

MethodPathMCP toolDescription
GET/api/v3/intel/gex/{ticker}intel_gexAggregate gamma and delta exposure for a ticker, from the most recent daily row. ?freshness=. Returns {ticker, exposure, as_of, is_stale, source}.
GET/api/v3/intel/gex_strikes/{ticker}intel_gex_strikesDealer greek exposure per strike for the current session, all expiries summed at each strike: call_gex, put_gex and net_gex in shares of underlying per $1 move (gamma × open interest × 100; calls positive, puts negative), call_delta and put_delta in shares, and charm and vanna per leg and net. totals gives the ladder's call, put and net GEX, and gamma_usd_per_1pct_move gives them in dollars per 1% move at the stated spot (null with a reason when the spot is not from the exposure's session). The units block states each, as on intel_gex and intel_gex_history. Narrow with ?min_strike= and ?max_strike=; for earlier sessions use gex_history with per_strike=true. An unknown symbol is a 404.
GET/api/v3/intel/gex_history/{ticker}intel_gex_historyHow dealer positioning shifted, from daily per-strike snapshots. Requires ?date= or ?start= (with optional ?end=); at most 30 days per request (422 otherwise). Default: one row per trading day (call, put and net GEX, strike count, max-gamma strike); ?per_strike=true returns the strike ladder (gamma, charm, vanna, call and put GEX per strike). ?limit= (1-50000, default 10000). Coverage begins 2026-05-10.
GET/api/v3/intel/max_pain/{ticker}intel_max_painMax-pain price per options expiration. Returns {ticker, items}; each item has expiry, max_pain and spot.

Options tide and net premium

Net premium is premium traded at the ask minus premium traded at the bid, in USD. The tide routes serve a session's ticks as the feed publishes them: never add ticks together.

MethodPathMCP toolDescription
GET/api/v3/intel/market_tideintel_market_tideWhether options money leaned to calls or puts through a session, market-wide: one tick every 5 minutes with net call premium, net put premium (USD) and net volume (contracts), each cumulative since the open as of the tick's UTC time, so the latest tick is the session so far. Omit ?date= for the latest session, read live (60 s cache); a past session comes from the tide archive, which holds sessions from 2026-06-05, each captured after its close. A date that is not a session is a 422; a past session the archive missed says so (status: "not_in_archive").
GET/api/v3/intel/sector_tide/{sector}intel_sector_tideOne sector's options net-premium tide for a session, per tick with its UTC time (archived sessions: one tick per minute): net call and net put premium (USD) and net volume (contracts). Whether a tick is that interval's flow or a running total is not stated, so never add ticks. Sectors: technology, healthcare, energy, consumer_cyclical, consumer_defensive, communication_services, industrials, utilities, real_estate, basic_materials (anything else is a 422 with the list). Omit ?date= for the latest session, read live; past sessions from the tide archive (from 2026-06-05).
GET/api/v3/intel/etf_tide/{etf}intel_etf_tideOne ETF's options net-premium tide for a session, per tick with its UTC time (archived sessions: one per minute): net call and net put premium (USD), net volume (contracts) and the ETF's price (USD). Any ETF for the latest session, read live; past sessions (?date=) from the tide archive for SPY, QQQ and IWM only (from 2026-06-05), and a past date for another ETF is a 422 naming those three.
GET/api/v3/intel/net_premium/{ticker}intel_net_premiumWhen in a session options buyers leaned to calls or puts on one name: one row per minute carrying that minute's flow (tape_time, UTC), with net call and net put premium (USD), net call and put volume and total call and put volume by side of the book (contracts), and the feed's net delta (read for sign and relative size). Omit ?date= for the latest session (60 s cache); a past session inside the feed's history window (about 730 sessions) is cached for hours, and an older one is a 422. An unknown symbol is a 404.
GET/api/v3/intel/options_volume_history/{ticker}intel_options_volume_historyDaily options volume history, one row per session, newest first: call and put volume (contracts, also split by side of the book), call and put open interest (contracts), call and put premium and net premium (USD), the feed's bullish and bearish premium split (USD), its 3-, 7- and 30-session average volumes, and put_call_ratio (null with a reason when there were no calls). Each ticker's depth is its own, about two years for most, served as history_from; a window before it answers status: "before_coverage". Each session is captured once after its close; as_of is the newest session served. Requires ?date= or ?start= (with optional ?end=), at most 1,830 days; ?limit= (1-2000, default 500). An unknown symbol is a 404.

Dark pool and off-exchange

MethodPathMCP toolDescription
GET/api/v3/intel/darkpool/recentintel_darkpool_recentRecent dark-pool prints across all tickers. ?limit= (1-200, default 50), ?freshness=. Returns {items, count, as_of, age_hours, is_stale}.
GET/api/v3/intel/darkpool/{ticker}intel_darkpool_tickerDark-pool prints for one ticker. ?limit= (1-200, default 50), ?freshness=. Returns {ticker, items, count, as_of, age_hours, is_stale}.
GET/api/v3/intel/darkpool_history/{ticker}intel_darkpool_historyIndividual dark-pool prints from the warehouse capture, newest first, with the NBBO at print time. Requires ?date= or ?start= (with optional ?end=); at most 7 days per request (422 otherwise). ?min_premium= (USD, 0 or more), ?limit= (1-5000, default 1000). Coverage begins 2026-05-10.
GET/api/v3/intel/off_exchange/{ticker}intel_off_exchangeDaily off-exchange (dark pool + ATS) volume and its share of total volume, newest session first. ?limit= (1-200, default 30 days), ?freshness=. Returns {ticker, items, count, as_of, age_hours, is_stale}. Served from a warehouse copy of the feed first, which holds sessions from 2026-05-08 (data_from, history_floor, coverage_note; archive_ingested_at is when the copy last carried the rows) and has total_volume: null because the copy does not keep it; the live feed answers only for a ticker the copy does not hold. When neither can answer: 503 upstream_unavailable, not billed (codes as on Alt-Data).

Short interest, borrow cost and securities lending

MethodPathMCP toolDescription
GET/api/v3/intel/short_interest/{ticker}intel_short_interestFINRA bi-monthly short-interest report. Returns {ticker, short_interest_shares, short_interest_pct_of_float, days_to_cover, short_interest_change_pct_30d, avg_daily_volume_at_settlement}. borrow_fee_pct_annualized is always null here; use borrow_cost. An answer with no short-interest record carries the same fields, each null, with source saying why; it used to omit avg_daily_volume_at_settlement and prior_settlement_date.
GET/api/v2/short-interest/{ticker}short_interestThe latest settled short-interest record (shares short, days to cover) with up to five recent daily short-volume rows. Returns {ticker, short_interest, recent_short_volume, source}; short_interest is null when no record is held.
GET/api/v3/origin/short_activity/{ticker}origin_short_activityHow shorted a name is: FINRA's daily short-sale volume (short ratio per session) next to the settled short interest (position, days to cover). ?days= (5-180, default 30). The daily short_volume and total_volume count only trades reported to FINRA facilities, that is off-exchange volume, so total_volume is not the stock's total daily volume and the ratio is the off-exchange short share; volume_scope (finra_off_exchange) and volume_note say so.
GET/api/v3/intel/short_interest_history/{ticker}intel_short_interest_historyMulti-year short-selling history: the daily off-exchange short-volume series (short and total shares across FINRA venues, short ratio, back to 2006) plus the official bi-monthly short-interest series. Omit both ?start= and ?end= to get the most recent available coverage (the archive lags, so this is the reliable call). Pass either bound for a fixed window: ?start= (YYYY-MM-DD, default one year before end), ?end= (default today). ?limit= (1-5000, default 400 daily rows).
GET/api/v3/intel/borrow_cost/{ticker}intel_borrow_costLive securities-lending borrow cost. Returns fee_rate_pct (annualized), borrow_fee_band (easy under 1%, hard 1-10%, extreme over 10%), rebate_rate_pct, utilization_pct, short_shares_available, is_stale (prints older than 48 hours), data_source_pending and source.
GET/api/v3/intel/borrow_cost_history/{ticker}intel_borrow_cost_historyDaily borrow-cost history from the licensed securities-finance archive: annualized fee, rebate, utilization and on-loan and lendable quantities, falling back to an option-implied borrow rate when the archive lacks the name. ?start= (default 90 days before end), ?end= (default today), at most 365 days per request; ?limit= (1-2000, default 365).
GET/api/v3/short/lending/{ticker}short_lendingDaily securities-lending supply and demand for a US stock: lendable and actively lendable shares and USD value, shares and USD value on loan, shares on loan to short sellers, utilization (percent, 0-100), a 1-10 cost-of-borrow score and average loan tenure in days. Published about six trading days after the day; history from 2003. This is lending data, not short interest: finra_cross_check lists FINRA's settled short interest on each settlement date in the window beside short_loan_quantity and their ratio. For the headline fee use borrow_cost_history; for shares held short use origin/short_activity. ?start= (default 90 days before end), ?end=, window up to 366 days; ?limit= (1-400, default 120).
GET/api/v3/short/borrow/{ticker}short_borrowDaily borrow cost and availability for a US stock from a broker-lending feed: indicative borrow fee and rebate (percent a year) and shares available to borrow, one row per trading day (that day's last snapshot). Availability is reported only up to 10,000,000 shares; above that shares_available is null and shares_available_min is 10,000,000. History from 2026-03-16, updated each trading day. This is borrow supply, not short interest; FINRA's settled short interest in the window is listed for context. Use it for hard-to-borrow and squeeze-cost checks. ?start= (default 90 days before end), ?end=, window up to 366 days; ?limit= (1-400, default 120).

Examples

Example 1: Unusual options flow (bash + curl)

Pull the latest cross-ticker unusual options flow (4 credits per call). freshness=live refuses with 503 data_stale rather than serve a stale feed.

Shell
curl -H "Authorization: Bearer $WEALTHNOW_API_KEY" \  "https://firm.wealthnow.io/api/v3/intel/options_flow?limit=10&min_premium=100000&freshness=live" # Illustrative response structure, not a live sample:# {#   "ok": true,#   "timestamp": "2026-09-24T14:22:00Z",#   "items": [#     {#       "ticker": "TSLA",#       "option_type": "CALL",#       "strike": 250.0,#       "expiry": "2026-09-26",#       "premium": 450000.0,#       "volume": 850,#       "open_interest": 12400,#       "is_sweep": true,#       "is_unusual": true,#       "sentiment": "bullish",#       "executed_at": "2026-09-24T14:15:30Z",#       "id": "..."#     }#   ],#   "count": 1,#   "as_of": "2026-09-24T14:15:30Z",#   "age_hours": 0.1,#   "is_stale": false# }

sentiment is derived from where the premium traded: mostly at the ask on calls, or at the bid on puts, reads bullish; the reverse reads bearish; a mix reads neutral. The alert itself is the "unusual" signal, so is_unusual is normally true.

Example 2: GEX + max pain (Python requests)

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

Python
import os, requests headers = {"Authorization": f"Bearer {os.environ['WEALTHNOW_API_KEY']}"} # 1. Gamma exposure for AAPL (4 credits)r = requests.get(    "https://firm.wealthnow.io/api/v3/intel/gex/AAPL",    headers=headers,    timeout=30,)r.raise_for_status()gex = r.json()print(f"GEX for {gex['ticker']} as of {gex.get('as_of')} (stale: {gex.get('is_stale')})")exposure = gex.get("exposure") or {}for field, value in exposure.items():    print(f"  {field}: {value}") # 2. Max pain per expiration (4 credits)r = requests.get(    "https://firm.wealthnow.io/api/v3/intel/max_pain/AAPL",    headers=headers,    timeout=30,)r.raise_for_status()max_pain = r.json()print(f"\nMax pain for {max_pain['ticker']}")for item in max_pain.get("items", []):    print(f"  {item['expiry']}: max pain {item['max_pain']} (spot {item['spot']})")

exposure is the feed's most recent daily greek-exposure row, passed through as the feed reports it. It is {} when the feed has no row for the ticker.

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

Pull the standardized implied-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.

curl -H "Authorization: Bearer $WEALTHNOW_API_KEY" \  "https://firm.wealthnow.io/api/v3/intel/vol_surface/AAPL?days=30" # Response structure:# {#   "ok": true,#   "timestamp": "2024-12-16T14:23:00Z",#   "ticker": "AAPL",#   "secid": 106276,#   "date": "2011-12-30",#   "requested_date": null,#   "mode": "latest_available",#   "days_filter": 30.0,#   "available_dates": { "start": "2011-01-03", "end": "2011-12-30", "n": 252 },#   "link": { "secid": 106276, "link_start": "1996-01-02", "link_end": "2023-12-29", "link_score": 1 },#   "n": 8,#   "rows": [#     { "days": 30.0, "delta": -10.0, "cp_flag": "P", "impl_volatility": 0.3421, "dispersion": 0.0184 },#     { "days": 30.0, "delta": -25.0, "cp_flag": "P", "impl_volatility": 0.3018, "dispersion": 0.0121 },#     { "days": 30.0, "delta": 50.0, "cp_flag": "C", "impl_volatility": 0.2607, "dispersion": 0.0093 },#     { "days": 30.0, "delta": 25.0, "cp_flag": "C", "impl_volatility": 0.2489, "dispersion": 0.0110 }#   ],#   "note": "Standardized implied-vol 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).",#   "source": "warehouse:[internal]+[internal]"# }

Example 4: Today's chain and volatility picture

Shell
# Calls expiring on one date, with Greekscurl -H "Authorization: Bearer $WEALTHNOW_API_KEY" \  "https://firm.wealthnow.io/api/v3/intel/options_chain/NVDA?expiration_date=2026-10-17&contract_type=call&limit=50" # IV rank, skew and term structure for the latest sessioncurl -H "Authorization: Bearer $WEALTHNOW_API_KEY" \  "https://firm.wealthnow.io/api/v3/intel/iv_analytics/NVDA"

Illustrative structures, not live samples:

JSON
{  "ok": true,  "timestamp": "2026-09-24T14:30:00Z",  "ticker": "NVDA",  "expiration_date": "2026-10-17",  "contract_type": "call",  "contracts": [    {      "contract_symbol": "O:NVDA261017C00180000",      "underlying": "NVDA",      "contract_type": "call",      "strike": 180.0,      "expiration_date": "2026-10-17",      "exercise_style": "american",      "shares_per_contract": 100,      "bid": 8.1,      "ask": 8.25,      "bid_size": 40,      "ask_size": 25,      "last_price": 8.2,      "last_size": 3,      "day_volume": 15230,      "day_vwap": 8.04,      "open_interest": 48210,      "implied_volatility": 0.47,      "delta": 0.54,      "gamma": 0.019,      "theta": -0.21,      "vega": 0.23,      "underlying_price": 181.4    }  ],  "count": 1}
JSON
{  "ok": true,  "timestamp": "2026-09-24T14:30:05Z",  "ticker": "NVDA",  "as_of": "2026-09-23",  "iv_rank": {    "implied_volatility": 0.47,    "iv_rank_1y": 31.0,    "underlying_close": 181.4,    "interpretation": "vol MID-RANGE vs its 1y history",    "note": null  },  "skew": {    "rows": [{ "delta": 0.25, "risk_reversal": -0.031 }],    "count": 1,    "note": null  },  "term_structure": {    "rows": [      { "expiry": "2026-10-17", "dte": 23, "implied_volatility": 0.47, "implied_move": 12.1, "implied_move_pct": 6.7 }    ],    "count": 1,    "shape": null,    "note": null  },  "source": "warehouse:iv-analytics-archive"}

If the live chain feed is unavailable, options_chain answers 503 with error code options_chain_unavailable and a Retry-After header; it is not charged and it never substitutes a chain without Greeks. If a later page fails after the first, the contracts already read are served with partial: true and complete: false. Check complete before treating the chain as whole: a liquid underlying has thousands of contracts, so narrow with the expiry and strike filters. In iv_analytics, iv_rank_1y runs from 0 (the 52-week low) to 100 (the high); interpretation reads rich at 75 or above and cheap at 25 or below. Skew rows carry expiry beside delta and risk_reversal, one row per expiry and delta, ordered by expiry. The term structure's shape compares the expiries nearest 30 and 90 days to expiry over the whole session, with 0-DTE expiries left out, and shape_tenors names the two it compared; shape is null when two such distinct expiries are not available. limit caps the term rows shown (count), not the comparison, and n_expiries counts every expiry read. A block with no data returns empty rows with its own note.

Example 5: How flow and dealer positioning evolved

The history routes need a bounded window: date= for one day, or start= (and optionally end=) for up to 7 days of flow or dark-pool prints, or up to 30 days of GEX. Coverage begins 2026-05-10; earlier windows return no rows.

Shell
# Bullish flow snapshots on NVDA over a weekcurl -H "Authorization: Bearer $WEALTHNOW_API_KEY" \  "https://firm.wealthnow.io/api/v3/intel/options_flow_history/NVDA?start=2026-08-20&end=2026-08-26&side=bullish" # Daily GEX into an expirycurl -H "Authorization: Bearer $WEALTHNOW_API_KEY" \  "https://firm.wealthnow.io/api/v3/intel/gex_history/SPY?start=2026-09-01&end=2026-09-19"

Illustrative structures, not live samples:

JSON
{  "ok": true,  "timestamp": "2026-09-24T14:31:00Z",  "ticker": "NVDA",  "start": "2026-08-20",  "end": "2026-08-26",  "n": 1,  "rows": [    { "as_of_ts": "2026-08-26T19:58:00+00:00", "polarity": 0.42, "n_alerts": 37, "premium_total": 18400000.0 }  ],  "summary": {    "peak_snapshot_premium_usd": 18400000.0,    "avg_snapshot_premium_usd": 18400000.0,    "avg_polarity": 0.42,    "bullish_snapshots": 1,    "bearish_snapshots": 0,    "scope": "served_rows",    "n_rows": 1,    "complete": true  },  "filters": { "min_premium": null, "side": "bullish" },  "truncated": false,  "source": "warehouse:options-flow-archive"}
JSON
{  "ok": true,  "timestamp": "2026-09-24T14:31:02Z",  "ticker": "SPY",  "start": "2026-09-01",  "end": "2026-09-19",  "mode": "daily_aggregate",  "n": 1,  "rows": [    {      "date": "2026-09-19",      "as_of_ts": "2026-09-20T02:50:00+00:00",      "call_gex_total": 1.9e9,      "put_gex_total": -1.2e9,      "net_gex": 7.0e8,      "n_strikes": 212,      "max_gamma_strike": 660.0    }  ],  "truncated": false,  "source": "warehouse:gex-archive"}

Each flow row is a point-in-time aggregate: polarity runs from -1 (net bearish) to 1 (net bullish). Consecutive snapshots re-aggregate largely the same alerts, so never sum premium_total across rows; that double-counts. Use the per-snapshot peak and average in summary. With per_strike=true, GEX rows carry date, as_of_ts, strike, gamma, charm, vanna, call_gex and put_gex. A daily GEX snapshot is written the morning after its trading day.

Example 6: Dark-pool blocks over a week

Shell
# Prints of $1M or more in AAPLcurl -H "Authorization: Bearer $WEALTHNOW_API_KEY" \  "https://firm.wealthnow.io/api/v3/intel/darkpool_history/AAPL?start=2026-09-15&end=2026-09-19&min_premium=1000000" # Daily off-exchange share of volume, refusing stale datacurl -H "Authorization: Bearer $WEALTHNOW_API_KEY" \  "https://firm.wealthnow.io/api/v3/intel/off_exchange/AAPL?limit=10&freshness=live"

Illustrative structure, not a live sample:

JSON
{  "ok": true,  "timestamp": "2026-09-24T14:32:00Z",  "ticker": "AAPL",  "start": "2026-09-15",  "end": "2026-09-19",  "n": 1,  "rows": [    {      "executed_at": "2026-09-19T19:41:07Z",      "price": 227.1,      "size": 25000,      "premium": 5677500.0,      "market_center": "D",      "nbbo_bid": 227.08,      "nbbo_ask": 227.12,      "canceled": false    }  ],  "summary": {    "total_premium_usd": 5677500.0,    "total_size": 25000,    "n_canceled_excluded": 0  },  "filters": { "min_premium": 1000000.0 },  "truncated": false,  "source": "warehouse:darkpool-archive"}

On options_flow_history and darkpool_history, the summary totals cover the rows served, not necessarily the whole window: scope is served_rows, n_rows counts them, and complete is false (with a scope_note) when the read hit limit. Raise limit or narrow the window for a complete total. On options_flow_history, peak_snapshot_premium_usd and avg_snapshot_premium_usd are null, not 0, when no served snapshot carried a premium, and premium_null_reason says so. Canceled prints stay in rows with canceled: true but are left out of the summary totals. Compare price with nbbo_bid and nbbo_ask to see whether a block printed at the bid, the ask or in between. Live prints from /api/v3/intel/darkpool/{ticker} carry ticker, size, price, notional, executed_at, trade_code and exchange. Off-exchange items carry date, off_exchange_volume, short_volume, total_volume (null on rows from the warehouse copy) and dark_pool_pct.

Example 7: Short selling and borrow cost

Shell
# Daily short-volume tape next to settled short interest (last 60 sessions)curl -H "Authorization: Bearer $WEALTHNOW_API_KEY" \  "https://firm.wealthnow.io/api/v3/origin/short_activity/GME?days=60" # Most recent available short-selling history (no dates)curl -H "Authorization: Bearer $WEALTHNOW_API_KEY" \  "https://firm.wealthnow.io/api/v3/intel/short_interest_history/GME" # A fixed multi-year windowcurl -H "Authorization: Bearer $WEALTHNOW_API_KEY" \  "https://firm.wealthnow.io/api/v3/intel/short_interest_history/GME?start=2020-06-01&end=2021-06-30" # Daily borrow cost over a quartercurl -H "Authorization: Bearer $WEALTHNOW_API_KEY" \  "https://firm.wealthnow.io/api/v3/intel/borrow_cost_history/GME?start=2021-01-01&end=2021-03-31"

Illustrative structures, not live samples:

JSON
{  "ok": true,  "timestamp": "2026-09-24T14:33:00Z",  "ticker": "GME",  "window_days": 60,  "identity_verified": true,  "daily_short_volume": {    "available": true,    "latest_date": "2026-09-23",    "latest_short_volume": 1204113.5,    "latest_total_volume": 3050221.25,    "latest_short_ratio": 0.3948,    "window_mean_short_ratio": 0.41,    "window_max_short_ratio": 0.52,    "n_sessions": 41,    "series": [      { "date": "2026-09-23", "short_volume": 1204113.5, "total_volume": 3050221.25, "short_ratio": 0.3948 }    ]  },  "settled_short_interest": {    "available": true,    "settlement_date": "2026-09-15",    "short_position": 34800000.0,    "previous_short_position": 33100000.0,    "change_pct": 5.14,    "days_to_cover": 4.2,    "avg_daily_volume": 8300000.0  },  "data_source": "FINRA (consolidated tape + settled short interest)"}
JSON
{  "ok": true,  "timestamp": "2026-09-24T14:33:05Z",  "ticker": "GME",  "start": "2021-01-01",  "end": "2021-03-31",  "cusip": "36467W109",  "n": 1,  "series": [    {      "date": "2021-03-31",      "fee_pct": 0.9,      "rebate_pct": -0.8,      "utilization_pct": 62.0,      "short_loan_quantity": 20100000,      "quantity_on_loan": 21400000,      "lendable_quantity": 34500000    }  ],  "source": "warehouse:securities-finance-archive",  "as_of": "2021-03-31",  "identity_verified": true}

Read the short measures together, never interchangeably:

  • Short ratio (daily short-volume share) is a flow: what fraction of a session's prints were short-marked.
  • Short interest is a stock: the settled position, published twice a month with a publication lag.
  • Share volume in the tape is fractional by design, because of retail fractional trading, so values below one share are genuine.
  • short_interest_history returns daily_short_volume rows (date, short_shares, total_shares, short_ratio) and short_interest_bimonthly rows. Its daily archive lags, so a window ending today can come back empty. Omit both dates to get the latest available rows (mode: "latest_available", with the served start and end); with either date the response reports mode: "window".

Borrow history comes from a licensed archive that refreshes on a lag:

  • Check as_of before treating the newest row as current, and use /api/v3/intel/borrow_cost/{ticker} for the live read.
  • When the archive lacks the name, rows carry implied_borrow_pct and tenor_days from the option-implied borrow rate instead, with identity_verified: false.
  • A symbol that does not resolve to exactly one current security returns an empty series with a warning rather than a possibly wrong series.