Extended-hours data on Massive has two traps, and neither is coverage. There is no parameter that selects a trading session, so you separate pre-market, regular and after-hours with timestamps. And aggregate bars are far sparser outside regular hours than the trade count suggests, because a minute whose only trades are odd lots has no bar.
Applies to
- Plans: any Stocks subscription. The tier decides how recent the data can be, not whether extended hours are included.
- Endpoints: /v3/trades, /v3/quotes, /v2/aggs/... and the flat files; the T, Q, A and AM WebSocket channels.
- Asset classes: US stocks and ETFs.
The session boundaries
The session boundaries are conventions of the US equities market rather than Massive settings. All times Eastern:
| Session | Runs |
|---|---|
| Pre-market | 04:00 to 09:30 |
| Regular hours | 09:30 to 16:00 |
| After-hours | 16:00 to 20:00 |
How to select one session
Pass timestamps rather than dates. The from and to parameters accept a millisecond or nanosecond epoch value as well as a date, and that is the only way to bound a request to part of a day:
curl -X GET "https://api.massive.com/v2/aggs/ticker/AAPL/range/1/minute/1788508800000/1788528599999?limit=5000&apiKey=YOUR_API_KEY"
Response
{ "ticker": "AAPL", "queryCount": 282, "resultsCount": 282, "status": "OK" }
Those two values are 04:00:00 and 09:29:59.999 Eastern on 2026-09-04, and the bars run from 04:00 to 09:29 with a total volume of 538,708.38. The count is 282 rather than 330 because 48 of the premarket minutes held no eligible trade.
The end bound matters more than it looks. Both from and to are inclusive, so ending at 09:30 pulls in the opening minute of the regular session, which on that day carried 547,599 of the volume by itself, more than the whole pre-market before it. Stop one millisecond short.
Do not try to get a single premarket bar by setting the multiplier to 330. Windows are anchored to the start of the day, so a 330-minute grid runs 00:00, 05:30, 11:00 and 16:30 Eastern and never matches the session. Aggregate the minute bars yourself instead.
Why extended-hours bars are sparse
Extended-hours bars are sparse because eligibility, not coverage, decides whether a trade updates a bar. Many extended-hours prints are odd lots, which add to a bar's volume and trade count but cannot set its open, high, low or close, so a minute that holds only odd-lot trades has no bar at all, and a bar that exists can carry volume its own high and low do not reflect.
So if you need the real extended-hours picture, work from /v3/trades. If bars are enough, expect gaps and do not treat them as missing data.
If you see an error
No bars in the premarket for a thin ticker is normal. Check /v3/trades for the same window before reporting it.
A bar whose volume looks inconsistent with its price range is a condition that updates volume but not price. The conditions endpoint will tell you which one.
An empty result for a timestamp range is often the limit, because it counts minutes scanned rather than bars returned.
Related
- Does Massive have market data outside of normal trading hours?
- How does Massive treat hourly bars when querying regular trading hours?
- How does Massive create aggregate bars?
- What do Massive's stock trade condition codes mean?
- Does a Form T trade update a pre-market minute bar's high, low, open and close?

