Intraday bars for a futures contract come from the Massive Futures API in two steps, because a futures product like Micro E-mini Nasdaq (MNQ) is not one ticker. Each product has a separate contract per expiration, so first find the contract ticker that was trading on the date you want, then ask for bars on that ticker. Every request and response below is real, taken from the session that settled on 4 September 2026.
Applies to
- Plans: any Futures subscription tier. See the pricing page for what each tier includes.
- Endpoints or feeds: /futures/v1/contracts, /futures/v1/aggs/{ticker}
- Asset classes: futures
How to get intraday bars for a futures contract
- Find the contract ticker. Pass the product code and the date you care about, so you get the contracts that were actually trading that day rather than expired ones.
curl -X GET "https://api.massive.com/futures/v1/contracts?product_code=MNQ&date=2026-09-04&type=single&limit=5&sort=ticker.asc&apiKey=YOUR_API_KEY"
Response
{
"results": [
{ "ticker": "MNQH7", "days_to_maturity": 192, "last_trade_date": "2027-03-19" },
{ "ticker": "MNQM7", "days_to_maturity": 282, "last_trade_date": "2027-06-17" },
{ "ticker": "MNQU6", "days_to_maturity": 10, "last_trade_date": "2026-09-18" },
{ "ticker": "MNQU7", "days_to_maturity": 374, "last_trade_date": "2027-09-17" },
{ "ticker": "MNQZ6", "days_to_maturity": 101, "last_trade_date": "2026-12-18" }
],
"status": "OK"
}
The list comes back ordered by ticker, not by expiry, so the front-month contract is not first. It is the one with the smallest days_to_maturity, which on this date is MNQU6 with 10 days left. type=single filters out combo contracts, which cover two expirations traded together and name both, as in MNQU6-MNQH7. On contracts dated before 12 March 2025 the type field is null, so that filter excludes them too.
- Ask for bars on that contract ticker. Set the bar size with resolution and the start of the range with window_start.gte.
curl -X GET "https://api.massive.com/futures/v1/aggs/MNQU6?resolution=1min&window_start.gte=2026-09-04&limit=3&sort=window_start.asc&apiKey=YOUR_API_KEY"
Response
{
"results": [
{
"ticker": "MNQU6",
"window_start": 1788480000000000000,
"session_end_date": "2026-09-04",
"open": 29503.75,
"high": 29507.5,
"low": 29491,
"close": 29505.5,
"volume": 2332,
"transactions": 1156,
"dollar_volume": 68796015
},
{
"window_start": 1788480060000000000,
"open": 29505.5,
"high": 29510.75,
"low": 29500.5,
"close": 29504.5,
"volume": 907
},
{
"window_start": 1788480120000000000,
"open": 29505.25,
"high": 29507.5,
"low": 29501.75,
"close": 29502.25,
"volume": 427
}
],
"next_url": "https://api.massive.com/futures/v1/aggs/MNQU6?cursor=...",
"status": "OK"
}
window_start is a Unix timestamp in nanoseconds, so the three bars above start at 2026-09-04 00:00, 00:01 and 00:02 UTC. Divide by 1,000,000,000 for seconds before you convert it. When the response carries a next_url, follow it for the next page rather than raising limit.
resolution is a number followed by a unit: sec, min, hour, day, session, week, month, quarter or year. Each unit stops one step short of the next unit that covers the same span, and asking for one step too many is where most 400 responses come from. These are the largest multipliers that work:
| Unit | Largest that works | Above that, use |
|---|---|---|
| sec | 59sec | 1min |
| min | 59min | 1hour |
| hour | 23hour | 1day |
| month | 11month | 1year |
| quarter | 3quarter | 1year |
So resolution=30min is fine and resolution=60min returns a 400. The day, session, week and year units accept every multiplier we have tried, so there is no boundary to watch there. For a futures contract 1day and 1session return the same bar, because the trading day is the session.
Why a session bar is dated the day before it settles
A futures session opens the evening before the date it settles on, so a session bar's window_start falls on the previous calendar day while its session_end_date is the date it settles. To load the session that settled on 4 September 2026, ask for window_start of 3 September.
window_start on a session bar is that start date at 00:00:00 UTC, not the moment the session opened. The bar below carries 1788393600000000000, which is 2026-09-03 00:00:00 UTC, while the CME open for that session was late on 3 September. Convert the timestamp expecting a midnight boundary rather than an evening one.
curl -X GET "https://api.massive.com/futures/v1/aggs/MNQU6?resolution=1session&window_start=2026-09-03&apiKey=YOUR_API_KEY"
Response
{
"results": [
{
"ticker": "MNQU6",
"window_start": 1788393600000000000,
"session_end_date": "2026-09-04",
"open": 29500,
"high": 29720,
"low": 29468.25,
"close": 29524.75,
"volume": 1961639,
"settlement_price": 29565.25
}
],
"status": "OK"
}
The bar starts at 2026-09-03 00:00 UTC and settles on 2026-09-04, which is why the two dates differ. Asking for that session by its settlement date returns nothing at all, because no session started that day:
curl -X GET "https://api.massive.com/futures/v1/aggs/MNQU6?resolution=1session&window_start=2026-09-04&apiKey=YOUR_API_KEY"
Response
{
"results": [],
"status": "OK"
}
Bars are built from the trades in each interval, so an interval with no trades has no bar at all rather than a bar of zeroes. Gaps in a thinly traded contract are expected.
If you see an error
{"status":"ERROR","error":"Invalid resolution: invalid resolution"} with HTTP 400 means the bar size is not one the API supports. 60min is the common case; use 1hour instead.
An empty results array with HTTP 200 means the query was valid and matched nothing. Check that the contract had not already expired on the date you asked for, and that you are asking for a session by its start date rather than its settlement date.
NOT_AUTHORIZED means the API key's plan does not include Futures. Futures is a separate subscription from Stocks, Options, Indices and Currencies.

