There is no universal source of truth for OHLC data, so Massive and another careful vendor can disagree and both be defensible. What makes a difference diagnosable rather than a matter of opinion is that only four things actually vary, and each one can be checked against the raw trades in a few minutes. Work through them in order.
Applies to
- Plans: every plan.
- Endpoints: the aggregates, trades and quotes endpoints, plus /v3/reference/conditions for eligibility and /stocks/v1/splits for adjustment.
- Asset classes: US stocks above all, where eligibility rules are richest.
The four causes, in the order to check them
Check them in this order, because the earlier ones explain more of the reports:
| Cause | Symptom | How to check |
|---|---|---|
| Trade eligibility | High or low differs, volume differs | Pull the trades for the window and look up their conditions |
| Timestamp choice | Values are right but land in the neighboring bar | Compare sip_timestamp against participant_timestamp bucketing |
| Split adjustment | Everything before one date is off by a constant ratio | Re-request with adjusted=false and compare |
| Late corrections | A bar you stored differs from the same bar today | Re-pull from REST, which holds the corrected version |
Work down the list rather than across it. Eligibility explains most reports, adjustment explains most of the rest, and the two together account for nearly everything.
How to check the first cause
Eligibility is the one to rule out first, and the conditions endpoint answers it as data rather than prose:
curl -X GET "https://api.massive.com/v3/reference/conditions?asset_class=stocks&data_type=trade&id=37&apiKey=YOUR_API_KEY"
Response
{
"results": [
{
"id": 37, "type": "sale_condition", "name": "Odd Lot Trade",
"update_rules": {
"consolidated": { "updates_high_low": false, "updates_open_close": false, "updates_volume": true }
}
}
],
"status": "OK"
}
An odd lot adds to volume and touches no price field, which is why a bar rebuilt from every trade has the right volume and the wrong high. Look up each condition on the trades that disagree before assuming the bar is wrong.
Why eligibility causes most of it
Eligibility causes most of it because not every trade updates every part of a bar. US stock trades carry sale conditions defined by the CTA and UTP plans, and those conditions say whether a trade may set the open or close, extend the high or low, or add to volume. Massive follows those rules. A vendor that includes every print, or applies the rules slightly differently, produces a different high, a different low and a different volume for the same minute, from the same underlying tape.
That is why a reconstruction from raw ticks usually disagrees with our bars until the condition rules are applied, and why comparing two vendors on volume is often the quickest way to see that eligibility is the cause.
What is not usually the cause
What is not usually the cause is coverage. Massive takes the full consolidated tape, so a missing trade is far less likely than a trade that was counted differently. And a delay is rarely it either, unless you are comparing a real-time feed with a delayed one, which is worth ruling out first if the two series are otherwise identical but offset in time.
If you see an error
A difference that is a constant ratio across a date is a split. Check /stocks/v1/splits.
A difference only in volume, with matching prices, is eligibility or size against decimal_size.
A difference that disappears when you re-pull is a correction that has since been applied.

