{"openapi":"3.0.3","info":{"title":"OptionsBell Options Flow API","description":"Unusual options activity and analytics derived from it for 7,000+\nUS-listed stocks - the same dataset that powers OptionsBell email alerts.\nThe current trading day is rescanned every 5 minutes during the regular\nsession; past days are immutable and queryable by date.\n\n## Authentication\n\nGenerate an API key at [Settings](https://optionsbell.com/settings) and\nsend it as the `X-API-Key` header (keys start with `sms_`). There is one\nplan, **Personal**; an active subscription is required. A canceled\nsubscription keeps working until the end of its paid period.\n\n## Rate limits\n\n30 requests per minute and 2,000 requests per day per API key, enforced\ndurably across deployments. Every authenticated response (200, 400, 429)\ncarries `X-RateLimit-Limit`, `X-RateLimit-Remaining`, `X-RateLimit-Reset`\n(minute window) plus `X-RateLimit-Daily-Limit` and\n`X-RateLimit-Daily-Remaining` (day window). Responses rejected before\nauthentication completes (401, 403, 503) carry no rate-limit headers.\nEvery response carries an `X-Request-Id` header.\n\n## Errors\n\nErrors are JSON `{ \"error\": \"<message>\", \"code\": \"<CODE>\" }`; a 500 adds\n`requestId`. Validation failures answer 400 with one of `INVALID_DATE`,\n`INVALID_DATE_RANGE`, `INVALID_SINCE`, `INVALID_PARAM`, `INVALID_SYMBOLS`\nor `INVALID_SYMBOL` - each endpoint lists the codes it can return.\n\n## Value types\n\nPostgres integers arrive as JSON numbers; BIGINT and NUMERIC columns\narrive as **numeric strings** (`\"1234\"`, `\"25.43\"`) to preserve precision;\nFLOAT8 columns as numbers; text arrays as string arrays. Dates are\n`YYYY-MM-DD`; `first_seen_at` / `last_seen_at` are ISO-8601 timestamps in\nUTC. Implied volatility (`volatility`, `*_iv`) is in percent. Empty\nresults keep the same envelope shape with `count: 0`.\n\n## License\n\nOne subscription is bound to one named person. You may use the output for\nyour own professional or business decisions, but you may not share your\nAPI key, connector URL, data or output with anyone - not even colleagues\nin the same company; every person needs their own subscription. Output\nmust not be redistributed or embedded in products, bots, dashboards,\nreports or channels for others. Stored responses must be deleted within\n30 days. Full terms: https://optionsbell.com/terms#api-license\n","version":"1.2.0","termsOfService":"https://optionsbell.com/terms","contact":{"name":"OptionsBell Support","email":"contact@optionsbell.com","url":"https://optionsbell.com"},"license":{"name":"Proprietary - OptionsBell API license","url":"https://optionsbell.com/terms#api-license"}},"servers":[{"url":"https://optionsbell.com/api/v1","description":"Production"}],"security":[{"ApiKeyAuth":[]}],"tags":[{"name":"Health","description":"Liveness and readiness probes - public, no auth."},{"name":"Unusual Activity","description":"Contract-level unusual options activity."},{"name":"Derived Analytics","description":"Analytics derived from the unusual-activity dataset - sentiment, IV rank, OI changes, sectors, market regime, history, streaks, expiry."},{"name":"Meta","description":"Dataset coverage and discovery."}],"paths":{"/ping":{"get":{"tags":["Health"],"summary":"Liveness probe","description":"Public. No auth, no database. Returns the server time.","security":[],"responses":{"200":{"description":"OK","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PingResponse"}}}},"500":{"$ref":"#/components/responses/InternalError"}}}},"/health":{"get":{"tags":["Health"],"summary":"Readiness probe","description":"Public. Runs a trivial database query and reports its latency. Answers 503 `DB_UNHEALTHY` when the database is unreachable.","security":[],"responses":{"200":{"description":"Service and database healthy","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HealthResponse"}}}},"500":{"$ref":"#/components/responses/InternalError"},"503":{"description":"Database unreachable (`DB_UNHEALTHY`).","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":"Database unreachable.","code":"DB_UNHEALTHY"}}}}}}},"/options-flow/stats":{"get":{"tags":["Meta"],"summary":"Dataset coverage stats","description":"Available date ranges, contract counts, symbol counts and sector\ncoverage. Lets clients and agents discover what is queryable before\nthey query it. `rescan_cadence_minutes` is the intraday refresh\ninterval of the current day (5).\n","responses":{"200":{"description":"Coverage summary","headers":{"X-RateLimit-Limit":{"$ref":"#/components/headers/X-RateLimit-Limit"},"X-RateLimit-Remaining":{"$ref":"#/components/headers/X-RateLimit-Remaining"},"X-RateLimit-Reset":{"$ref":"#/components/headers/X-RateLimit-Reset"},"X-RateLimit-Daily-Limit":{"$ref":"#/components/headers/X-RateLimit-Daily-Limit"},"X-RateLimit-Daily-Remaining":{"$ref":"#/components/headers/X-RateLimit-Daily-Remaining"},"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/StatsResponse"}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/InternalError"},"503":{"$ref":"#/components/responses/AuthUnavailable"}}}},"/options-flow/unusual":{"get":{"tags":["Unusual Activity"],"summary":"Unusual options activity scan","description":"Contract-level unusual options activity across the covered universe.\nDefaults to the latest scan day. Filter by symbols, side and every\nnumeric threshold.\n\n**Ordering and paging.** Rows are ranked by score =\n`volume_oi_ratio * ln(premium_estimate + 1)` descending, then\n`data_date, symbol, option_symbol` ascending, so `limit` + `offset`\npaging is deterministic. The envelope reports `filtered_total` (rows\nmatching the filters across all pages) and `has_more`. Row identity\nis `(data_date, symbol, option_symbol)`.\n\n**Freshness.** The current day is upserted every 5 minutes during the\nregular session (rows added or updated, never removed); past days are\nimmutable. `since` selects contracts whose `last_seen_at` is at or\nafter the timestamp - a polling window, not a monotonic cursor. On\nthis endpoint `since` combines with the day scope (latest day unless\n`date` / `date_from` / `date_to` is set), so poll with a few minutes of\noverlap and de-duplicate on the row identity.\n\n**Base floor.** Unless `raw=1`, rows must satisfy Vol/OI >= 1.5,\nopen interest >= 100 and premium >= $25,000.\n","parameters":[{"$ref":"#/components/parameters/date"},{"$ref":"#/components/parameters/date_from"},{"$ref":"#/components/parameters/date_to"},{"$ref":"#/components/parameters/since"},{"$ref":"#/components/parameters/symbols"},{"$ref":"#/components/parameters/type"},{"$ref":"#/components/parameters/min_voloi"},{"$ref":"#/components/parameters/min_premium"},{"$ref":"#/components/parameters/min_iv"},{"$ref":"#/components/parameters/max_dte"},{"$ref":"#/components/parameters/min_volume"},{"$ref":"#/components/parameters/min_oi"},{"$ref":"#/components/parameters/raw"},{"name":"limit","in":"query","description":"Max rows per page. Floats are floored; out-of-range values are clamped.","schema":{"type":"integer","minimum":1,"maximum":1000,"default":300}},{"$ref":"#/components/parameters/offset"}],"responses":{"200":{"description":"Ranked unusual contracts","headers":{"X-RateLimit-Limit":{"$ref":"#/components/headers/X-RateLimit-Limit"},"X-RateLimit-Remaining":{"$ref":"#/components/headers/X-RateLimit-Remaining"},"X-RateLimit-Reset":{"$ref":"#/components/headers/X-RateLimit-Reset"},"X-RateLimit-Daily-Limit":{"$ref":"#/components/headers/X-RateLimit-Daily-Limit"},"X-RateLimit-Daily-Remaining":{"$ref":"#/components/headers/X-RateLimit-Daily-Remaining"},"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"type":"object","required":["date","date_from","date_to","since","count","limit","offset","filtered_total","has_more","sort","data"],"properties":{"date":{"type":"string","format":"date","nullable":true,"description":"Resolved scan day; null in range mode or when the dataset is empty."},"date_from":{"type":"string","format":"date","nullable":true},"date_to":{"type":"string","format":"date","nullable":true},"since":{"type":"string","format":"date-time","nullable":true,"description":"Echo of the since filter (ISO-8601, UTC)."},"count":{"type":"integer","description":"Rows in this response"},"limit":{"type":"integer"},"offset":{"type":"integer"},"filtered_total":{"type":"integer","description":"Rows matching the filters across all pages (0 when the page is past the end)."},"has_more":{"type":"boolean"},"sort":{"type":"string","enum":["score_desc,symbol,option_symbol"]},"data":{"type":"array","items":{"$ref":"#/components/schemas/UnusualContract"}}}}}}},"400":{"description":"Invalid input: `INVALID_DATE`, `INVALID_DATE_RANGE`, `INVALID_SINCE`, `INVALID_PARAM`, `INVALID_SYMBOLS`.","headers":{"X-RateLimit-Limit":{"$ref":"#/components/headers/X-RateLimit-Limit"},"X-RateLimit-Remaining":{"$ref":"#/components/headers/X-RateLimit-Remaining"},"X-RateLimit-Reset":{"$ref":"#/components/headers/X-RateLimit-Reset"},"X-RateLimit-Daily-Limit":{"$ref":"#/components/headers/X-RateLimit-Daily-Limit"},"X-RateLimit-Daily-Remaining":{"$ref":"#/components/headers/X-RateLimit-Daily-Remaining"},"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/InternalError"},"503":{"$ref":"#/components/responses/AuthUnavailable"}}}},"/options-flow/{symbol}":{"get":{"tags":["Unusual Activity"],"summary":"Per-symbol unusual activity","description":"Every contract on a single ticker that passed the unusual filter,\nranked by score (`volume_oi_ratio * ln(premium_estimate + 1)`\ndescending, then `data_date, symbol, option_symbol`). Same filters,\npaging and freshness rules as `/options-flow/unusual`; `symbols` is\nignored here.\n\nDefault scope is the latest scan day that has data for this symbol.\n`date`, `date_from` / `date_to` take precedence. Unlike `/unusual`,\n`since` on its own is not combined with a day scope - it selects\nmatching rows across all days.\n","parameters":[{"$ref":"#/components/parameters/symbolPath"},{"$ref":"#/components/parameters/date"},{"$ref":"#/components/parameters/date_from"},{"$ref":"#/components/parameters/date_to"},{"$ref":"#/components/parameters/since"},{"$ref":"#/components/parameters/type"},{"$ref":"#/components/parameters/min_voloi"},{"$ref":"#/components/parameters/min_premium"},{"$ref":"#/components/parameters/min_iv"},{"$ref":"#/components/parameters/max_dte"},{"$ref":"#/components/parameters/min_volume"},{"$ref":"#/components/parameters/min_oi"},{"$ref":"#/components/parameters/raw"},{"name":"limit","in":"query","description":"Max rows per page. Floats are floored; out-of-range values are clamped.","schema":{"type":"integer","minimum":1,"maximum":500,"default":100}},{"$ref":"#/components/parameters/offset"}],"responses":{"200":{"description":"Contracts for the symbol","headers":{"X-RateLimit-Limit":{"$ref":"#/components/headers/X-RateLimit-Limit"},"X-RateLimit-Remaining":{"$ref":"#/components/headers/X-RateLimit-Remaining"},"X-RateLimit-Reset":{"$ref":"#/components/headers/X-RateLimit-Reset"},"X-RateLimit-Daily-Limit":{"$ref":"#/components/headers/X-RateLimit-Daily-Limit"},"X-RateLimit-Daily-Remaining":{"$ref":"#/components/headers/X-RateLimit-Daily-Remaining"},"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"type":"object","required":["symbol","date","date_from","date_to","since","count","limit","offset","filtered_total","has_more","sort","data"],"properties":{"symbol":{"type":"string","example":"AAPL"},"date":{"type":"string","format":"date","nullable":true,"description":"Resolved scan day; null in range / since mode or when the symbol has no data."},"date_from":{"type":"string","format":"date","nullable":true},"date_to":{"type":"string","format":"date","nullable":true},"since":{"type":"string","format":"date-time","nullable":true},"count":{"type":"integer"},"limit":{"type":"integer"},"offset":{"type":"integer"},"filtered_total":{"type":"integer"},"has_more":{"type":"boolean"},"sort":{"type":"string","enum":["score_desc,symbol,option_symbol"]},"data":{"type":"array","items":{"$ref":"#/components/schemas/UnusualContract"}}}}}}},"400":{"description":"Invalid input: `INVALID_SYMBOL`, `INVALID_DATE`, `INVALID_DATE_RANGE`, `INVALID_SINCE`, `INVALID_PARAM`.","headers":{"X-RateLimit-Limit":{"$ref":"#/components/headers/X-RateLimit-Limit"},"X-RateLimit-Remaining":{"$ref":"#/components/headers/X-RateLimit-Remaining"},"X-RateLimit-Reset":{"$ref":"#/components/headers/X-RateLimit-Reset"},"X-RateLimit-Daily-Limit":{"$ref":"#/components/headers/X-RateLimit-Daily-Limit"},"X-RateLimit-Daily-Remaining":{"$ref":"#/components/headers/X-RateLimit-Daily-Remaining"},"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/InternalError"},"503":{"$ref":"#/components/responses/AuthUnavailable"}}}},"/options-flow/top":{"get":{"tags":["Unusual Activity"],"summary":"Top prints of the day","description":"The day's biggest bets, ranked by `premium_estimate` descending\n(`rank` is the 1-based position) - the view that also powers the\nalert emails. A thin, ranked cut over the same contract-level data as\n`/options-flow/unusual`, without the base floor: only `min_premium`\napplies.\n","parameters":[{"$ref":"#/components/parameters/date"},{"$ref":"#/components/parameters/type"},{"$ref":"#/components/parameters/symbols"},{"name":"min_premium","in":"query","description":"Minimum estimated premium in USD. Negative values are clamped to 0.","schema":{"type":"number","minimum":0,"default":25000}},{"name":"limit","in":"query","schema":{"type":"integer","minimum":1,"maximum":100,"default":20}}],"responses":{"200":{"description":"Ranked top prints","headers":{"X-RateLimit-Limit":{"$ref":"#/components/headers/X-RateLimit-Limit"},"X-RateLimit-Remaining":{"$ref":"#/components/headers/X-RateLimit-Remaining"},"X-RateLimit-Reset":{"$ref":"#/components/headers/X-RateLimit-Reset"},"X-RateLimit-Daily-Limit":{"$ref":"#/components/headers/X-RateLimit-Daily-Limit"},"X-RateLimit-Daily-Remaining":{"$ref":"#/components/headers/X-RateLimit-Daily-Remaining"},"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"type":"object","required":["date","type","min_premium","count","data"],"properties":{"date":{"type":"string","format":"date","nullable":true},"type":{"type":"string","enum":["call","put","all"],"description":"Normalized side filter."},"min_premium":{"type":"number"},"count":{"type":"integer"},"data":{"type":"array","items":{"$ref":"#/components/schemas/TopPrint"}}}}}}},"400":{"description":"Invalid input: `INVALID_DATE`, `INVALID_PARAM`, `INVALID_SYMBOLS`.","headers":{"X-RateLimit-Limit":{"$ref":"#/components/headers/X-RateLimit-Limit"},"X-RateLimit-Remaining":{"$ref":"#/components/headers/X-RateLimit-Remaining"},"X-RateLimit-Reset":{"$ref":"#/components/headers/X-RateLimit-Reset"},"X-RateLimit-Daily-Limit":{"$ref":"#/components/headers/X-RateLimit-Daily-Limit"},"X-RateLimit-Daily-Remaining":{"$ref":"#/components/headers/X-RateLimit-Daily-Remaining"},"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/InternalError"},"503":{"$ref":"#/components/responses/AuthUnavailable"}}}},"/options-flow/market":{"get":{"tags":["Derived Analytics"],"summary":"Market breadth and regime","description":"Breadth of unusual flow per trading day, newest first: `breadth_score`\n0-100 (share of classified symbols reading bullish; null only when no\nsymbol was classified that day), aggregate call/put volume ratio,\nregime label (`bullish` / `bearish` / `mixed`) and bullish/bearish\nsymbol counts. Without `date` / range the envelope's `date` is the\nlatest available day and `data` holds the newest `limit` days.\n","parameters":[{"$ref":"#/components/parameters/date"},{"$ref":"#/components/parameters/date_from"},{"$ref":"#/components/parameters/date_to"},{"name":"limit","in":"query","schema":{"type":"integer","minimum":1,"maximum":365,"default":30}}],"responses":{"200":{"description":"Daily market rows","headers":{"X-RateLimit-Limit":{"$ref":"#/components/headers/X-RateLimit-Limit"},"X-RateLimit-Remaining":{"$ref":"#/components/headers/X-RateLimit-Remaining"},"X-RateLimit-Reset":{"$ref":"#/components/headers/X-RateLimit-Reset"},"X-RateLimit-Daily-Limit":{"$ref":"#/components/headers/X-RateLimit-Daily-Limit"},"X-RateLimit-Daily-Remaining":{"$ref":"#/components/headers/X-RateLimit-Daily-Remaining"},"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"type":"object","required":["date","date_from","date_to","count","data"],"properties":{"date":{"type":"string","format":"date","nullable":true},"date_from":{"type":"string","format":"date","nullable":true},"date_to":{"type":"string","format":"date","nullable":true},"count":{"type":"integer"},"data":{"type":"array","items":{"$ref":"#/components/schemas/MarketRow"}}}}}}},"400":{"description":"Invalid input: `INVALID_DATE`, `INVALID_DATE_RANGE`, `INVALID_PARAM`.","headers":{"X-RateLimit-Limit":{"$ref":"#/components/headers/X-RateLimit-Limit"},"X-RateLimit-Remaining":{"$ref":"#/components/headers/X-RateLimit-Remaining"},"X-RateLimit-Reset":{"$ref":"#/components/headers/X-RateLimit-Reset"},"X-RateLimit-Daily-Limit":{"$ref":"#/components/headers/X-RateLimit-Daily-Limit"},"X-RateLimit-Daily-Remaining":{"$ref":"#/components/headers/X-RateLimit-Daily-Remaining"},"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/InternalError"},"503":{"$ref":"#/components/responses/AuthUnavailable"}}}},"/options-flow/sentiment":{"get":{"tags":["Derived Analytics"],"summary":"Daily unusual-flow sentiment","description":"Per-symbol sentiment of the day's unusual flow - call/put volumes,\npremium, open interest, net delta, C/P ratios, average IV per side,\nplus bullish/bearish classification with `strength_score` 0-9 and the\nscreener confirmations behind it. Defaults to the latest scan day;\nwith a range each `(symbol, date)` pair is a row. Ordered by total\npremium (call + put) descending.\n","parameters":[{"$ref":"#/components/parameters/date"},{"$ref":"#/components/parameters/date_from"},{"$ref":"#/components/parameters/date_to"},{"$ref":"#/components/parameters/symbols"},{"name":"sector","in":"query","description":"GICS sector name, exact match (e.g. `Information Technology`).","schema":{"type":"string"}},{"name":"side","in":"query","description":"Only rows classified with this signal side.","schema":{"type":"string","enum":["bullish","bearish"]}},{"name":"signal_only","in":"query","description":"`1` or `true`: only rows with an active bullish/bearish signal. Implied by `side`.","schema":{"type":"boolean"}},{"name":"min_strength","in":"query","description":"Minimum `strength_score`. Floored and clamped to 0-9.","schema":{"type":"integer","minimum":0,"maximum":9}},{"name":"min_premium","in":"query","description":"Minimum call + put total premium in USD. Negative values are clamped to 0.","schema":{"type":"number","minimum":0}},{"name":"limit","in":"query","schema":{"type":"integer","minimum":1,"maximum":500,"default":100}}],"responses":{"200":{"description":"Sentiment rows","headers":{"X-RateLimit-Limit":{"$ref":"#/components/headers/X-RateLimit-Limit"},"X-RateLimit-Remaining":{"$ref":"#/components/headers/X-RateLimit-Remaining"},"X-RateLimit-Reset":{"$ref":"#/components/headers/X-RateLimit-Reset"},"X-RateLimit-Daily-Limit":{"$ref":"#/components/headers/X-RateLimit-Daily-Limit"},"X-RateLimit-Daily-Remaining":{"$ref":"#/components/headers/X-RateLimit-Daily-Remaining"},"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"type":"object","required":["date","date_from","date_to","count","data"],"properties":{"date":{"type":"string","format":"date","nullable":true},"date_from":{"type":"string","format":"date","nullable":true},"date_to":{"type":"string","format":"date","nullable":true},"count":{"type":"integer"},"data":{"type":"array","items":{"$ref":"#/components/schemas/SentimentRow"}}}}}}},"400":{"description":"Invalid input: `INVALID_DATE`, `INVALID_DATE_RANGE`, `INVALID_PARAM`, `INVALID_SYMBOLS`.","headers":{"X-RateLimit-Limit":{"$ref":"#/components/headers/X-RateLimit-Limit"},"X-RateLimit-Remaining":{"$ref":"#/components/headers/X-RateLimit-Remaining"},"X-RateLimit-Reset":{"$ref":"#/components/headers/X-RateLimit-Reset"},"X-RateLimit-Daily-Limit":{"$ref":"#/components/headers/X-RateLimit-Daily-Limit"},"X-RateLimit-Daily-Remaining":{"$ref":"#/components/headers/X-RateLimit-Daily-Remaining"},"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/InternalError"},"503":{"$ref":"#/components/responses/AuthUnavailable"}}}},"/options-flow/sentiment/{symbol}":{"get":{"tags":["Derived Analytics"],"summary":"Per-symbol sentiment series","description":"One symbol's unusual-flow sentiment per trading day, newest first.\nDefaults to the most recent 30 days; bound the window with\n`date_from` / `date_to`. `date` in the envelope is the newest day\nreturned (null when the symbol has no data).\n","parameters":[{"$ref":"#/components/parameters/symbolPath"},{"$ref":"#/components/parameters/date_from"},{"$ref":"#/components/parameters/date_to"},{"name":"limit","in":"query","schema":{"type":"integer","minimum":1,"maximum":250,"default":30}}],"responses":{"200":{"description":"Sentiment series","headers":{"X-RateLimit-Limit":{"$ref":"#/components/headers/X-RateLimit-Limit"},"X-RateLimit-Remaining":{"$ref":"#/components/headers/X-RateLimit-Remaining"},"X-RateLimit-Reset":{"$ref":"#/components/headers/X-RateLimit-Reset"},"X-RateLimit-Daily-Limit":{"$ref":"#/components/headers/X-RateLimit-Daily-Limit"},"X-RateLimit-Daily-Remaining":{"$ref":"#/components/headers/X-RateLimit-Daily-Remaining"},"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"type":"object","required":["symbol","date","date_from","date_to","count","data"],"properties":{"symbol":{"type":"string"},"date":{"type":"string","format":"date","nullable":true,"description":"Newest day returned."},"date_from":{"type":"string","format":"date","nullable":true},"date_to":{"type":"string","format":"date","nullable":true},"count":{"type":"integer"},"data":{"type":"array","items":{"$ref":"#/components/schemas/SentimentSeriesRow"}}}}}}},"400":{"description":"Invalid input: `INVALID_SYMBOL`, `INVALID_DATE`, `INVALID_DATE_RANGE`, `INVALID_PARAM`.","headers":{"X-RateLimit-Limit":{"$ref":"#/components/headers/X-RateLimit-Limit"},"X-RateLimit-Remaining":{"$ref":"#/components/headers/X-RateLimit-Remaining"},"X-RateLimit-Reset":{"$ref":"#/components/headers/X-RateLimit-Reset"},"X-RateLimit-Daily-Limit":{"$ref":"#/components/headers/X-RateLimit-Daily-Limit"},"X-RateLimit-Daily-Remaining":{"$ref":"#/components/headers/X-RateLimit-Daily-Remaining"},"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/InternalError"},"503":{"$ref":"#/components/responses/AuthUnavailable"}}}},"/options-flow/oi-changes":{"get":{"tags":["Derived Analytics"],"summary":"Day-over-day OI changes","description":"Open-interest change per symbol between the requested day (default:\nlatest) and the prior trading day with data, at the total / call /\nput level. Ordered by `|oi_change_pct|` descending. Symbols without a\nprior observation are excluded.\n","parameters":[{"$ref":"#/components/parameters/date"},{"$ref":"#/components/parameters/symbols"},{"name":"side","in":"query","description":"`gainers`: positive total OI change only; `losers`: negative only.","schema":{"type":"string","enum":["gainers","losers","all"],"default":"all"}},{"name":"min_change_pct","in":"query","description":"Minimum absolute day-over-day change as a fraction (0.5 = 50%). Negative values are clamped to 0.","schema":{"type":"number","minimum":0}},{"name":"min_prev_oi","in":"query","description":"Minimum prior-day total OI, filters low-base noise. Negative values are clamped to 0.","schema":{"type":"number","minimum":0,"default":1000}},{"name":"limit","in":"query","schema":{"type":"integer","minimum":1,"maximum":500,"default":100}}],"responses":{"200":{"description":"OI change rows","headers":{"X-RateLimit-Limit":{"$ref":"#/components/headers/X-RateLimit-Limit"},"X-RateLimit-Remaining":{"$ref":"#/components/headers/X-RateLimit-Remaining"},"X-RateLimit-Reset":{"$ref":"#/components/headers/X-RateLimit-Reset"},"X-RateLimit-Daily-Limit":{"$ref":"#/components/headers/X-RateLimit-Daily-Limit"},"X-RateLimit-Daily-Remaining":{"$ref":"#/components/headers/X-RateLimit-Daily-Remaining"},"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"type":"object","required":["date","side","min_prev_oi","count","data"],"properties":{"date":{"type":"string","format":"date","nullable":true},"side":{"type":"string","enum":["gainers","losers","all"]},"min_prev_oi":{"type":"number"},"count":{"type":"integer"},"data":{"type":"array","items":{"$ref":"#/components/schemas/OiChangeRow"}}}}}}},"400":{"description":"Invalid input: `INVALID_DATE`, `INVALID_PARAM`, `INVALID_SYMBOLS`.","headers":{"X-RateLimit-Limit":{"$ref":"#/components/headers/X-RateLimit-Limit"},"X-RateLimit-Remaining":{"$ref":"#/components/headers/X-RateLimit-Remaining"},"X-RateLimit-Reset":{"$ref":"#/components/headers/X-RateLimit-Reset"},"X-RateLimit-Daily-Limit":{"$ref":"#/components/headers/X-RateLimit-Daily-Limit"},"X-RateLimit-Daily-Remaining":{"$ref":"#/components/headers/X-RateLimit-Daily-Remaining"},"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/InternalError"},"503":{"$ref":"#/components/responses/AuthUnavailable"}}}},"/options-flow/oi-changes/{symbol}":{"get":{"tags":["Derived Analytics"],"summary":"Per-symbol OI change series","description":"One symbol's total / call / put open interest per trading day with\nthe change versus the previous day with data, newest first. The\noldest row in the window has no predecessor, so its `prev_*` and\n`*_change` fields are null. `date` in the envelope is the newest day\nreturned.\n","parameters":[{"$ref":"#/components/parameters/symbolPath"},{"$ref":"#/components/parameters/date_from"},{"$ref":"#/components/parameters/date_to"},{"name":"limit","in":"query","schema":{"type":"integer","minimum":1,"maximum":500,"default":60}}],"responses":{"200":{"description":"OI change series","headers":{"X-RateLimit-Limit":{"$ref":"#/components/headers/X-RateLimit-Limit"},"X-RateLimit-Remaining":{"$ref":"#/components/headers/X-RateLimit-Remaining"},"X-RateLimit-Reset":{"$ref":"#/components/headers/X-RateLimit-Reset"},"X-RateLimit-Daily-Limit":{"$ref":"#/components/headers/X-RateLimit-Daily-Limit"},"X-RateLimit-Daily-Remaining":{"$ref":"#/components/headers/X-RateLimit-Daily-Remaining"},"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"type":"object","required":["symbol","date","date_from","date_to","count","data"],"properties":{"symbol":{"type":"string"},"date":{"type":"string","format":"date","nullable":true},"date_from":{"type":"string","format":"date","nullable":true},"date_to":{"type":"string","format":"date","nullable":true},"count":{"type":"integer"},"data":{"type":"array","items":{"$ref":"#/components/schemas/OiChangeSeriesRow"}}}}}}},"400":{"description":"Invalid input: `INVALID_SYMBOL`, `INVALID_DATE`, `INVALID_DATE_RANGE`, `INVALID_PARAM`.","headers":{"X-RateLimit-Limit":{"$ref":"#/components/headers/X-RateLimit-Limit"},"X-RateLimit-Remaining":{"$ref":"#/components/headers/X-RateLimit-Remaining"},"X-RateLimit-Reset":{"$ref":"#/components/headers/X-RateLimit-Reset"},"X-RateLimit-Daily-Limit":{"$ref":"#/components/headers/X-RateLimit-Daily-Limit"},"X-RateLimit-Daily-Remaining":{"$ref":"#/components/headers/X-RateLimit-Daily-Remaining"},"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/InternalError"},"503":{"$ref":"#/components/responses/AuthUnavailable"}}}},"/options-flow/sectors":{"get":{"tags":["Derived Analytics"],"summary":"Sector unusual-flow rollup","description":"The day's unusual-flow premium, volume, average net delta and\nbullish/bearish symbol counts per GICS sector, ordered by total\npremium descending. Symbols without a sector are grouped as\n`Unclassified`.\n","parameters":[{"$ref":"#/components/parameters/date"},{"name":"limit","in":"query","schema":{"type":"integer","minimum":1,"maximum":50,"default":11}}],"responses":{"200":{"description":"Sector rows","headers":{"X-RateLimit-Limit":{"$ref":"#/components/headers/X-RateLimit-Limit"},"X-RateLimit-Remaining":{"$ref":"#/components/headers/X-RateLimit-Remaining"},"X-RateLimit-Reset":{"$ref":"#/components/headers/X-RateLimit-Reset"},"X-RateLimit-Daily-Limit":{"$ref":"#/components/headers/X-RateLimit-Daily-Limit"},"X-RateLimit-Daily-Remaining":{"$ref":"#/components/headers/X-RateLimit-Daily-Remaining"},"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"type":"object","required":["date","count","data"],"properties":{"date":{"type":"string","format":"date","nullable":true},"count":{"type":"integer"},"data":{"type":"array","items":{"$ref":"#/components/schemas/SectorRow"}}}}}}},"400":{"description":"Invalid input: `INVALID_DATE`, `INVALID_PARAM`.","headers":{"X-RateLimit-Limit":{"$ref":"#/components/headers/X-RateLimit-Limit"},"X-RateLimit-Remaining":{"$ref":"#/components/headers/X-RateLimit-Remaining"},"X-RateLimit-Reset":{"$ref":"#/components/headers/X-RateLimit-Reset"},"X-RateLimit-Daily-Limit":{"$ref":"#/components/headers/X-RateLimit-Daily-Limit"},"X-RateLimit-Daily-Remaining":{"$ref":"#/components/headers/X-RateLimit-Daily-Remaining"},"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/InternalError"},"503":{"$ref":"#/components/responses/AuthUnavailable"}}}},"/options-flow/iv-rank":{"get":{"tags":["Derived Analytics"],"summary":"IV rank snapshot","description":"IV rank and IV percentile per symbol as of the latest available day,\ncomputed from each symbol's history of daily average IV (percent).\n\n- `*_iv_rank` = `(current - min) / (max - min)` over the window, 0..1;\n  null when max equals min.\n- `*_iv_percentile` = share of sessions with lower IV, 0..1.\n- `side` picks the rank used for `min_rank` / `max_rank`, for\n  ordering and for the `iv_rank` field: `call`, `put`, or `both`\n  (default) = `GREATEST(call_iv_rank, put_iv_rank)`.\n- Default lookback is the full available history; `lookback_days`\n  restricts it. Symbols with fewer than 20 sessions are excluded.\n\nOrdered by `iv_rank` descending, then symbol.\n","parameters":[{"$ref":"#/components/parameters/symbols"},{"name":"side","in":"query","schema":{"type":"string","enum":["call","put","both"],"default":"both"}},{"name":"min_rank","in":"query","description":"Clamped to 0..1.","schema":{"type":"number","minimum":0,"maximum":1}},{"name":"max_rank","in":"query","description":"Clamped to 0..1.","schema":{"type":"number","minimum":0,"maximum":1}},{"name":"lookback_days","in":"query","description":"Calendar days of history to rank against. Default is the full available history.","schema":{"type":"integer","minimum":1,"maximum":3650}},{"name":"limit","in":"query","schema":{"type":"integer","minimum":1,"maximum":500,"default":100}}],"responses":{"200":{"description":"IV rank rows","headers":{"X-RateLimit-Limit":{"$ref":"#/components/headers/X-RateLimit-Limit"},"X-RateLimit-Remaining":{"$ref":"#/components/headers/X-RateLimit-Remaining"},"X-RateLimit-Reset":{"$ref":"#/components/headers/X-RateLimit-Reset"},"X-RateLimit-Daily-Limit":{"$ref":"#/components/headers/X-RateLimit-Daily-Limit"},"X-RateLimit-Daily-Remaining":{"$ref":"#/components/headers/X-RateLimit-Daily-Remaining"},"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"type":"object","required":["date","side","lookback_days","count","data"],"properties":{"date":{"type":"string","format":"date","nullable":true},"side":{"type":"string","enum":["call","put","both"]},"lookback_days":{"type":"integer","nullable":true,"description":"Echo of the parameter; null = full history."},"count":{"type":"integer"},"data":{"type":"array","items":{"$ref":"#/components/schemas/IvRankRow"}}}}}}},"400":{"description":"Invalid input: `INVALID_PARAM`, `INVALID_SYMBOLS`.","headers":{"X-RateLimit-Limit":{"$ref":"#/components/headers/X-RateLimit-Limit"},"X-RateLimit-Remaining":{"$ref":"#/components/headers/X-RateLimit-Remaining"},"X-RateLimit-Reset":{"$ref":"#/components/headers/X-RateLimit-Reset"},"X-RateLimit-Daily-Limit":{"$ref":"#/components/headers/X-RateLimit-Daily-Limit"},"X-RateLimit-Daily-Remaining":{"$ref":"#/components/headers/X-RateLimit-Daily-Remaining"},"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/InternalError"},"503":{"$ref":"#/components/responses/AuthUnavailable"}}}},"/options-flow/iv-rank/{symbol}":{"get":{"tags":["Derived Analytics"],"summary":"Per-symbol IV rank series","description":"One row per trading day, newest first, each carrying that day's call\nand put average IV (percent) with its rank and percentile against the\nsymbol's full available history (or the last `lookback_days`).\n`date` in the envelope is the newest day returned.\n","parameters":[{"$ref":"#/components/parameters/symbolPath"},{"name":"lookback_days","in":"query","description":"Calendar days of history, counted back from the symbol's latest day. Default is the full history.","schema":{"type":"integer","minimum":1,"maximum":3650}},{"name":"limit","in":"query","schema":{"type":"integer","minimum":1,"maximum":500,"default":60}}],"responses":{"200":{"description":"IV rank time series","headers":{"X-RateLimit-Limit":{"$ref":"#/components/headers/X-RateLimit-Limit"},"X-RateLimit-Remaining":{"$ref":"#/components/headers/X-RateLimit-Remaining"},"X-RateLimit-Reset":{"$ref":"#/components/headers/X-RateLimit-Reset"},"X-RateLimit-Daily-Limit":{"$ref":"#/components/headers/X-RateLimit-Daily-Limit"},"X-RateLimit-Daily-Remaining":{"$ref":"#/components/headers/X-RateLimit-Daily-Remaining"},"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"type":"object","required":["symbol","date","lookback_days","count","data"],"properties":{"symbol":{"type":"string"},"date":{"type":"string","format":"date","nullable":true},"lookback_days":{"type":"integer","nullable":true},"count":{"type":"integer"},"data":{"type":"array","items":{"$ref":"#/components/schemas/IvRankSeriesRow"}}}}}}},"400":{"description":"Invalid input: `INVALID_SYMBOL`, `INVALID_PARAM`.","headers":{"X-RateLimit-Limit":{"$ref":"#/components/headers/X-RateLimit-Limit"},"X-RateLimit-Remaining":{"$ref":"#/components/headers/X-RateLimit-Remaining"},"X-RateLimit-Reset":{"$ref":"#/components/headers/X-RateLimit-Reset"},"X-RateLimit-Daily-Limit":{"$ref":"#/components/headers/X-RateLimit-Daily-Limit"},"X-RateLimit-Daily-Remaining":{"$ref":"#/components/headers/X-RateLimit-Daily-Remaining"},"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/InternalError"},"503":{"$ref":"#/components/responses/AuthUnavailable"}}}},"/options-flow/history/{symbol}":{"get":{"tags":["Derived Analytics"],"summary":"Per-symbol EOD unusual-flow history","description":"End-of-day series of a symbol's unusual options flow (aggregated from\ncontracts that passed the unusual filter - not the full tape): daily\ncall/put contract counts, volume, open interest, premium, C/P ratios,\naverage IV, average Vol/OI, net delta and the consecutive-day streak.\nNewest first. An unknown symbol is not an error: 200 with `count: 0`.\n","parameters":[{"$ref":"#/components/parameters/symbolPath"},{"$ref":"#/components/parameters/date_from"},{"$ref":"#/components/parameters/date_to"},{"name":"limit","in":"query","schema":{"type":"integer","minimum":1,"maximum":200,"default":90}}],"responses":{"200":{"description":"Daily flow rows","headers":{"X-RateLimit-Limit":{"$ref":"#/components/headers/X-RateLimit-Limit"},"X-RateLimit-Remaining":{"$ref":"#/components/headers/X-RateLimit-Remaining"},"X-RateLimit-Reset":{"$ref":"#/components/headers/X-RateLimit-Reset"},"X-RateLimit-Daily-Limit":{"$ref":"#/components/headers/X-RateLimit-Daily-Limit"},"X-RateLimit-Daily-Remaining":{"$ref":"#/components/headers/X-RateLimit-Daily-Remaining"},"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"type":"object","required":["symbol","date","date_from","date_to","count","data"],"properties":{"symbol":{"type":"string"},"date":{"type":"string","format":"date","nullable":true,"description":"Newest day returned."},"date_from":{"type":"string","format":"date","nullable":true},"date_to":{"type":"string","format":"date","nullable":true},"count":{"type":"integer"},"data":{"type":"array","items":{"$ref":"#/components/schemas/DailyFlowRow"}}}}}}},"400":{"description":"Invalid input: `INVALID_SYMBOL`, `INVALID_DATE`, `INVALID_DATE_RANGE`, `INVALID_PARAM`.","headers":{"X-RateLimit-Limit":{"$ref":"#/components/headers/X-RateLimit-Limit"},"X-RateLimit-Remaining":{"$ref":"#/components/headers/X-RateLimit-Remaining"},"X-RateLimit-Reset":{"$ref":"#/components/headers/X-RateLimit-Reset"},"X-RateLimit-Daily-Limit":{"$ref":"#/components/headers/X-RateLimit-Daily-Limit"},"X-RateLimit-Daily-Remaining":{"$ref":"#/components/headers/X-RateLimit-Daily-Remaining"},"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/InternalError"},"503":{"$ref":"#/components/responses/AuthUnavailable"}}}},"/options-flow/streaks":{"get":{"tags":["Derived Analytics"],"summary":"Multi-day unusual-flow streaks","description":"Symbols showing unusual options activity for `min_streak` or more\nconsecutive trading days as of the requested day (default: latest).\n`dominant_side` is `call` when the call/put volume ratio is >= 1,\notherwise `put`; `side` filters on it. Ordered by `streak_days`\ndescending, then total premium descending.\n","parameters":[{"$ref":"#/components/parameters/date"},{"$ref":"#/components/parameters/symbols"},{"name":"min_streak","in":"query","schema":{"type":"integer","minimum":1,"maximum":365,"default":3}},{"name":"side","in":"query","schema":{"type":"string","enum":["call","put","all"],"default":"all"}},{"name":"min_volume","in":"query","description":"Minimum total contract volume on the day. Negative values are clamped to 0.","schema":{"type":"number","minimum":0}},{"name":"limit","in":"query","schema":{"type":"integer","minimum":1,"maximum":200,"default":50}}],"responses":{"200":{"description":"Streak rows","headers":{"X-RateLimit-Limit":{"$ref":"#/components/headers/X-RateLimit-Limit"},"X-RateLimit-Remaining":{"$ref":"#/components/headers/X-RateLimit-Remaining"},"X-RateLimit-Reset":{"$ref":"#/components/headers/X-RateLimit-Reset"},"X-RateLimit-Daily-Limit":{"$ref":"#/components/headers/X-RateLimit-Daily-Limit"},"X-RateLimit-Daily-Remaining":{"$ref":"#/components/headers/X-RateLimit-Daily-Remaining"},"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"type":"object","required":["date","min_streak","side","count","data"],"properties":{"date":{"type":"string","format":"date","nullable":true},"min_streak":{"type":"integer"},"side":{"type":"string","enum":["call","put","all"]},"count":{"type":"integer"},"data":{"type":"array","items":{"$ref":"#/components/schemas/StreakRow"}}}}}}},"400":{"description":"Invalid input: `INVALID_DATE`, `INVALID_PARAM`, `INVALID_SYMBOLS`.","headers":{"X-RateLimit-Limit":{"$ref":"#/components/headers/X-RateLimit-Limit"},"X-RateLimit-Remaining":{"$ref":"#/components/headers/X-RateLimit-Remaining"},"X-RateLimit-Reset":{"$ref":"#/components/headers/X-RateLimit-Reset"},"X-RateLimit-Daily-Limit":{"$ref":"#/components/headers/X-RateLimit-Daily-Limit"},"X-RateLimit-Daily-Remaining":{"$ref":"#/components/headers/X-RateLimit-Daily-Remaining"},"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/InternalError"},"503":{"$ref":"#/components/responses/AuthUnavailable"}}}},"/options-flow/expiry":{"get":{"tags":["Derived Analytics"],"summary":"Expiry (DTE) concentration","description":"Where the day's unusual premium sits along the DTE axis, in fixed\nbuckets with call/put splits. Buckets on integer\n`days_to_expiration`: `0-7` (dte <= 7), `8-30`, `31-90`, `90+`\n(dte > 90); rows without a DTE are excluded. Buckets are ordered\nshort-dated first; a bucket with no contracts is omitted. `date` in\nthe response is the day that was aggregated, also when the latest-day\ndefault was used.\n","parameters":[{"$ref":"#/components/parameters/date"},{"$ref":"#/components/parameters/symbols"}],"responses":{"200":{"description":"DTE buckets","headers":{"X-RateLimit-Limit":{"$ref":"#/components/headers/X-RateLimit-Limit"},"X-RateLimit-Remaining":{"$ref":"#/components/headers/X-RateLimit-Remaining"},"X-RateLimit-Reset":{"$ref":"#/components/headers/X-RateLimit-Reset"},"X-RateLimit-Daily-Limit":{"$ref":"#/components/headers/X-RateLimit-Daily-Limit"},"X-RateLimit-Daily-Remaining":{"$ref":"#/components/headers/X-RateLimit-Daily-Remaining"},"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"type":"object","required":["date","symbols","count","buckets"],"properties":{"date":{"type":"string","format":"date","nullable":true},"symbols":{"type":"array","items":{"type":"string"},"nullable":true,"description":"Echo of the parsed symbols filter; null when not sent."},"count":{"type":"integer","description":"Number of buckets returned"},"buckets":{"type":"array","items":{"$ref":"#/components/schemas/ExpiryBucket"}}}}}}},"400":{"description":"Invalid input: `INVALID_DATE`, `INVALID_SYMBOLS`.","headers":{"X-RateLimit-Limit":{"$ref":"#/components/headers/X-RateLimit-Limit"},"X-RateLimit-Remaining":{"$ref":"#/components/headers/X-RateLimit-Remaining"},"X-RateLimit-Reset":{"$ref":"#/components/headers/X-RateLimit-Reset"},"X-RateLimit-Daily-Limit":{"$ref":"#/components/headers/X-RateLimit-Daily-Limit"},"X-RateLimit-Daily-Remaining":{"$ref":"#/components/headers/X-RateLimit-Daily-Remaining"},"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"$ref":"#/components/responses/Forbidden"},"429":{"$ref":"#/components/responses/RateLimited"},"500":{"$ref":"#/components/responses/InternalError"},"503":{"$ref":"#/components/responses/AuthUnavailable"}}}}},"components":{"securitySchemes":{"ApiKeyAuth":{"type":"apiKey","in":"header","name":"X-API-Key","description":"API key generated at https://optionsbell.com/settings (prefix `sms_`). Requires an active Personal subscription."}},"headers":{"X-RateLimit-Limit":{"description":"Requests allowed per minute (30).","schema":{"type":"integer","example":30}},"X-RateLimit-Remaining":{"description":"Requests remaining in the current minute window.","schema":{"type":"integer"}},"X-RateLimit-Reset":{"description":"Unix timestamp (seconds) when the current minute window resets. Always refers to the minute window.","schema":{"type":"integer"}},"X-RateLimit-Daily-Limit":{"description":"Requests allowed per day (2000).","schema":{"type":"integer","example":2000}},"X-RateLimit-Daily-Remaining":{"description":"Requests remaining in the current day window.","schema":{"type":"integer"}},"X-Request-Id":{"description":"Unique id of this request; quote it when reporting a problem.","schema":{"type":"string","format":"uuid"}}},"parameters":{"symbolPath":{"name":"symbol","in":"path","required":true,"description":"Ticker, case-insensitive. Must match `^[A-Z][A-Z0-9.\\-]{0,9}$` after upper-casing, otherwise 400 `INVALID_SYMBOL`.","schema":{"type":"string","example":"AAPL"}},"symbols":{"name":"symbols","in":"query","description":"Comma-separated tickers, case-insensitive (e.g. `AAPL,NVDA`). Tokens must match `^[A-Z][A-Z0-9.\\-]{0,9}$`; invalid tokens next to valid ones are dropped, no valid token at all is 400 `INVALID_SYMBOLS`.","schema":{"type":"string"}},"date":{"name":"date","in":"query","description":"A specific trading day, `YYYY-MM-DD` (must be a real calendar day). Default is the latest available day.","schema":{"type":"string","format":"date"}},"date_from":{"name":"date_from","in":"query","description":"Inclusive lower bound, `YYYY-MM-DD`.","schema":{"type":"string","format":"date"}},"date_to":{"name":"date_to","in":"query","description":"Inclusive upper bound, `YYYY-MM-DD`. Must not be before `date_from` (400 `INVALID_DATE_RANGE`).","schema":{"type":"string","format":"date"}},"since":{"name":"since","in":"query","description":"ISO-8601 timestamp. Only contracts whose `last_seen_at` is at or after this instant. A polling window, not a monotonic cursor.","schema":{"type":"string","format":"date-time"}},"type":{"name":"type","in":"query","description":"Contract side, case-insensitive: `c` / `call` / `calls`, `p` / `put` / `puts`, or `all`.","schema":{"type":"string","enum":["c","p","all","call","calls","put","puts"],"default":"all"}},"min_voloi":{"name":"min_voloi","in":"query","description":"Minimum volume / open-interest ratio. Negative values are clamped to 0.","schema":{"type":"number","minimum":0}},"min_premium":{"name":"min_premium","in":"query","description":"Minimum estimated premium in USD (`last_price * volume * 100`). Negative values are clamped to 0.","schema":{"type":"number","minimum":0}},"min_iv":{"name":"min_iv","in":"query","description":"Minimum implied volatility in percent (60 = 60%).","schema":{"type":"number","minimum":0}},"max_dte":{"name":"max_dte","in":"query","description":"Maximum days to expiration. Floats are floored.","schema":{"type":"integer","minimum":0}},"min_volume":{"name":"min_volume","in":"query","description":"Minimum contract volume.","schema":{"type":"number","minimum":0}},"min_oi":{"name":"min_oi","in":"query","description":"Minimum open interest.","schema":{"type":"number","minimum":0}},"raw":{"name":"raw","in":"query","description":"`1` or `true`: skip the always-on base floor (Vol/OI >= 1.5, OI >= 100, premium >= $25k).","schema":{"type":"boolean","default":false}},"offset":{"name":"offset","in":"query","description":"Rows to skip. Combine with `limit` to enumerate every matching row; the envelope reports `filtered_total` and `has_more`.","schema":{"type":"integer","minimum":0,"default":0}}},"schemas":{"ApiError":{"type":"object","required":["error","code"],"properties":{"error":{"type":"string","description":"Human-readable message."},"code":{"type":"string","description":"Stable machine-readable code."},"requestId":{"type":"string","format":"uuid","description":"Present on 500 responses only; matches the X-Request-Id header."}}},"NumericString":{"type":"string","description":"Numeric string - a BIGINT or NUMERIC value serialized as text to preserve precision, e.g. \"1234\" or \"25.43\".","example":"1234"},"PingResponse":{"type":"object","required":["status","timestamp"],"properties":{"status":{"type":"string","enum":["ok"]},"timestamp":{"type":"string","format":"date-time"}}},"HealthResponse":{"type":"object","required":["status","version","timestamp","db"],"properties":{"status":{"type":"string","enum":["ok"]},"version":{"type":"string","example":"v1"},"timestamp":{"type":"string","format":"date-time"},"db":{"type":"object","required":["reachable","latencyMs"],"properties":{"reachable":{"type":"boolean"},"latencyMs":{"type":"integer"}}}}},"StatsResponse":{"type":"object","required":["unusual_activity","daily_flow","sectors","rescan_cadence_minutes"],"properties":{"unusual_activity":{"type":"object","properties":{"date_from":{"type":"string","format":"date","nullable":true},"date_to":{"type":"string","format":"date","nullable":true},"contracts":{"type":"integer"},"symbols":{"type":"integer"}}},"daily_flow":{"type":"object","properties":{"date_from":{"type":"string","format":"date","nullable":true},"date_to":{"type":"string","format":"date","nullable":true},"trading_days":{"type":"integer"},"symbols":{"type":"integer"}}},"sectors":{"type":"object","properties":{"distinct_sectors":{"type":"integer"},"classified_symbols":{"type":"integer"}}},"rescan_cadence_minutes":{"type":"integer","example":5}}},"UnusualContract":{"type":"object","description":"One contract-level unusual activity row. Prices, volumes and ratios are numeric strings.","properties":{"symbol":{"type":"string","example":"TSLA"},"option_symbol":{"type":"string","example":"TSLA|20260605|460.00P"},"symbol_type":{"type":"string","enum":["Call","Put"]},"base_last_price":{"type":"string","description":"Numeric string. Underlying price."},"strike_price":{"type":"string","description":"Numeric string."},"expiration_date":{"type":"string","description":"Expiration date as stored by the data source."},"days_to_expiration":{"type":"integer","nullable":true},"last_price":{"type":"string","description":"Numeric string."},"bid_price":{"type":"string","description":"Numeric string."},"midpoint":{"type":"string","description":"Numeric string."},"ask_price":{"type":"string","description":"Numeric string."},"volume":{"type":"string","description":"Numeric string."},"open_interest":{"type":"string","description":"Numeric string."},"volume_oi_ratio":{"type":"string","description":"Numeric string."},"volatility":{"type":"string","description":"Numeric string. Implied volatility in percent (25.43 = 25.43%)."},"delta":{"type":"string","description":"Numeric string."},"trade_time":{"type":"string","description":"Last trade time as stored by the data source."},"data_date":{"type":"string","format":"date","description":"Trading day, YYYY-MM-DD."},"first_seen_at":{"type":"string","format":"date-time","nullable":true,"description":"First 5-minute scan that listed the contract (UTC); null when no intraday appearance was recorded."},"last_seen_at":{"type":"string","format":"date-time","nullable":true,"description":"Most recent regular-session scan that listed the contract (UTC)."},"sector":{"type":"string","nullable":true},"industry":{"type":"string","nullable":true},"premium_estimate":{"type":"string","description":"Numeric string. last_price * volume * 100, USD, rounded."},"is_sweep_like":{"type":"boolean","nullable":true,"description":"EOD proxy for sweep-quality prints: Vol/OI >= 5, OI >= 100, volume >= 1000, DTE 0-60, premium >= $250k. Null when an input is missing."}}},"TopPrint":{"type":"object","description":"One ranked top print.","properties":{"rank":{"type":"integer","description":"1-based position by premium_estimate."},"symbol":{"type":"string"},"option_symbol":{"type":"string"},"symbol_type":{"type":"string","enum":["Call","Put"]},"base_last_price":{"type":"string","description":"Numeric string."},"strike_price":{"type":"string","description":"Numeric string."},"expiration_date":{"type":"string"},"days_to_expiration":{"type":"integer"},"last_price":{"type":"string","description":"Numeric string."},"volume":{"type":"string","description":"Numeric string."},"open_interest":{"type":"string","description":"Numeric string."},"volume_oi_ratio":{"type":"string","description":"Numeric string."},"volatility":{"type":"string","description":"Numeric string. IV in percent."},"delta":{"type":"string","description":"Numeric string."},"date":{"type":"string","format":"date"},"sector":{"type":"string","nullable":true},"industry":{"type":"string","nullable":true},"premium_estimate":{"type":"string","description":"Numeric string. USD."}}},"MarketRow":{"type":"object","properties":{"date":{"type":"string","format":"date"},"breadth_score":{"type":"integer","nullable":true,"minimum":0,"maximum":100,"description":"Share of classified symbols reading bullish; null only when none were classified."},"call_put_ratio":{"type":"number","nullable":true,"description":"Aggregate call vs. put volume across flagged names."},"regime":{"type":"string","enum":["bullish","bearish","mixed"]},"bullish_count":{"type":"integer"},"bearish_count":{"type":"integer"}}},"SentimentSeriesRow":{"type":"object","description":"One (symbol, day) sentiment row without the symbol field.","properties":{"date":{"type":"string","format":"date"},"stock_price":{"type":"string","nullable":true,"description":"Numeric string."},"sector":{"type":"string","nullable":true},"industry":{"type":"string","nullable":true},"side":{"type":"string","nullable":true,"enum":["bullish","bearish",null],"description":"Signal classification; null when no signal fired."},"signal_type":{"type":"string","nullable":true},"strength_score":{"type":"integer","nullable":true,"minimum":0,"maximum":9},"call_volume":{"type":"string","description":"Numeric string."},"put_volume":{"type":"string","description":"Numeric string."},"call_total_premium":{"type":"string","description":"Numeric string. USD."},"put_total_premium":{"type":"string","description":"Numeric string. USD."},"call_oi":{"type":"string","description":"Numeric string."},"put_oi":{"type":"string","description":"Numeric string."},"net_delta":{"type":"string","description":"Numeric string."},"call_put_volume_ratio":{"type":"string","nullable":true,"description":"Numeric string."},"call_put_oi_ratio":{"type":"string","nullable":true,"description":"Numeric string."},"call_avg_iv":{"type":"string","description":"Numeric string. Percent."},"put_avg_iv":{"type":"string","description":"Numeric string. Percent."},"avg_days_to_expiry":{"type":"string","nullable":true,"description":"Numeric string."},"consecutive_days":{"type":"integer"},"bullish_confirmations":{"type":"array","items":{"type":"string"},"description":"Screener names confirming the bullish read; empty when none."},"bearish_confirmations":{"type":"array","items":{"type":"string"}}}},"SentimentRow":{"allOf":[{"type":"object","properties":{"symbol":{"type":"string"}}},{"$ref":"#/components/schemas/SentimentSeriesRow"}]},"OiChangeSeriesRow":{"type":"object","description":"One day of a symbol's OI series. prev_* and *_change are null on the oldest row of the window.","properties":{"date":{"type":"string","format":"date"},"prev_date":{"type":"string","format":"date","nullable":true},"total_oi":{"type":"string","description":"Numeric string."},"prev_oi":{"type":"string","nullable":true,"description":"Numeric string."},"oi_change":{"type":"string","nullable":true,"description":"Numeric string."},"oi_change_pct":{"type":"number","nullable":true,"description":"Fraction (0.5 = +50%); null when prev_oi is 0 or missing."},"call_oi":{"type":"string","description":"Numeric string."},"prev_call_oi":{"type":"string","nullable":true,"description":"Numeric string."},"call_oi_change":{"type":"string","nullable":true,"description":"Numeric string."},"put_oi":{"type":"string","description":"Numeric string."},"prev_put_oi":{"type":"string","nullable":true,"description":"Numeric string."},"put_oi_change":{"type":"string","nullable":true,"description":"Numeric string."}}},"OiChangeRow":{"allOf":[{"type":"object","properties":{"symbol":{"type":"string"},"sector":{"type":"string","nullable":true},"industry":{"type":"string","nullable":true}}},{"$ref":"#/components/schemas/OiChangeSeriesRow"}]},"SectorRow":{"type":"object","properties":{"sector":{"type":"string","description":"GICS sector or `Unclassified`."},"symbol_count":{"type":"string","description":"Numeric string."},"total_volume":{"type":"string","description":"Numeric string."},"call_premium_usd":{"type":"string","description":"Numeric string."},"put_premium_usd":{"type":"string","description":"Numeric string."},"total_premium_usd":{"type":"string","description":"Numeric string."},"avg_net_delta":{"type":"string","nullable":true,"description":"Numeric string."},"bullish_count":{"type":"string","description":"Numeric string."},"bearish_count":{"type":"string","description":"Numeric string."}}},"IvRankSeriesRow":{"type":"object","properties":{"date":{"type":"string","format":"date"},"call_iv":{"type":"string","description":"Numeric string. Percent."},"put_iv":{"type":"string","description":"Numeric string. Percent."},"call_iv_rank":{"type":"string","nullable":true,"description":"Numeric string, 0..1; null when max == min."},"put_iv_rank":{"type":"string","nullable":true,"description":"Numeric string, 0..1; null when max == min."},"call_iv_percentile":{"type":"number","minimum":0,"maximum":1},"put_iv_percentile":{"type":"number","minimum":0,"maximum":1},"min_call_iv":{"type":"string","description":"Numeric string."},"max_call_iv":{"type":"string","description":"Numeric string."},"min_put_iv":{"type":"string","description":"Numeric string."},"max_put_iv":{"type":"string","description":"Numeric string."},"lookback_days":{"type":"string","description":"Numeric string. Sessions in the window."},"history_start":{"type":"string","format":"date"}}},"IvRankRow":{"type":"object","properties":{"symbol":{"type":"string"},"date":{"type":"string","format":"date"},"sector":{"type":"string","nullable":true},"industry":{"type":"string","nullable":true},"iv_rank":{"type":"string","nullable":true,"description":"Numeric string. The rank selected by `side`."},"current_call_iv":{"type":"string","description":"Numeric string. Percent."},"current_put_iv":{"type":"string","description":"Numeric string. Percent."},"call_iv_rank":{"type":"string","nullable":true,"description":"Numeric string, 0..1."},"put_iv_rank":{"type":"string","nullable":true,"description":"Numeric string, 0..1."},"call_iv_percentile":{"type":"number","minimum":0,"maximum":1},"put_iv_percentile":{"type":"number","minimum":0,"maximum":1},"min_call_iv":{"type":"string","description":"Numeric string."},"max_call_iv":{"type":"string","description":"Numeric string."},"min_put_iv":{"type":"string","description":"Numeric string."},"max_put_iv":{"type":"string","description":"Numeric string."},"lookback_days":{"type":"string","description":"Numeric string. Sessions in the window (>= 20)."},"history_start":{"type":"string","format":"date"}}},"DailyFlowRow":{"type":"object","description":"One end-of-day row of a symbol's aggregated unusual flow.","properties":{"date":{"type":"string","format":"date"},"stock_price":{"type":"string","nullable":true,"description":"Numeric string."},"call_contracts":{"type":"integer"},"put_contracts":{"type":"integer"},"call_volume":{"type":"string","description":"Numeric string."},"put_volume":{"type":"string","description":"Numeric string."},"total_volume":{"type":"string","description":"Numeric string."},"call_open_interest":{"type":"string","description":"Numeric string."},"put_open_interest":{"type":"string","description":"Numeric string."},"total_oi":{"type":"string","description":"Numeric string."},"call_total_premium":{"type":"string","description":"Numeric string. USD."},"put_total_premium":{"type":"string","description":"Numeric string. USD."},"call_put_volume_ratio":{"type":"string","nullable":true,"description":"Numeric string."},"call_put_oi_ratio":{"type":"string","nullable":true,"description":"Numeric string."},"call_avg_iv":{"type":"string","description":"Numeric string. Percent."},"put_avg_iv":{"type":"string","description":"Numeric string. Percent."},"call_avg_vol_oi":{"type":"string","description":"Numeric string."},"put_avg_vol_oi":{"type":"string","description":"Numeric string."},"net_delta":{"type":"string","description":"Numeric string."},"avg_days_to_expiry":{"type":"string","nullable":true,"description":"Numeric string."},"consecutive_days":{"type":"integer"}}},"StreakRow":{"type":"object","properties":{"symbol":{"type":"string"},"date":{"type":"string","format":"date"},"streak_days":{"type":"integer"},"dominant_side":{"type":"string","enum":["call","put"]},"call_put_volume_ratio":{"type":"string","nullable":true,"description":"Numeric string."},"stock_price":{"type":"string","nullable":true,"description":"Numeric string."},"call_volume":{"type":"string","description":"Numeric string."},"put_volume":{"type":"string","description":"Numeric string."},"total_volume":{"type":"string","description":"Numeric string."},"call_total_premium":{"type":"string","description":"Numeric string. USD."},"put_total_premium":{"type":"string","description":"Numeric string. USD."},"total_premium":{"type":"string","description":"Numeric string. USD."},"call_avg_iv":{"type":"string","description":"Numeric string. Percent."},"put_avg_iv":{"type":"string","description":"Numeric string. Percent."},"net_delta":{"type":"string","description":"Numeric string."},"sector":{"type":"string","nullable":true},"industry":{"type":"string","nullable":true}}},"ExpiryBucket":{"type":"object","properties":{"dte_bucket":{"type":"string","enum":["0-7","8-30","31-90","90+"]},"contracts":{"type":"integer"},"volume":{"type":"string","description":"Numeric string."},"premium_estimate":{"type":"string","description":"Numeric string. USD."},"call_contracts":{"type":"integer"},"put_contracts":{"type":"integer"},"call_premium":{"type":"string","description":"Numeric string. USD."},"put_premium":{"type":"string","description":"Numeric string. USD."}}}},"responses":{"Unauthorized":{"description":"Missing or invalid API key: `MISSING_API_KEY`, `INVALID_API_KEY_FORMAT`, `INVALID_API_KEY`. No rate-limit headers.","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":"Missing X-API-Key header. Generate one at /settings.","code":"MISSING_API_KEY"}}}},"Forbidden":{"description":"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.","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":"API access requires an active subscription. Subscribe at /settings.","code":"NO_ACTIVE_SUBSCRIPTION"}}}},"RateLimited":{"description":"Rate limit exceeded: `RATE_LIMIT_MINUTE` (30/min) or `RATE_LIMIT_DAY` (2,000/day). Carries both rate-limit header sets.","headers":{"X-RateLimit-Limit":{"$ref":"#/components/headers/X-RateLimit-Limit"},"X-RateLimit-Remaining":{"$ref":"#/components/headers/X-RateLimit-Remaining"},"X-RateLimit-Reset":{"$ref":"#/components/headers/X-RateLimit-Reset"},"X-RateLimit-Daily-Limit":{"$ref":"#/components/headers/X-RateLimit-Daily-Limit"},"X-RateLimit-Daily-Remaining":{"$ref":"#/components/headers/X-RateLimit-Daily-Remaining"},"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":"Rate limit exceeded. pro plan: max 30 requests per minute.","code":"RATE_LIMIT_MINUTE"}}}},"InternalError":{"description":"Unexpected server error: `INTERNAL_ERROR`. The body and the X-Request-Id header carry the request id.","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":"Internal server error. Please try again later.","code":"INTERNAL_ERROR","requestId":"6f1c1c0e-2a7b-4c1e-9d3a-0b1c2d3e4f5a"}}}},"AuthUnavailable":{"description":"Authentication backend unreachable: `AUTH_UNAVAILABLE`. Retry later. No rate-limit headers.","headers":{"X-Request-Id":{"$ref":"#/components/headers/X-Request-Id"}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiError"},"example":{"error":"Authentication service unavailable. Please try again later.","code":"AUTH_UNAVAILABLE"}}}}}}}