Options open interest on Massive is the number of contracts held at the end of the last trading day, and the snapshot that returns it has no date parameter. Adding as_of or date to the request does not fail: the call succeeds and returns today's figure, which is easy to mistake for the past value you asked for. Once a contract expires, the snapshot stops returning it, so its open interest can only be recorded while it is still listed.
Applies to
- Plans: Options Starter, Developer and Advanced, which include the snapshots and list daily open interest, and Options Business. Options Basic includes neither.
- Endpoints: /v3/snapshot/options/{underlyingAsset} (the chain), /v3/snapshot/options/{underlyingAsset}/{optionContract} (one contract) and /v3/snapshot (the unified snapshot).
- Asset classes: US-listed options.
Where open interest appears
Open interest appears in three Massive endpoints, and all three are snapshots of the current state: the option chain snapshot, the option contract snapshot and the unified snapshot. Each one documents open_interest as "the quantity of this contract held at the end of the last trading day" and lists plan history as not applicable, as on the option chain snapshot page. The options endpoints and files that do go back in time carry no open interest field:
| Source | Open interest | Past dates |
|---|---|---|
| Option chain, contract and unified snapshots | Latest figure only | No |
| Daily bars, /v2/aggs/ticker/{optionsTicker}/range/1/day/{from}/{to} | No | Yes |
| Daily open and close, /v1/open-close/{optionsTicker}/{date} | No | Yes |
| Options day aggregates flat file | No | Yes |
Open interest is not available anywhere else in Massive's API either. Apart from those three snapshots, no page in the REST, WebSocket or flat-file documentation lists an open interest field, for any asset class, and the futures snapshot and futures bars return none.
How to build your own open interest history
An options open interest history has to be recorded going forward, one read per trading day:
- Once each trading day, in the afternoon or evening, request the chain snapshot for each underlying you track with limit=250, the largest page size, and follow next_url until the response has none.
- Save each contract's details.ticker and open_interest under the previous trading day's date, because the figure is the open interest at the end of that day, and keep the date and time you read them as well. The response does not say when the open interest figure was set, so your own timestamp is the only record of it.
- Keep the rows after a contract expires. The snapshot drops a contract once it expires, so your table becomes the only record of that contract's open interest.
curl -X GET "https://api.massive.com/v3/snapshot/options/SPY?expiration_date=2028-12-15&strike_price=800&apiKey=YOUR_API_KEY"
Response, trimmed:
{
"results": [
{
"details": {
"contract_type": "call",
"expiration_date": "2028-12-15",
"strike_price": 800,
"ticker": "O:SPY281215C00800000"
},
"open_interest": 4447
},
{
"details": {
"contract_type": "put",
"expiration_date": "2028-12-15",
"strike_price": 800,
"ticker": "O:SPY281215P00800000"
},
"open_interest": 329
}
],
"status": "OK"
}
The SPY call and put at the 800 strike for December 2028 each carry one open_interest figure, and no field says when that figure was set. A live call returns the current figures, which change from one trading day to the next.
When the daily open interest figure changes
The options open interest figure changes once per trading day. OPRA, the consolidated feed for US options, schedules its open interest messages for about 6:30 AM Eastern each trading day, as shown in the schedule of daily messages in the OPRA output specification. Through the afternoon and the evening, the figure on the snapshot stays the same, so one read during the afternoon or evening captures the day's value, and reading again later that day returns the same number.
Why this happens
Massive has no historical open interest because open interest is a once-a-day figure that the API serves only as the latest value on each listed contract's snapshot. OPRA sends it each morning as the volume of contracts that have not been exercised and have not yet reached expiration, rather than with every trade, so it is not part of the trades, quotes or bars that Massive keeps history for.
If you see an error
as_of=2026-06-01 or date=2026-06-01 on the options snapshot returns HTTP 200 with today's open interest, not the figure for that date. The snapshot ignores both parameters rather than refusing them, and as_of=notadate returns HTTP 200 as well. Fix: none is possible from the API; past figures exist only if you stored them.
"error": "Options contract not found." with HTTP 404 from /v3/snapshot/options/{underlyingAsset}/{optionContract} is what an expired contract returns. Fix: record contracts while they are listed; an expired contract's open interest is not available from Massive.
"results": [] with "status": "OK" from the chain snapshot, when expiration_date is a past date, means every contract in that expiration has expired.
"error": "NOT_FOUND" with "message": "Ticker not found." for one ticker in a /v3/snapshot response is what the unified snapshot returns for an expired contract.

