API docs for using
market context programmatically.
Use OptionChainIQ endpoints to pull captured option-chain data, IV/HV analytics, OHLCV history, signals, scanner candidates, and contract research records from the same store behind the Overview.
1. Quickstart
Send your API key in the X-API-Key header. Public utility endpoints such as /health do not require a key, but data endpoints require API privileges.
curl "https://api.optionchainiq.com/v1/iv-rank/SPY?limit=5" \ -H "X-API-Key: occ_your_api_key"
Python
import os
import requests
API_KEY = os.environ["OPTIONCHAINIQ_API_KEY"]
BASE_URL = "https://api.optionchainiq.com"
response = requests.get(
f"{BASE_URL}/v1/iv-rank/AAPL",
params={"limit": 5},
headers={"X-API-Key": API_KEY},
timeout=20,
)
response.raise_for_status()
print(response.json())
REST Client
@baseUrl = https://api.optionchainiq.com
@apiKey = occ_your_api_key
### IV Rank for AAPL
GET {{baseUrl}}/v1/iv-rank/AAPL?limit=5
X-API-Key: {{apiKey}}
### Latest AAPL chain
GET {{baseUrl}}/v1/chains/AAPL?option_type=CALL&min_dte=20&max_dte=45&limit=50
X-API-Key: {{apiKey}}
2. Authentication
API access is available to plans with API privileges. Dashboard-only plans can view the app but cannot call protected API endpoints.
| Header | Required | Description |
|---|---|---|
X-API-Key | Yes | Your OptionChainIQ API key generated from the API Console. |
3. Pagination and limits
List endpoints use limit and offset. Most paginated endpoints default to 100 rows and cap at 500.
{
"data": [],
"meta": {
"total": 1240,
"count": 100,
"limit": 100,
"offset": 0
}
}
4. System and symbols
GET /health checks API, database, parquet, and runner health. No API key required.
GET /v1/symbols lists symbols with captured volatility data.
GET /health
{
"status": "ok",
"checks": {
"database": {"status": "ok", "size_mb": 22.1},
"parquet": {"status": "ok", "files": 8884},
"runner": {"status": "ok"}
}
}
GET /v1/symbols
{
"data": ["AAPL", "MSFT", "NVDA", "SPY"],
"meta": {
"total": 208,
"count": 4
}
}
5. Volatility analytics
GET /v1/iv-rank/{symbol} returns the latest IV Rank plus recent IV history for one symbol.
GET /v1/iv returns paginated implied-volatility snapshots. Query: symbol, from, to, limit, offset.
GET /v1/hv returns paginated historical-volatility snapshots. Query: symbol, from, to, limit, offset.
GET /v1/iv-rank/AAPL
{
"symbol": "AAPL",
"latest": {
"captured_at": "2026-05-18T20:00:00Z",
"underlying_price": 300.23,
"atm_iv": 24.18,
"iv_rank": 41.6,
"iv_percentile": 58.2,
"skew": 3.4
},
"history": []
}
GET /v1/hv?symbol=AAPL
{
"data": [
{
"symbol": "AAPL",
"computed_at": "2026-05-18T20:05:00Z",
"hv_10d": 18.9,
"hv_20d": 21.4,
"hv_30d": 22.1
}
],
"meta": {"limit": 100, "offset": 0}
}
6. Option-chain and contract endpoints
GET /v1/chains/{symbol} returns option-chain contracts for a symbol from the Parquet store.
GET /v1/chains/{symbol}/expirations returns available expirations and call/put counts for a symbol.
GET /v1/contracts searches contracts by symbol, date, expiration, strike, option type, DTE, volume, open interest, delta, IV, and pagination filters.
GET /v1/contracts/{option_symbol} returns the latest captured row for one option contract.
GET /v1/contracts/{option_symbol}/history returns historical captured rows for one option contract.
GET /v1/chains/AAPL
{
"data": [
{
"underlying_symbol": "AAPL",
"option_symbol": "AAPL260619C00300000",
"expiration_date": "2026-06-19",
"put_call": "CALL",
"strike": 300,
"bid": 12.4,
"ask": 12.75,
"delta": 0.52,
"implied_volatility": 0.241
}
],
"meta": {"count": 1, "limit": 50}
}
GET /v1/contracts
{
"data": [
{
"option_symbol": "SPY260619P00700000",
"underlying_symbol": "SPY",
"put_call": "PUT",
"strike": 700,
"days_to_expiration": 32,
"open_interest": 18420,
"volume": 3912
}
],
"meta": {"total": 18420, "limit": 100, "offset": 0}
}
7. Signals, prices, and scanners
GET /v1/signals returns signals generated from captured market data.
GET /v1/ohlcv returns underlying OHLCV history.
GET /v1/underlying-snapshots returns per-run underlying price snapshots captured with option chains.
GET /v1/scanners/premium returns premium scanner candidates from latest captured analytics.
GET /v1/strategies/pcs-candidates returns put credit spread candidates based on IV Rank, skew, earnings, and volatility context.
GET /v1/signals
{
"data": [
{
"symbol": "AAPL",
"signal": "IV_EXPANSION",
"strength": "medium",
"score": 72.4,
"captured_at": "2026-05-18T20:00:00Z"
}
],
"meta": {"count": 1}
}
GET /v1/strategies/pcs-candidates
{
"data": [
{
"symbol": "SPY",
"strategy": "PUT_CREDIT_SPREAD",
"short_put": 720,
"long_put": 715,
"expiration": "2026-06-19",
"credit": 1.22,
"pop": 68.5,
"score": 81.3
}
],
"meta": {"count": 1}
}
8. Tradier broker endpoints
Tradier broker endpoints use the same X-API-Key to identify the OptionChainIQ user, then read that user's encrypted Tradier OAuth connection. Clients never send Tradier tokens to these endpoints.
GET /v1/broker/tradier/status returns the user's broker connection status.
GET /v1/broker/tradier/accounts lists authorized Tradier account numbers for that user.
POST /v1/broker/tradier/accounts/select sets the selected authorized account.
GET /v1/broker/tradier/summary returns balances, positions, and orders for the selected or requested authorized account.
GET /v1/broker/tradier/positions returns OptionChainIQ's normalized positions and P/L payload from the user's Tradier account.
GET /v1/broker/tradier/status
{
"provider": "tradier",
"entitled": true,
"connection": {
"connected": true,
"selected_account_id": "VA000001",
"scopes": "read market"
}
}
GET /v1/broker/tradier/summary
{
"provider": "tradier",
"account_id": "VA000001",
"balances": {"total_equity": 25000.5},
"positions": [],
"orders": []
}
9. Response shape
Responses are JSON. List endpoints return a data array and meta pagination object. Single-resource endpoints return the requested object or a structured detail error.
{
"symbol": "SPY",
"count": 5,
"latest": {
"captured_at": "2026-05-12T14:30:00Z",
"underlying_price": 738.41,
"atm_iv": 18.42,
"iv_rank": 72.8,
"iv_percentile": 66.1,
"skew": 4.2
},
"history": []
}
10. Errors
| Status | Meaning |
|---|---|
401 | Missing API key. |
403 | Invalid, disabled, or plan-restricted API key. |
404 | No data found for the requested symbol, run, date, or filter. |
429 | Rate limit exceeded. |
500 | Server-side query or storage error. |
11. Examples
List symbols
curl "https://api.optionchainiq.com/v1/symbols" \ -H "X-API-Key: occ_your_api_key"
Latest SPY chain
curl "https://api.optionchainiq.com/v1/chains/SPY?option_type=PUT&min_dte=20&max_dte=45&limit=100" \ -H "X-API-Key: occ_your_api_key"
REST Client file
@baseUrl = https://api.optionchainiq.com
@apiKey = occ_your_api_key
### Health, no key required
GET {{baseUrl}}/health
### Symbols
GET {{baseUrl}}/v1/symbols
X-API-Key: {{apiKey}}
### IV snapshots
GET {{baseUrl}}/v1/iv?symbol=AAPL&limit=25
X-API-Key: {{apiKey}}
### Contract search
GET {{baseUrl}}/v1/contracts?symbol=SPY&option_type=PUT&min_dte=20&max_dte=45&min_open_interest=500&limit=50
X-API-Key: {{apiKey}}
### Put credit spread candidates
GET {{baseUrl}}/v1/strategies/pcs-candidates?symbol=SPY&limit=25
X-API-Key: {{apiKey}}
### Tradier positions for the authenticated API user
GET {{baseUrl}}/v1/broker/tradier/positions
X-API-Key: {{apiKey}}
Python helper
import os
import requests
class OptionChainIQ:
def __init__(self, api_key, base_url="https://api.optionchainiq.com"):
self.base_url = base_url.rstrip("/")
self.session = requests.Session()
self.session.headers.update({"X-API-Key": api_key})
def get(self, path, **params):
response = self.session.get(
f"{self.base_url}{path}",
params={k: v for k, v in params.items() if v is not None},
timeout=30,
)
response.raise_for_status()
return response.json()
client = OptionChainIQ(os.environ["OPTIONCHAINIQ_API_KEY"])
chain = client.get(
"/v1/chains/AAPL",
option_type="CALL",
min_dte=20,
max_dte=45,
limit=50,
)
print(chain["meta"])