On Massive, a stock's official closing price is in the stock's trades, from /v3/trades, and finding it means matching the exchange as well as the condition. More than one exchange can report a condition 15 print for the same stock at the close, and only the one from the stock's listing exchange is the official close. Nasdaq, for example, documents that its Closing Cross sets the Nasdaq Official Closing Price (Nasdaq Opening and Closing Crosses FAQ).
Applies to
- Plans: /v3/trades is included in Stocks Developer (15-minute delayed), Stocks Advanced (real-time) and Stocks Business (end-of-day, or real-time with the Business expansion), and not in Stocks Basic or Stocks Starter, per the trades documentation. Daily bars and the Daily Ticker Summary are included in every Stocks plan.
- Endpoints: /v3/reference/tickers/{ticker}, /v3/reference/exchanges and /v3/trades/{stockTicker}; for comparison, /v2/aggs/ticker/{stocksTicker}/range/1/day/... and /v1/open-close/{stocksTicker}/{date}.
- Asset classes: US stocks and ETFs.
How to get the official closing price
- Read the stock's listing exchange from primary_exchange on /v3/reference/tickers/{ticker}. It is a Market Identifier Code (MIC), such as XNAS.
- Turn the MIC into the exchange id that trades carry, with /v3/reference/exchanges?asset_class=stocks, which returns each exchange's mic and id.
- Request the stock's trades from one minute before the close to 15 minutes after it, with order=asc&sort=timestamp. Without those two parameters /v3/trades returns the newest trades first. A page holds at most 50,000 trades, so follow next_url if the response has one.
- Keep the trade whose conditions include 15 and whose exchange is the listing exchange's id. Its price is the official closing price.
For NVDA, the listing exchange is Nasdaq:
curl -X GET "https://api.massive.com/v3/reference/tickers/NVDA?apiKey=YOUR_API_KEY"
Response
{
"results": {
"ticker": "NVDA",
"primary_exchange": "XNAS"
},
"status": "OK"
}
The exchanges endpoint maps XNAS to id 12:
curl -X GET "https://api.massive.com/v3/reference/exchanges?asset_class=stocks&apiKey=YOUR_API_KEY"
Response
{
"results": [
{
"id": 12,
"type": "exchange",
"name": "Nasdaq",
"mic": "XNAS"
}
],
"status": "OK"
}
The listing exchanges you will meet most often, from the same endpoint, are below. Look up any other MIC in the endpoint's response.
| primary_exchange (MIC) | Exchange | Exchange id on trades |
|---|---|---|
| XNYS | New York Stock Exchange | 10 |
| XNAS | Nasdaq | 12 |
| ARCX | NYSE Arca | 11 |
| BATS | Cboe BZX | 19 |
| XASE | NYSE American | 1 |
Then the trades around the close of 1 October 2026, from 15:59 to 16:15 ET:
curl -X GET "https://api.massive.com/v3/trades/NVDA?timestamp.gte=1790884740000000000×tamp.lt=1790885700000000000&order=asc&sort=timestamp&limit=50000&apiKey=YOUR_API_KEY"
Response, trimmed to the closing prints:
{
"results": [
{
"conditions": [15],
"exchange": 11,
"price": 231.03,
"sip_timestamp": 1790884800119225379,
"size": 300,
"decimal_size": "300.0"
},
{
"conditions": [8, 9, 41],
"exchange": 12,
"price": 230.86,
"sip_timestamp": 1790884800542415455,
"size": 1.1786181e+07,
"decimal_size": "11786181.0"
},
{
"conditions": [15],
"exchange": 12,
"price": 230.86,
"sip_timestamp": 1790884800542424374,
"size": 1.1786181e+07,
"decimal_size": "11786181.0"
}
],
"status": "OK"
}
NVDA's official close on 1 October 2026 is 230.86: the condition 15 row from exchange 12, Nasdaq. The three sip_timestamp values are nanoseconds since the Unix epoch and decode to 16:00:00.119, 16:00:00.542 and 16:00:00.542 ET. The first row is NYSE Arca's own condition 15 print at 231.03 for 300 shares, which is not NVDA's official close. A large size can come back in exponent form, as 1.1786181e+07 does here; decimal_size gives the same 11,786,181 shares as a plain string.
Why condition 15 alone does not identify the official close
Condition 15 alone does not identify a stock's official close, because the condition marks each exchange's own closing price for the stock. The conditions reference names it Market Center Official Close, and the stock trade conditions reference defines it as the closing value "as determined by a Market Center". Another exchange's condition 15 print may carry a different price, as NYSE Arca's does for NVDA above.
Other exchanges can also run closing crosses of their own, so a closing-auction condition does not identify the listing exchange either. SPY is listed on NYSE Arca, exchange 11, and on 1 October 2026 Nasdaq also reported a 100-share closing trade in it:
curl -X GET "https://api.massive.com/v3/trades/SPY?timestamp.gte=1790884740000000000×tamp.lt=1790885700000000000&order=asc&sort=timestamp&limit=50000&apiKey=YOUR_API_KEY"
Response, trimmed to the closing prints:
{
"results": [
{ "conditions": [8, 9, 41], "exchange": 12, "price": 764.04, "sip_timestamp": 1790884800181730862, "size": 100 },
{ "conditions": [15], "exchange": 12, "price": 764.04, "sip_timestamp": 1790884800181815022, "size": 100 },
{ "conditions": [8, 41], "exchange": 11, "price": 763.99, "sip_timestamp": 1790884800368816668, "size": 1.009525e+06 },
{ "conditions": [15], "exchange": 11, "price": 763.99, "sip_timestamp": 1790884800369042221, "size": 1.009525e+06 },
{ "conditions": [38, 41], "exchange": 11, "price": 763.99, "sip_timestamp": 1790885400000866465, "size": 0 },
{ "conditions": [15], "exchange": 11, "price": 763.99, "sip_timestamp": 1790885400000875507, "size": 1.009525e+06 }
],
"status": "OK"
}
SPY's official close that day is 763.99, from exchange 11. Nasdaq's pair at 764.04 is its own cross. The first four rows are at 16:00:00 ET and the last two at 16:10:00 ET.
The auction trade and the official close print
The closing auction on the listing exchange appears as two rows: a trade carrying condition 8 (Closing Prints), then a condition 15 print from the same exchange at the same price and size. They are one auction reported twice, and the conditions endpoint shows that only the condition 8 trade counts toward the consolidated volume:
curl -X GET "https://api.massive.com/v3/reference/conditions?asset_class=stocks&data_type=trade&limit=1000&apiKey=YOUR_API_KEY"
Response, trimmed to the codes on closing prints:
{
"results": [
{
"id": 8,
"name": "Closing Prints",
"update_rules": {
"consolidated": { "updates_high_low": true, "updates_open_close": true, "updates_volume": true }
}
},
{
"id": 15,
"name": "Market Center Official Close",
"update_rules": {
"consolidated": { "updates_high_low": false, "updates_open_close": false, "updates_volume": false }
}
},
{
"id": 37,
"name": "Odd Lot Trade",
"update_rules": {
"consolidated": { "updates_high_low": false, "updates_open_close": false, "updates_volume": true }
}
},
{
"id": 38,
"name": "Corrected Consolidated Close (per listing market)",
"update_rules": {
"consolidated": { "updates_high_low": true, "updates_open_close": true, "updates_volume": false }
}
}
],
"status": "OK"
}
If you add up closing volume yourself, count the auction's shares once, from the condition 8 trade, and not again from the condition 15 print.
Closing prints that arrive ten minutes later
For stocks listed on NYSE, NYSE Arca and Cboe BZX, the listing exchange sends two more prints about ten minutes after the close: a condition 38 (Corrected Consolidated Close) print with size 0, and a second condition 15 print with the same price and size as the first. The SPY response above shows the pair at 16:10:00 ET. Both prints carry the official closing price, and size 0 on the condition 38 print is expected. A filter that keeps every condition 15 print from the listing exchange therefore returns the official close twice, at the same price, so either row answers the question. Nasdaq-listed stocks such as NVDA do not get this pair.
On early-close days the market closes at 1:00 PM ET, so the closing prints arrive just after 1:00 PM and the later pair about ten minutes after that. Move the time window to match. The market holidays endpoint, /v1/marketstatus/upcoming, lists the coming early-close days with their close times.
When the daily bar's close differs from the official close
The daily bar's close, from /v2/aggs or the Daily Ticker Summary, is computed from trades under the consolidated update rules, and the Daily Ticker Summary documentation describes its close as "the close price for the symbol in the given time period", not as the official close. It usually equals the official close. It differs when the closing auction executes as an odd lot: the auction trade then carries condition 37 (Odd Lot Trade) as well as condition 8, condition 37 does not update the consolidated close, and the daily bar keeps the last trade that could.
PRHI, listed on Nasdaq, shows the difference on 16 July 2026:
curl -X GET "https://api.massive.com/v3/trades/PRHI?timestamp.gte=1784231940000000000×tamp.lt=1784232900000000000&order=asc&sort=timestamp&limit=50000&apiKey=YOUR_API_KEY"
Response, trimmed to the last regular trade and the closing prints:
{
"results": [
{ "exchange": 4, "price": 5.05, "sip_timestamp": 1784231994477714185, "size": 133, "trf_id": 202 },
{ "conditions": [15], "exchange": 11, "price": 5.05, "sip_timestamp": 1784232000076865996, "size": 133 },
{ "conditions": [8, 37, 41], "exchange": 12, "price": 5.28, "sip_timestamp": 1784232000137717133, "size": 78 },
{ "conditions": [15], "exchange": 12, "price": 5.28, "sip_timestamp": 1784232000137730248, "size": 78 }
],
"status": "OK"
}
The official close is 5.28, the Nasdaq closing cross of 78 shares at 16:00:00.137 ET, which carries condition 37. The first row, a 133-share trade at 5.05 reported through a trade reporting facility at 15:59:54.477 ET, has no conditions, so it is the last trade that could update the consolidated close. The daily bar keeps it:
curl -X GET "https://api.massive.com/v2/aggs/ticker/PRHI/range/1/day/2026-07-16/2026-07-16?adjusted=false&apiKey=YOUR_API_KEY"
Response
{
"ticker": "PRHI",
"adjusted": false,
"results": [
{ "c": 5.05, "t": 1784174400000 }
],
"status": "OK"
}
The bar's close is 5.05, not the official 5.28. t is 1784174400000, milliseconds since the Unix epoch, which is midnight ET at the start of 16 July 2026. The Daily Ticker Summary, /v1/open-close/PRHI/2026-07-16?adjusted=false, also returns a close of 5.05. When you need the official close, read it from the trades; when you need a close consistent with the rest of the bar, use the bar.
Why this happens
The official closing price comes from the listing exchange's closing auction, while each exchange that reports a closing price for a stock sends its own condition 15 print, and Massive publishes those prints as trades. The daily bar is a separate calculation: it applies the consolidated update rules to the session's trades, so it can differ from the official close when the auction trade is not allowed to set the consolidated close.
If you see an error
No condition 15 print from the listing exchange for a full trading session is worth reporting. Check first that the time window covers the close (1:00 PM ET on early-close days), that the request used order=asc&sort=timestamp, and that you followed next_url to the end. If the print is still missing, send the request and its request_id as described in How should I go about reporting a possible Massive data discrepancy?

