Most of the gaps people find in an aggregate series are minutes in which nothing eligible traded, and there is nothing to deliver for those: Massive emits no placeholder bar rather than an empty one. The check that separates a real gap from a quiet minute takes one request, and it is worth running before you report anything.
Applies to
- Plans: every plan.
- Endpoints: /v2/aggs/ticker/... for the bars and /v3/trades/{ticker} for the trades behind them.
- Asset classes: stocks above all, where sale conditions govern eligibility.
How to tell the two apart
- Pull the aggregate range with a limit high enough for the whole range, at least 1,000 for one day of minutes, and note which windows are absent.
- Pull /v3/trades for one of the absent windows.
- No trades at all means the market was genuinely quiet in that minute. That is not a gap in the data.
- Trades that exist but produced no bar means none of them was eligible. Look at each trade's conditions array, then ask the conditions endpoint what those codes update.
curl -X GET "https://api.massive.com/v3/reference/conditions?asset_class=stocks&data_type=trade&id=2&apiKey=YOUR_API_KEY"
Response
{
"results": [
{
"id": 2, "type": "sale_condition", "name": "Average Price Trade",
"update_rules": {
"consolidated": { "updates_high_low": false, "updates_open_close": false, "updates_volume": true }
}
}
],
"status": "OK"
}
Condition 2 updates volume but not price, so a minute containing only average-price trades gets no open, high, low or close and therefore no bar.
Where gaps concentrate
Gaps concentrate in four places, and two of them account for most reports:
| Pattern | Cause |
|---|---|
| Gaps throughout a thin ticker's day | Most minutes simply have no trade |
| Gaps concentrated in pre-market and after-hours | Extended-hours prints often carry conditions that do not update price |
| A whole day missing | A market holiday or an early close. Check /v1/marketstatus/upcoming |
| The end of a long range missing | The limit, which counts minutes scanned rather than bars returned |
Why no placeholder bar
There is no placeholder because a bar with no trades has no honest open, high, low or close to report. Carrying the previous close forward would invent a price that nobody traded at, and zeroes would corrupt any calculation that touched them. Leaving the window out means your code has to decide what a quiet minute means for it, which is the only place that decision can correctly be made.
If your charts need a continuous series, fill forward on your side, and keep the filled points distinguishable from real ones.
If you see an error
Bars missing from the end of a long request is the limit, not the data. Compare queryCount with the limit you set.
A minute with trades but no bar is eligibility. The conditions endpoint will name the reason.
A bar that appeared and then changed is a correction. Late trades revise a bar for about 15 minutes on the stream, and after that at the end of the day.

