Yes, with one qualification worth understanding. Massive publishes every off-exchange print, which is where dark pool executions appear, on the ordinary trades feed. There is no separate dark pool endpoint: you identify these trades by their exchange ID of 4, which marks a trade reported through a Trade Reporting Facility rather than executed on a lit exchange.
Applies to
- Plans: a Stocks subscription. The history depth follows your tier.
- Endpoints: /v3/trades/{ticker} for history and the T channel on the /stocks WebSocket cluster for live prints.
- Asset classes: US stocks and ETFs.
How to identify an off-exchange print
Pull trades and keep the rows where exchange is 4:
curl -X GET "https://api.massive.com/v3/trades/AAPL?timestamp=2026-09-04&limit=1000&apiKey=YOUR_API_KEY"
Response
{
"results": [
{
"conditions": [12],
"exchange": 4,
"price": 320.01,
"size": 370,
"sip_timestamp": 1788566398110367271,
"trf_id": 202,
"trf_timestamp": 1788566398110341815
}
],
"status": "OK"
}
Exchange 4 on its own is sufficient. In a 1,000-row sample of AAPL prints, 674 rows carried exchange 4 and every one of them also carried a trf_id, while every row with a trf_id had exchange 4, so testing both fields adds nothing. Off-exchange volume is a large share of the tape: those 674 rows were 67 percent of the sample.
What trf_id tells you, and what it does not
trf_id tells you which Trade Reporting Facility received the report, not the venue where the trade happened. The values in that sample were 201 and 202, the FINRA NYSE and FINRA Nasdaq facilities, which is why it cannot distinguish one dark pool from another: dozens of venues report through the same facility. trf_timestamp is when that facility received the report, which is why it can sit slightly before or after the SIP timestamp.
If you need per-venue attribution, that is not in the consolidated tape at all. FINRA publishes weekly volume by ATS separately, and it is aggregated rather than trade by trade.
Why off-exchange prints arrive late
Off-exchange prints arrive later than lit ones because they are reported rather than matched on an exchange. FINRA requires a trade to be reported as soon as practicable and within 10 seconds during reporting-facility hours, and executions outside those hours are reported when the facility next opens. Ten seconds is long enough, at market speed, for a print to land after the bar it belongs to was published, which is what makes aggregate bars get corrected.
Two consequences worth designing for. A live consumer that counts off-exchange volume during the session will undercount it and catch up later. And a bar you built live can differ from the same bar pulled from REST the next day.
If you see an error
No rows with exchange 4 in a short window is normal for a thinly traded ticker, not a data gap. Widen the window.
A trf_id you do not recognize is still a valid facility id. Do not filter on specific values; filter on exchange being 4.

