Unusual Whales API - Dark Pool endpoints
Layer mapping: L1 (0DTE) load-bearing. Off-exchange (ATS / dark pool) prints are institutional positioning made visible only after print. For SPY, large dark-pool prints near a key level are high-conviction context for the SPY hunter.
Two endpoints: recent (all tickers, time-windowed feed) and per-ticker.
1. Base contract
| Property | Value |
|---|---|
| Base URL | https://api.unusualwhales.com |
| Auth | Authorization: Bearer <token> header |
| Response envelope | { "data": [ ... ] } |
| Status codes | 200, 422, 500 |
| Rate limits | Not specified |
2. Endpoint matrix
| # | Path | Purpose |
|---|---|---|
| 1 | GET /api/darkpool/recent | Cross-ticker feed of recent dark-pool prints |
| 2 | GET /api/darkpool/{ticker} | One ticker’s dark-pool prints with time windowing |
3. Common print schema (both endpoints)
| Field | Type | Description |
|---|---|---|
ticker | string | Symbol |
price | decimal (string) | Execution price |
size | int | Trade quantity (shares) |
premium | decimal (string) | Notional value (price * size) |
volume | int | Consolidated daily volume at print time |
executed_at | ISO 8601 | Execution timestamp |
trf_executed_at | ISO 8601 / null | TRF reporting timestamp |
market_center | string | Market center / ATS code |
nbbo_bid | decimal (string) | NBBO bid at print |
nbbo_bid_quantity | int | NBBO bid size |
nbbo_ask | decimal (string) | NBBO ask at print |
nbbo_ask_quantity | int | NBBO ask size |
trade_settlement | string | E.g. "regular_settlement" |
ext_hour_sold_codes | string | Extended-hours indicator |
sale_cond_codes | string / null | Sale condition codes |
trade_code | string / null | Trade classification code |
canceled | bool | Was the print canceled / busted |
tracking_id | int | Unique trade identifier |
Key derived features:
print_side_estimate= comparepricevsnbbo_bid/nbbo_ask. At ask → likely buyer-aggressive; at bid → seller-aggressive. Inside the spread → ambiguous.is_block=size >= 10000(conventional block threshold).print_to_daily_volume=size / volume(how much of today’s tape this one print represents).
4. GET /api/darkpool/recent - Cross-ticker feed
Time-windowed feed of recent prints across all tickers.
Query parameters:
| Param | Type | Required | Default | Range |
|---|---|---|---|---|
limit | int | no | 100 | 1 to 200 |
date | date | no | last trading date | - |
min_premium | int | no | 0 | >= 0 |
max_premium | int | no | - | - |
min_size | int | no | 0 | >= 0 |
max_size | int | no | - | - |
min_volume | int | no | 0 | >= 0 |
max_volume | int | no | - | - |
Use in MK3: secondary feed. Useful for whole-market context
(min_premium=1000000 catches all $1M+ prints), but L1 SPY hunter
will rely on the per-ticker endpoint.
5. GET /api/darkpool/{ticker} - Per ticker
Same schema, filtered to one ticker, with time-windowing parameters.
Path parameter:
| Param | Required | Notes |
|---|---|---|
ticker | yes | E.g. SPY |
Query parameters:
| Param | Type | Required | Default | Range |
|---|---|---|---|---|
date | date | no | last trading date | - |
newer_than | unix ms or ISO | no | - | - |
older_than | unix ms or ISO | no | - | - |
min_premium | int | no | 0 | >= 0 |
max_premium | int | no | - | - |
min_size | int | no | 0 | >= 0 |
max_size | int | no | - | - |
min_volume | int | no | 0 | >= 0 |
max_volume | int | no | - | - |
limit | int | no | 500 | 1 to 500 |
Note the limit ceiling here is 500 (vs 200 on the cross-ticker
feed). Per-ticker is the higher-volume endpoint.
6. MK3 use (L1 0DTE)
The SPY hunter consumes this endpoint as a context feature:
- Polling cadence: every 30s during RTH (rate-limit-bound).
Use
newer_thanto fetch only new prints since last poll. - De-dupe by
tracking_id(unique per print). - Derive aggressor side from
pricevsnbbo_bid/nbbo_ask. - Roll up to 1-min bars with: count, total_premium, aggressor-net premium, max single-print size.
- Feature for the Setup Hunter:
darkpool_dollar_volume_1m(notional in the last minute)darkpool_block_count_1m(count ofsize >= 10000)darkpool_aggressor_net_1m(signed premium)
Interaction with the contrarian-aggressor finding (2026-05-22-uw-historical-findings): unlike option flow, dark pool equity prints do not have the same contrarian-aggressor flip. Block-buyer-aggressive dark-pool prints in SPY have historically led intraday moves. Treat the sign of option flow and dark-pool flow differently.
7. Nautilus integration shape
- Custom data class:
UWDarkpoolPrint(one per print). - Polling Actor:
UWDarkpoolActorpolls/api/darkpool/SPYevery 30s withnewer_than. - Publishes each new print to the bus as
UWDarkpoolPrint. - A signal Actor rolls them into 1-min features and publishes those.
@customdataclass rules apply (nautilus-custom-data): ts_event
from executed_at, ts_init from receive time, numeric strings
coerced in __post_init__.
8. Known gaps / footguns
- No realtime push. Polling only. Lag is at most one poll interval (30s).
tracking_iduniqueness scope unclear - assumed unique-per-day but not documented. De-dupe with(tracking_id, executed_at)to be safe.canceled: trueprints still come through; filter them.market_center: "L"etc. are codes - cataloging which codes are which venue (ATS, TRF, etc.) is a future-fetch task.
9. Source URLs
https://api.unusualwhales.com/docs/operations/PublicApi.DarkpoolController.darkpool_recenthttps://api.unusualwhales.com/docs/operations/PublicApi.DarkpoolController.darkpool_ticker
cortana-north-star uw-api-gex-greeks uw-api-alerts 2026-05-22-uw-historical-findings 2026-05-15-mk3-setup-hunter-architecture