A REST aggregate bar and the same bar in a Massive minute or day aggregates flat file can disagree on volume as well as on price when the ticker is a stock that has split since the bar, because split adjustment rescales both. The default REST bar for ETHA at 10:00 AM ET on 1 October 2026 opens at 61.02 on about 15,293 shares, adjusted for the one-for-three reverse split ETHA executed on 6 October 2026 and for any later split, while the flat file row for that minute opens at 20.34 on about 45,879 shares. Options, indices, crypto, forex and futures bars are not rescaled for splits, so for those asset classes the comparison comes down to format, and for forex also to which quote sets the open and close.
Applies to
- Plans: Starter and above in the asset class you compare. The Basic plans include the REST aggregates endpoints but not the aggregates flat files; see the stocks, options, indices, crypto, forex and futures minute aggregates documentation.
- Endpoints and files: the custom bars endpoint /v2/aggs/ticker/{ticker}/range/{multiplier}/{timespan}/{from}/{to} for stocks, options, indices, crypto and forex, the stocks grouped daily endpoint /v2/aggs/grouped/locale/us/market/stocks/{date} and the futures aggregates endpoint /futures/v1/aggs/{ticker}, against the minute and day aggregates flat files (minute_aggs_v1, day_aggs_v1) and the futures minute and session aggregates files (minute_aggs_v1, session_aggs_v1).
- Asset classes: US stocks and ETFs, options, indices, crypto, forex and futures.
Split adjustment changes both price and volume
Split adjustment changes both the prices and the volume of a Massive REST stock bar, and the stock flat files never apply it. The custom bars and grouped daily endpoints return split-adjusted stock bars unless you pass adjusted=false. The stocks flat files overview states that all stock flat files contain unadjusted data, with prices and volumes not adjusted for splits, dividends or other corporate actions. So when a stock has split since the bar's date, the default REST bar and the flat file row show different prices and volumes, and requesting the REST bar with adjusted=false removes that difference.
Example: the ETHA bar at 10:00 AM ET on 1 October 2026
The ETHA minute bar at 10:00 AM ET on 1 October 2026 shows split adjustment at work, because ETHA executed a one-for-three reverse split five days later:
curl -X GET "https://api.massive.com/stocks/v1/splits?ticker=ETHA&execution_date=2026-10-06&apiKey=YOUR_API_KEY"
Response, trimmed:
{
"status": "OK",
"results": [
{ "execution_date": "2026-10-06", "split_from": 3.0, "split_to": 1.0, "ticker": "ETHA", "adjustment_type": "reverse_split" }
]
}
The default REST request returns the bar adjusted for every ETHA split since the bar, so these values change if ETHA splits again:
curl -X GET "https://api.massive.com/v2/aggs/ticker/ETHA/range/1/minute/1790863200000/1790863200000?apiKey=YOUR_API_KEY"
Response, trimmed:
{
"ticker": "ETHA",
"adjusted": true,
"results": [
{ "v": 15293.003453, "vw": 60.9264, "o": 61.02, "c": 60.87, "h": 61.05, "l": 60.87, "t": 1790863200000, "n": 131 }
],
"status": "OK"
}
The same request with adjusted=false returns the bar as traded:
curl -X GET "https://api.massive.com/v2/aggs/ticker/ETHA/range/1/minute/1790863200000/1790863200000?adjusted=false&apiKey=YOUR_API_KEY"
Response, trimmed:
{
"ticker": "ETHA",
"adjusted": false,
"results": [
{ "v": 45879.01036, "vw": 20.3088, "o": 20.34, "c": 20.29, "h": 20.35, "l": 20.29, "t": 1790863200000, "n": 131 }
],
"status": "OK"
}
The same bar in the minute aggregates flat file us_stocks_sip/minute_aggs_v1/2026/10/2026-10-01.csv.gz:
ticker,volume,open,close,high,low,window_start,transactions
ETHA,45879.010360,20.340000,20.290000,20.350000,20.290000,1790863200000000000,131
REST t 1790863200000 is in Unix milliseconds and the file's window_start 1790863200000000000 is in Unix nanoseconds; both are 10:00 AM ET (14:00 UTC) on 1 October 2026. The unadjusted REST bar and the file row agree on every price, the volume and the trade count. The default bar shows three times each price and a third of the volume, because ETHA now has a third as many shares.
Stock format differences that remain with adjusted=false
A Massive REST stock custom bar requested with adjusted=false still differs from the same stock flat file row in these format details:
| Difference | REST custom bars | Minute and day aggregates flat files |
|---|---|---|
| Price precision | Rounded to four decimal places | As many as six decimal places |
| Bar time | t, start of the bar in Unix milliseconds | window_start, start of the bar in Unix nanoseconds |
| Volume-weighted average price | vw | No VWAP column |
| Trade count column | n | transactions |
| Volume column | v | volume |
The custom bars documentation defines t as the Unix millisecond timestamp for the start of the aggregate window. The minute and day aggregates file documentation defines window_start as the Unix nanosecond timestamp for the start of the window, and lists no VWAP column.
The grouped daily endpoint differs from the day file in one more way. The grouped daily documentation defines its t as the end of the aggregate window, so a grouped daily t and the day file's window_start mark different instants. Match grouped daily rows to the day file on ticker and date, not on timestamp.
How the other asset classes compare
Massive's other asset classes compare with their flat files in fewer steps than stocks, because their REST bars are not rescaled for splits. This table lists what still differs for each; the sections after it show the evidence:
| Asset class | Split adjustment | Bar time, REST and file | Tickers in the file | Values | Columns on one side only |
|---|---|---|---|---|---|
| Options | None, even after the underlying splits | t in milliseconds, window_start in nanoseconds | Same as REST | Same prices | vw in REST |
| Indices | None, and no adjusted parameter | t in milliseconds, window_start in nanoseconds | Same as REST | The file can print floating-point digits, such as 7619.110000000001 for 7619.11 | None; neither side has volume, VWAP or a trade count |
| Crypto | None | t in milliseconds, window_start in nanoseconds | Hyphenated: X:BTC-USD for X:BTCUSD | Same prices; the file's volume can carry floating-point digits | vw in REST |
| Forex | None | t in milliseconds, window_start in nanoseconds | Hyphenated: C:EUR-USD for C:EURUSD | High and low the same; open and close can come from a different quote in the same second | vw in REST |
| Futures | None, and no adjusted parameter | window_start in nanoseconds on both sides | Same as REST | The file prints nine decimal places | exchange in the minute file |
Options bars keep their prices after a split
Options bars from Massive's REST API keep the prices they traded at after the underlying splits, so an options bar matches its flat file row without adjusted=false. The bar below is for an ETHA call option on 1 October 2026, before ETHA's one-for-three reverse split, and the default request returns it with "adjusted": true and the traded prices:
curl -X GET "https://api.massive.com/v2/aggs/ticker/O:ETHA270319C00021000/range/1/minute/1790862300000/1790862300000?apiKey=YOUR_API_KEY"
Response, trimmed:
{
"ticker": "O:ETHA270319C00021000",
"adjusted": true,
"results": [
{ "v": 5, "vw": 2.852, "o": 2.82, "c": 2.87, "h": 2.88, "l": 2.81, "t": 1790862300000, "n": 5 }
],
"status": "OK"
}
The same bar in the options minute aggregates flat file us_options_opra/minute_aggs_v1/2026/10/2026-10-01.csv.gz:
ticker,volume,open,close,high,low,window_start,transactions
O:ETHA270319C00021000,5,2.82,2.87,2.88,2.81,1790862300000000000,5
t 1790862300000 is 9:45 AM ET (13:45 UTC) on 1 October 2026, and every price, the volume and the trade count agree. After the split, the series is listed as an adjusted contract under its own symbol rather than at rescaled prices:
curl -X GET "https://api.massive.com/v3/reference/options/contracts/O:ETHA1270319C00021000?as_of=2026-10-07&apiKey=YOUR_API_KEY"
Response, trimmed:
{
"results": {
"correction": 1,
"expiration_date": "2027-03-19",
"shares_per_contract": 33,
"strike_price": 21,
"ticker": "O:ETHA1270319C00021000",
"underlying_ticker": "ETHA"
},
"status": "OK"
}
O:ETHA1270319C00021000 has the same strike and expiration as the contract above and delivers 33 shares per contract. How does Massive handle adjusted options contracts? explains how to recognize an adjusted series.
Crypto and forex tickers carry a hyphen in the flat files
Crypto and forex tickers carry a hyphen in Massive's flat files and none in REST responses, so X:BTCUSD in a REST request is X:BTC-USD in the crypto files, and C:EURUSD is C:EUR-USD in the forex files. The first BTC to USD minute of 1 October 2026 (UTC) shows the hyphen and one more difference:
curl -X GET "https://api.massive.com/v2/aggs/ticker/X:BTCUSD/range/1/minute/1790812800000/1790812800000?apiKey=YOUR_API_KEY"
Response, trimmed:
{
"ticker": "X:BTCUSD",
"adjusted": true,
"results": [
{ "v": 14.53277525, "vw": 83566.6652, "o": 83556.14, "c": 83514.01, "h": 83673, "l": 83514.01, "t": 1790812800000, "n": 1059 }
],
"status": "OK"
}
The same bar in the crypto minute aggregates flat file global_crypto/minute_aggs_v1/2026/10/2026-10-01.csv.gz:
ticker,volume,open,close,high,low,window_start,transactions
X:BTC-USD,14.53277524999998,83556.14,83514.01,83673.0,83514.01,1790812800000000000,1059
t 1790812800000 and window_start 1790812800000000000 are both midnight UTC on 1 October 2026 (8:00 PM ET on 30 September). The prices and the trade count agree. The file's volume of 14.53277524999998 is the REST volume of 14.53277525 with floating-point digits, so compare crypto volume with a tolerance rather than exactly. The forex example in the next section shows the hyphen in a forex file.
Forex open and close can come from different quotes
Forex open and close values from Massive's REST API and forex flat files can differ even when the high, low, volume and trade count agree. Several forex quotes can share one timestamp, so the first or last moment of a minute can hold more than one quote, and the REST bar and the file row can take the open or close from different quotes. The EUR to USD minute at 00:05 UTC on 1 October 2026 shows it:
curl -X GET "https://api.massive.com/v2/aggs/ticker/C:EURUSD/range/1/minute/1790813100000/1790813100000?apiKey=YOUR_API_KEY"
Response, trimmed:
{
"ticker": "C:EURUSD",
"adjusted": true,
"results": [
{ "v": 147, "vw": 1.1328, "o": 1.1328, "c": 1.1327, "h": 1.1329, "l": 1.1326, "t": 1790813100000, "n": 147 }
],
"status": "OK"
}
The same bar in the forex minute aggregates flat file global_forex/minute_aggs_v1/2026/10/2026-10-01.csv.gz:
ticker,volume,open,close,high,low,window_start,transactions
C:EUR-USD,147,1.13281,1.13285,1.1329,1.1326,1790813100000000000,147
The volume, the trade count, the high and the low agree; the open and the close do not. These are the quotes in the last second of that minute, 00:05:59 UTC:
curl -X GET "https://api.massive.com/v3/quotes/C:EURUSD?timestamp.gte=1790813159000000000×tamp.lt=1790813160000000000&order=asc&sort=timestamp&apiKey=YOUR_API_KEY"
Response, trimmed:
{
"results": [
{ "bid_price": 1.13285, "participant_timestamp": 1790813159000000000 },
{ "bid_price": 1.13281, "participant_timestamp": 1790813159000000000 },
{ "bid_price": 1.1327, "participant_timestamp": 1790813159000000000 }
],
"status": "OK"
}
All three quotes carry the same nanosecond timestamp. The REST close of 1.1327 is the bid of the third quote and the file's close of 1.13285 is the bid of the first, so both are prices from the last second of the minute.
Index values can carry floating-point digits in the flat files
Index values in Massive's indices flat files can carry floating-point digits that the REST response does not show. The S&P 500 index (I:SPX) bar at 11:10 AM ET on 1 October 2026:
curl -X GET "https://api.massive.com/v2/aggs/ticker/I:SPX/range/1/minute/1790867400000/1790867400000?apiKey=YOUR_API_KEY"
Response, trimmed:
{
"ticker": "I:SPX",
"results": [
{ "o": 7621.34, "c": 7619.11, "h": 7621.34, "l": 7617.79, "t": 1790867400000 }
],
"status": "OK"
}
The same bar in the indices minute aggregates flat file us_indices/minute_aggs_v1/2026/10/2026-10-01.csv.gz:
ticker,open,close,high,low,window_start
I:SPX,7621.34,7619.110000000001,7621.34,7617.79,1790867400000000000
The file's close of 7619.110000000001 is the REST close of 7619.11. Index bars have no volume, VWAP or trade count on either side, and the indices custom bars documentation lists no adjusted parameter.
Futures bars use the same fields as the futures files
Futures bars from Massive's futures aggregates endpoint use the same field names as the futures minute and session aggregates flat files, including window_start in Unix nanoseconds, so a futures bar needs no timestamp conversion. The futures aggregates documentation lists ticker, session_end_date, window_start, open, high, low, close, volume, dollar_volume and transactions, adds settlement_price to session bars, has no adjusted parameter, and shows window_start as a nanosecond value in its sample response. The futures minute aggregates file documentation lists the same columns plus exchange, the futures session aggregates file documentation lists them plus settlement_price, and the sample rows of both print prices with nine decimal places, such as 1759.000000000. Neither side has a VWAP field; the futures aggregates documentation explains how to compute one from dollar_volume and volume.
How to compare a REST bar with a flat file row
- For stocks, request the REST bars with adjusted=false. The other asset classes need no adjustment setting.
- Multiply a custom bars t by 1,000,000 to get the file's window_start. Futures bars carry window_start in nanoseconds on both sides. For the stocks grouped daily endpoint, match on ticker and date instead.
- For crypto and forex, remove the hyphen from the file's ticker, so X:BTC-USD becomes X:BTCUSD.
- For stock custom bars, treat prices as equal when they differ by no more than 0.00005, the most that rounding to four decimal places can move a price. For the other asset classes, treat values as equal when they differ by less than one part in a billion, which absorbs floating-point digits such as 7619.110000000001.
- Compare the trade count exactly wherever both sides have one. Compare volume exactly for stocks, options, forex and futures, and with the tolerance in step 4 for crypto, whose file volume can carry floating-point digits.
- For forex, do not treat a different open or close as an error when the first or last second of the minute holds more than one quote. The forex quotes endpoint /v3/quotes/{fxTicker} shows the quotes in that second.
- Leave vw out, because no aggregates flat file has a VWAP column.
For ETHA on 1 October 2026, the stock custom bars request below returns 708 unadjusted minute bars, and the minute file has 708 ETHA rows for the same minutes, with the same volume and trade count and every price within 0.00005. The 11:45 AM ET bar shows the rounding:
curl -X GET "https://api.massive.com/v2/aggs/ticker/ETHA/range/1/minute/2026-10-01/2026-10-01?adjusted=false&sort=asc&limit=50000&apiKey=YOUR_API_KEY"
Response, trimmed to the 11:45 AM ET bar:
{
"ticker": "ETHA",
"resultsCount": 708,
"adjusted": false,
"results": [
{ "v": 33595.576896, "vw": 20.1809, "o": 20.1728, "c": 20.1801, "h": 20.185, "l": 20.17, "t": 1790869500000, "n": 51 }
],
"status": "OK"
}
The minute file's row for the same bar:
ticker,volume,open,close,high,low,window_start,transactions
ETHA,33595.576896,20.172848,20.180100,20.185000,20.170000,1790869500000000000,51
t 1790869500000 is 11:45 AM ET (15:45 UTC) on 1 October 2026. The file's open of 20.172848 is 20.1728 in REST; the volume, the trade count and the other three prices are the same.
Why this happens
Massive's REST bars and flat file bars differ for stocks because an adjusted REST stock bar is computed against the share count on the day you request it, so it changes every time the company splits again. The stocks flat files overview says each day's stock files are generated after the full session closes at 8:00 PM ET, are available by about 11:00 AM ET the following day, and contain unadjusted data, so a stock flat file keeps the prices and volumes as they traded. Forex open and close values differ for a different reason: when several quotes share the first or last timestamp of a minute, a bar has more than one candidate quote for its open or close.
If you see an error
A difference between a Massive REST bar and a flat file row that remains after these steps is worth reporting: a volume or trade count that differs, a high or low outside the tolerance for its asset class, or an open or close outside that tolerance for any asset class but forex. Start a chat at massive.com/contact with the REST request URL, its request_id, the flat file's full key and the row that differs. How should I go about reporting a possible Massive data discrepancy? has a template to fill in.
Related
- Is Massive's stock data adjusted for splits or dividends?
- Does Massive support normal and reverse splits?
- How does Massive handle adjusted options contracts?
- What asset classes are available through Massive's Currencies Subscription?
- How do I get started with Flat Files and S3 on Massive?
- What timezone are Massive's timestamps in?
- Why am I receiving a late aggregate bar through Massive's WebSockets?
- How should I go about reporting a possible Massive data discrepancy?

