---
title: "Day-over-day OI changes"
method: GET
path: "/options-flow/oi-changes"
tags: ["Derived Analytics"]
---

# Day-over-day OI changes

`GET /options-flow/oi-changes`

## Request

- Base URL: `https://optionsbell.com/api/v1`
- URL: `https://optionsbell.com/api/v1/options-flow/oi-changes`
- Auth: API key in header `X-API-Key`

Open-interest change per symbol between the requested day (default:
latest) and the symbol's most recent earlier day with unusual flow
within the previous 30 days (`prev_date` names it; not necessarily
the previous session), at the total / call / put level. Ordered by
`|oi_change_pct|` descending, then `symbol`.

A symbol is absent when it has no such prior observation, when
`prev_oi` is below `min_prev_oi`, or when it had no unusual flow on
the day. A zero change is present as a row with `oi_change: 0` (only
`side=gainers|losers` drop it), so "missing prior data" and "no
change" are distinguishable.

## Query parameters

- `date` string, date
- `symbols` string
- `side` 'gainers' | 'losers' | 'all'
- `min_change_pct` number
- `min_prev_oi` number
- `limit` integer
- `offset` integer

## Response `200`

OI change rows

- object
  - `date` string, date, nullable, required
  - `side` 'gainers' | 'losers' | 'all', required
  - `min_prev_oi` number, required
  - `count` integer, required
  - `limit` integer, required
  - `offset` integer, required
  - `filtered_total` integer, required: Rows matching the filters across all pages (0 when the page is past the end).
  - `has_more` boolean, required
  - `data` OiChangeRow[], required
    - `symbol` string
    - `sector` string, nullable
    - `industry` string, nullable
    - `date` string, date
    - `prev_date` string, date, nullable
    - `total_oi` string: Numeric string.
    - `prev_oi` string, nullable: Numeric string.
    - `oi_change` string, nullable: Numeric string.
    - `oi_change_pct` number, nullable: Fraction (0.5 = +50%); null when prev_oi is 0 or missing.
    - `call_oi` string: Numeric string.
    - `prev_call_oi` string, nullable: Numeric string.
    - `call_oi_change` string, nullable: Numeric string.
    - `put_oi` string: Numeric string.
    - `prev_put_oi` string, nullable: Numeric string.
    - `put_oi_change` string, nullable: Numeric string.

## Other responses

- `400`: Invalid input: `INVALID_DATE`, `INVALID_PARAM`, `INVALID_SYMBOLS`.
- `401`: Missing or invalid API key: `MISSING_API_KEY`, `INVALID_API_KEY_FORMAT`, `INVALID_API_KEY`. No rate-limit headers.
- `403`: Key is valid but has no usable subscription: `NO_ACTIVE_SUBSCRIPTION` (no Personal plan on the key) or `SUBSCRIPTION_INACTIVE` (past due, paused, expired, or canceled past its period end). No rate-limit headers.
- `429`: Rate limit exceeded: `RATE_LIMIT_MINUTE` (60/min) or `RATE_LIMIT_DAY` (4,000/day). Carries both rate-limit header sets and `Retry-After` (seconds until the exhausted window opens again). Rejected requests count against the minute window, so back off instead of retrying immediately.
- `500`: Unexpected server error: `INTERNAL_ERROR`. The body and the X-Request-Id header carry the request id.
- `503`: Authentication backend unreachable: `AUTH_UNAVAILABLE`. Retry later. No rate-limit headers.

---

[API](https://skmtc.dev/optionsbell/apis/optionsbell-options-flow-api.md) · [All operations](https://skmtc.dev/optionsbell/apis/optionsbell-options-flow-api/llms.txt) · [OpenAPI document](https://skmtc.dev/optionsbell/apis/optionsbell-options-flow-api/revisions/42db9bcaa61f?raw)
