Docs Options Endpoints Open Interest Change Open Interest Change Overview Open Interest Change returns a paginated, sortable, projectable table of per-contract daily open-interest delta records for a single trading session. Each row carries previous OI, current OI, the signed delta, and the fractional percent change.
POST /v1/options/tool/open-interest-change Copycurl -X POST https://api.quantdata.us/v1/options/tool/open-interest-change \
-H "Authorization: Bearer <YOUR_API_KEY>" \
-H "Content-Type: application/json" \
-d '{
"sessionDate": "2026-05-13",
"filter": { "tickers": ["AAPL"] }
}' Which AAPL contracts had the biggest OI build-ups today?
Find every SPY contract where OI grew by more than 10,000 today.
Show me the largest percent OI swings on NVDA from yesterday.
Selecting the session sessionDate is optional and selects the trading session to evaluate. If omitted, the most recent session is used. timeRange, snapshotTime, and aggregationPeriod are not accepted on this endpoint.
Open-interest data lags the session start, so before the market opens on any given day, the latest available session is yesterday's session. Pass sessionDate explicitly when you want a specific date.
Open Interest Change uses cursor pagination. size sets the page size (default 50, range 1-100). sort picks the order (default createdTime DESCENDING). Pass the previous response's nextSearchAfter back as searchAfter to get the next page. See Pagination for the full walk-through.
Subsequent page · cursor + explicit sort
Request · size + sort + searchAfter Copy{
"sessionDate" : "2026-05-13" ,
"filter" : { "tickers" : [ "AAPL" ] } ,
"size" : 50 ,
"sort" : { "field" : "changeInOpenInterest" , "direction" : "DESCENDING" } ,
"searchAfter" : [ "18000" , "5f4c2e9a" ]
} sort.field accepts any filterable field on the row; direction is ASCENDING or DESCENDING. When the result set is empty or the final page has been served, nextSearchAfter is omitted from the response.
Projection includes is a whitelist of fields to keep on each row; excludes is a blacklist. The two are mutually exclusive. Omitted fields are dropped from the JSON entirely. See Projection for the full contract.
Projectable fields: CHANGE_IN_OPEN_INTEREST, CONTRACT_TYPE, CREATED_TIME, CURRENT_OPEN_INTEREST, EXPIRATION_DATE, ID, PERCENT_CHANGE_IN_OPEN_INTEREST, PREVIOUS_OPEN_INTEREST, SESSION_DATE, STRIKE_PRICE, TICKER.
Includes · keep just the columns you need
{
"sessionDate" : "2026-05-13" ,
"filter" : { "tickers" : [ "AAPL" ] } ,
"includes" : [ "TICKER" , "STRIKE_PRICE" , "EXPIRATION_DATE" , "CHANGE_IN_OPEN_INTEREST" , "PERCENT_CHANGE_IN_OPEN_INTEREST" ]
} Response shape data is an ordered array of rows. nextSearchAfter is the cursor for the next page (or omitted when none).
200 OK · application/json Copy{
"data" : [
{
"id" : "5f4c2e9a" ,
"ticker" : "AAPL" ,
"contractType" : "CALL" ,
"strikePrice" : 220.0 ,
"expirationDate" : "2026-05-16" ,
"previousOpenInterest" : 12040 ,
"currentOpenInterest" : 30142 ,
"changeInOpenInterest" : 18102 ,
"percentChangeInOpenInterest" : 1.5036 ,
"sessionDate" : "2026-05-13" ,
"createdTime" : 1747137612000
}
] ,
"nextSearchAfter" : [ "18102" , "5f4c2e9a" ]
} Per-row fields (every field is nullable when trimmed by projection):
Identity : id (string), ticker (string), contractType (CALL / PUT), strikePrice (double, dollars), expirationDate (LocalDate).Open interest : previousOpenInterest (integer, contracts), currentOpenInterest (integer, contracts), changeInOpenInterest (integer, signed contracts), percentChangeInOpenInterest (double, fractional: 0.05 = 5%).Time : sessionDate (LocalDate), createdTime (epoch-millisecond Long).The endpoint throws ValidationFailure when the request is malformed.
Filters Convenience filter fields cover the row inventory and let you narrow without writing a filter expression. All are optional and inside filter.
tickers (list of string, OR-combined).contractTypes (set of CALL / PUT).strikePrices (list of double, dollars) or strikePriceRange (min /max in dollars). Mutually exclusive.expirationDates (list of LocalDate) or expirationDateRange (startDate / endDate). Mutually exclusive.previousOpenInterestRange, currentOpenInterestRange, changeInOpenInterestRange (min / max integers, contracts).percentChangeInOpenInterestRange (min / max double, fractional: 0.05 = 5%).The filterExpression DSL is also accepted and can be combined with filter; both are evaluated as AND.
Range filters · positive deltas of at least 5%
Request · range filters Copy{
"sessionDate" : "2026-05-13" ,
"filter" : {
"tickers" : [ "AAPL" , "NVDA" ] ,
"contractTypes" : [ "CALL" ] ,
"expirationDateRange" : { "startDate" : "2026-05-16" , "endDate" : "2026-06-20" } ,
"changeInOpenInterestRange" : { "min" : 5000 , "max" : null } ,
"percentChangeInOpenInterestRange" : { "min" : 0.05 , "max" : null }
}
} See Field Reference for the type and allowed values of every filterable field, and Filter Expression for the full DSL grammar.
Where to go next Field Reference
Every filterable field, grouped by surface, with aliases and value ranges.
Filter Expression
Boolean composition with AND, OR, and nested terminals.
Pagination
Cursor walk, sort defaults, and snapshot stability across pages.
Projection
Trim per-row fields with includes / excludes.
Conventions
Field-name normalization, alias rules, time-range and aggregation-period defaults.
Errors
RFC 9457 problem shape and every error category with example responses.
Rate Limiting
Per-user quota, response headers, and how to back off cleanly.
Browse Endpoints
Browse every options and equities endpoint, grouped by surface.
Quickstart
Quickstart: send your first authenticated request end-to-end.