The 09:30 open falls in the middle of the 09:00 bar on the Massive aggregates endpoint, and no parameter changes that. Windows are anchored to the start of the day rather than to the session, and the from and to parameters snap outward to whole windows so no bar is ever partial. A session figure therefore has to be built from minute bars, and the multiplier trick that looks like it should work does not.
Applies to
- Plans: every plan.
- Endpoints: /v2/aggs/ticker/{ticker}/range/{multiplier}/{timespan}/{from}/{to}.
- Asset classes: stocks above all, where the session boundaries matter most.
Where each window starts
Windows are anchored to a grid, and the grid starts at the beginning of the day:
| Timespan | A window begins at |
|---|---|
| Minute | The top of the minute |
| Hour | The top of the hour |
| Day | Midnight Eastern |
| Week | Sunday at midnight Eastern |
| Month | The first day of the month |
| Quarter | The first day of the quarter |
A multiplier does not change the anchor, it changes the step. Asking for 330-minute bars gives you windows at 00:00, 05:30, 11:00 and 16:30 Eastern, stepping 5.5 hours from midnight, and none of them lines up with the 04:00 to 09:30 premarket session.
How to get a session figure
Because there is no session parameter, aggregate the minutes yourself:
- Request 1-minute bars for the session window you want, with a limit of at least 1,000 so nothing is cut off. Premarket is 04:00 to 09:30 Eastern, regular hours 09:30 to 16:00, after-hours 16:00 to 20:00.
- Take the open from the first bar, the close from the last, the high and low as the extremes, and the volume as the sum.
- Convert the boundaries with a time-zone database rather than a fixed offset, or the two weeks around each daylight saving change will be wrong.
curl -X GET "https://api.massive.com/v2/aggs/ticker/AAPL/range/1/minute/2026-09-04/2026-09-04?limit=5000&apiKey=YOUR_API_KEY"
Response
{ "ticker": "AAPL", "queryCount": 885, "resultsCount": 885, "status": "OK" }
Those 885 bars cover a 960-minute extended session, because a minute with no eligible trade produces no bar. Do not assume a fixed number of bars per session.
What snapping does to your range
Snapping widens the range rather than narrowing it. Ask for hour bars from 09:45 and the from snaps back to 09:00; ask to 10:15 and it snaps forward to 11:00. You therefore get whole bars that may extend outside the range you named, which is deliberate: a partial hour bar would understate its volume and misplace its open.
If you see an error
An hour bar whose open is not the 09:30 opening price is correct. The 09:00 bar starts at 09:00, so its open is the first premarket-eligible trade of that hour.
An empty result on a large multiplier is usually the limit, not the anchor. A 330-minute request needs a limit of at least 330 before a window can complete.
A day that returns 16 hour bars rather than 7 is the extended session, 04:00 to 20:00 Eastern, which is 08:00 to 23:00 UTC.

