Public API Reference
Theta Vantage provides a REST API for programmatic access to options analytics data. Use it to integrate GEX, DEX, VEX, key levels, max pain, gamma profile, heatmap, and AI-generated daily report data into your own applications, scripts, or trading systems.
Authentication
All API requests require an API key. Generate one from your Account Settings page (PRO tiers only).
Method 1: Header Authentication (Recommended)
Include your key in every request using the X-API-Key header:
curl -H "X-API-Key: tvk_YOUR_KEY_HERE" \
"https://thetavantage.com/api/v1/status"
Method 2: Query Parameter Authentication
Alternatively, pass it as a query parameter api_key:
curl "https://thetavantage.com/api/v1/status?api_key=tvk_YOUR_KEY_HERE"
Note: Both methods work identically. Query parameters are useful for browser testing or when HTTP headers are difficult to set. Header authentication is recommended for production applications.
Rate Limits
- 60 requests per minute per API key (sliding window)
- Rate limit headers are included in every response:
X-RateLimit-Remaining— requests left in the current windowX-RateLimit-Reset— seconds until the window resets
Base URL
https://thetavantage.com/api/v1
Status
Test your API key and check connectivity.
GET /api/v1/status
Example (Header):
curl -H "X-API-Key: tvk_YOUR_KEY" https://thetavantage.com/api/v1/status
Example (Query Parameter):
curl "https://thetavantage.com/api/v1/status?api_key=tvk_YOUR_KEY"
Response:
{
"status": "ok",
"user": { "email": "[email protected]", "tier": "pro" },
"timestamp": "2026-02-14T19:00:00.000Z"
}
Gamma Exposure (GEX)
Returns strike-level gamma exposure analysis.
GET /api/v1/gex?symbol=SPY
| Parameter | Required | Default | Description |
|---|---|---|---|
symbol | Yes | — | Ticker symbol (e.g. SPY, AAPL, QQQ) |
expiration | No | all | Filter to a specific expiration (YYYY-MM-DD) |
Example (Header):
curl -H "X-API-Key: tvk_YOUR_KEY" \
"https://thetavantage.com/api/v1/gex?symbol=SPY&expiration=2026-02-21"
Example (Query Parameter):
curl "https://thetavantage.com/api/v1/gex?symbol=SPY&expiration=2026-02-21&api_key=tvk_YOUR_KEY"
Response fields:
| Field | Type | Description |
|---|---|---|
symbol | string | Ticker |
current_price | number | Current spot price |
expiration | string | Expiration filter used |
total_gamma_exposure | number | Net GEX across all strikes |
call_gamma_exposure | number | Total call-side GEX |
put_gamma_exposure | number | Total put-side GEX |
strikes | array | Per-strike breakdown with strike, gamma_exposure, call_gamma, put_gamma |
Delta Exposure (DEX)
Returns strike-level delta exposure analysis.
GET /api/v1/dex?symbol=SPY
| Parameter | Required | Default | Description |
|---|---|---|---|
symbol | Yes | — | Ticker symbol |
expiration | No | all | Filter to a specific expiration (YYYY-MM-DD) |
Response fields:
| Field | Type | Description |
|---|---|---|
symbol | string | Ticker |
current_price | number | Current spot price |
total_delta_exposure | number | Net DEX |
call_delta_exposure | number | Call-side DEX |
put_delta_exposure | number | Put-side DEX |
strikes | array | Per-strike breakdown |
Vanna Exposure (VEX)
Returns strike-level vanna exposure, measuring delta sensitivity to implied volatility.
GET /api/v1/vex?symbol=SPY
| Parameter | Required | Default | Description |
|---|---|---|---|
symbol | Yes | — | Ticker symbol |
expiration | No | all | Filter to a specific expiration (YYYY-MM-DD) |
Response fields:
| Field | Type | Description |
|---|---|---|
symbol | string | Ticker |
current_price | number | Current spot price |
total_vanna_exposure | number | Net VEX |
call_vanna_exposure | number | Call-side VEX |
put_vanna_exposure | number | Put-side VEX |
strikes | array | Per-strike breakdown |
Charm Exposure
Returns strike-level charm exposure, measuring delta decay over time.
GET /api/v1/charm?symbol=SPY
| Parameter | Required | Default | Description |
|---|---|---|---|
symbol | Yes | — | Ticker symbol |
expiration | No | all | Filter to a specific expiration (YYYY-MM-DD) |
Response fields:
| Field | Type | Description |
|---|---|---|
symbol | string | Ticker |
current_price | number | Current spot price |
total_charm_exposure | number | Net charm |
call_charm_exposure | number | Call-side charm |
put_charm_exposure | number | Put-side charm |
strikes | array | Per-strike breakdown |
Key Levels
Returns options-derived key price levels: Call Wall, Put Wall, Hedge Wall, Max Pain, Expected Move, and GEX walls.
GET /api/v1/key-levels?symbol=SPY
| Parameter | Required | Default | Description |
|---|---|---|---|
symbol | Yes | — | Ticker symbol |
expiration | No | nearest weekly | Filter to a specific expiration (YYYY-MM-DD) |
Example (Header):
curl -H "X-API-Key: tvk_YOUR_KEY" \
"https://thetavantage.com/api/v1/key-levels?symbol=SPY"
Example (Query Parameter):
curl "https://thetavantage.com/api/v1/key-levels?symbol=SPY&api_key=tvk_YOUR_KEY"
Response fields:
| Field | Type | Description |
|---|---|---|
call_wall | number | Highest call open interest strike (resistance) |
put_wall | number | Highest put open interest strike (support) |
hedge_wall | number | Where dealer hedging pressure flips |
max_pain | number | Strike with minimum total option holder pain |
expected_move_upper | number | Upper bound of expected move |
expected_move_lower | number | Lower bound of expected move |
expected_move_pct | number | Expected move as a percentage |
distances | object | Percentage distances from current price to each level |
gex_walls | object | GEX-derived call/put walls (gamma-weighted) |
Max Pain
Returns max pain analysis with per-strike pain breakdown.
GET /api/v1/max-pain?symbol=SPY
| Parameter | Required | Default | Description |
|---|---|---|---|
symbol | Yes | — | Ticker symbol |
expiration | No | nearest weekly | Filter to a specific expiration (YYYY-MM-DD) |
Response fields:
| Field | Type | Description |
|---|---|---|
max_pain_strike | number | The strike where total option holder pain is minimized |
distance_from_current_pct | number | Distance from current price (%) |
strikes | array | Per-strike call_pain, put_pain, total_pain breakdown |
Gamma Profile
Returns the gamma exposure curve across theoretical spot prices, the zero gamma level, and market implications.
GET /api/v1/gamma-profile?symbol=SPY
| Parameter | Required | Default | Description |
|---|---|---|---|
symbol | Yes | — | Ticker symbol |
Example (Header):
curl -H "X-API-Key: tvk_YOUR_KEY" \
"https://thetavantage.com/api/v1/gamma-profile?symbol=SPY"
Example (Query Parameter):
curl "https://thetavantage.com/api/v1/gamma-profile?symbol=SPY&api_key=tvk_YOUR_KEY"
Response fields:
| Field | Type | Description |
|---|---|---|
current_spot_gex | number | GEX at the current price |
zero_gamma_level | number/null | Price where GEX crosses zero |
is_above_zero_gamma | boolean | Whether spot is above the zero gamma level |
distance_to_zero_gamma_pct | number/null | Distance to zero gamma (%) |
gamma_environment | string | "Positive GEX", "Negative GEX", "Neutral", or "Unknown" |
market_implication | string | What the current gamma environment implies for price action |
profile | array | 100-point curve of { spotPrice, gammaExposure } |
Heatmap
Returns a 2-D grid of Greek exposure per strike × expiration, with volume breakdown.
GET /api/v1/heatmap?symbol=SPY&greek=gamma
| Parameter | Required | Default | Description |
|---|---|---|---|
symbol | Yes | — | Ticker symbol |
greek | No | gamma | Greek type: gamma, vanna, or delta |
range | No | 0.10 | Price range as a fraction (e.g. 0.05 = ±5% from spot) |
expiration | No | all | Filter to a single expiration (YYYY-MM-DD) |
Example (Header):
curl -H "X-API-Key: tvk_YOUR_KEY" \
"https://thetavantage.com/api/v1/heatmap?symbol=SPY&greek=gamma&range=0.05"
Example (Query Parameter):
curl "https://thetavantage.com/api/v1/heatmap?symbol=SPY&greek=gamma&range=0.05&api_key=tvk_YOUR_KEY"
Response fields:
| Field | Type | Description |
|---|---|---|
greek | string | Greek type used |
range | number | Price range fraction |
summary.total_exposure | number | Sum of all cell exposures |
summary.max_cell_exposure | number | Largest absolute cell exposure |
summary.total_volume | number | Total options volume in range |
summary.strikes_count | number | Number of strikes in the grid |
summary.expirations_count | number | Number of expirations |
summary.cells_count | number | Total grid cells with data |
summary.top_cells | array | Top 5 cells by absolute exposure |
expirations | array | Sorted list of expiration dates |
strikes | array | Sorted list of strike prices |
grid | array | Cell objects with strike, expiration, exposure, call_volume, put_volume, total_volume |
Daily Report
Returns an AI-generated daily trading report with mode assessment, positioning guidance, alert levels, scenario pathing, strategist's narrative, multi-timeframe technical analysis, and a social-ready formatted text. The endpoint fetches live options and quote data, calculates key levels, then generates the report via AI.
Note: Response time is typically 5–15 seconds due to AI generation.
GET /api/v1/report?symbol=SPY
| Parameter | Required | Default | Description |
|---|---|---|---|
symbol | Yes | — | Ticker symbol (e.g. SPY, AAPL, QQQ) |
expiration | No | nearest weekly | Filter key levels to a specific expiration (YYYY-MM-DD) |
Example (Header):
curl -H "X-API-Key: tvk_YOUR_KEY" \
"https://thetavantage.com/api/v1/report?symbol=SPY"
Example (Query Parameter):
curl "https://thetavantage.com/api/v1/report?symbol=SPY&api_key=tvk_YOUR_KEY"
Response fields:
| Field | Type | Description |
|---|---|---|
symbol | string | Ticker |
price | object | Full price snapshot (see below) |
expiration | string | Expiration used for key level calculations |
report | object | AI-generated report (see below) |
key_levels | object | Options-derived key levels (see below) |
timeframe_analysis | object|null | Multi-timeframe technical indicators (see below). Null if indicators unavailable. |
formatted_text | string | Social-ready formatted text (same as the copy-to-clipboard output) |
timestamp | string | ISO 8601 timestamp |
price object:
| Field | Type | Description |
|---|---|---|
current | number | Current spot price |
change | number | Dollar change from previous close |
change_percent | number | Percentage change from previous close |
previous_close | number | Previous closing price |
open | number | Today's open price |
high | number | Today's high |
low | number | Today's low |
volume | number | Today's volume |
report object:
| Field | Type | Description |
|---|---|---|
mode | string | Trading mode: green, yellow, yellow-improving, yellow-deteriorating, red |
modeLabel | string | Human-readable mode label (e.g. "YELLOW (Improving)") |
modeRationale | string | One-line explanation for the mode |
tiers | object | 4-tier signal breakdown: tier1Regime, tier2Trend, tier3Timing, tier4Flow (each green/yellow/red) |
dashboard | object | One-line signal summaries: regime, trend, timing, flow |
narrative | object | headline, story, keyWatch, invalidation |
positioning | object | stance, stanceRationale, dailyCapPercent, dailyCapRationale, perTradeGuidance |
alertLevels | array | Price levels sorted descending: price, level, type (trim/breakout/current/nibble/eject), action, tier |
scenarios | object | bull, base, bear — each with probability, trigger, target, action (probabilities sum to 100) |
optionsStatus | string | active, watching, avoid, or no_signal |
gammaRegime | string | positive or negative |
gammaContext | string | Explanation of current gamma environment |
masterEjectLevel | number | Exit-all price level |
upgradeConditions | array | Conditions that would upgrade the mode |
downgradeConditions | array | Conditions that would downgrade the mode |
key_levels object:
| Field | Type | Description |
|---|---|---|
call_wall | number | Highest call OI strike (resistance) |
put_wall | number | Highest put OI strike (support) |
hedge_wall | number | Dealer hedging flip point |
max_pain | number | Minimum total option pain strike |
key_gamma_strike | number | Zero gamma crossing point |
expected_move | object | upper, lower, percent |
days_to_expiration | number | DTE for the expiration used |
timeframe_analysis object (null if unavailable):
| Field | Type | Description |
|---|---|---|
timeframes | array | Per-timeframe technical analysis (Monthly, Weekly, Daily, 4H, 1H) |
alignment | object | Overall alignment status across all timeframes |
Each item in timeframes:
| Field | Type | Description |
|---|---|---|
timeframe | string | Label (e.g. "Monthly", "Weekly", "Daily", "4H", "1H") |
interval | string | Interval type for lookups |
bx_trender | object | BX Trender momentum: trend, signal ("buy"/"sell"/null), oscillator |
rsi | object | RSI: value (0-100 or null), status ("overbought"/"oversold"/"neutral") |
smi | object | SMI: value, signal, crossover ("bullish_cross"/"bearish_cross"/"none"), zone ("above_zero"/"below_zero") |
structure | object | Market structure: pattern (description), trend ("bullish"/"bearish"/"neutral") |
ema | object | EMA analysis: status ("above"/"below"/"between"), description |
verdict | object | Overall verdict: bias ("bullish"/"bearish"/"neutral"), strength ("strong"/"moderate"/"weak") |
alignment object:
| Field | Type | Description |
|---|---|---|
isAligned | boolean | Whether all timeframes agree |
bias | string | Overall bias: "bullish", "bearish", "mixed", or "neutral" |
bullishCount | number | Number of bullish timeframes |
bearishCount | number | Number of bearish timeframes |
summary | string | Human-readable alignment summary |
Example response (truncated):
{
"symbol": "SPY",
"price": {
"current": 598.23,
"change": 2.15,
"change_percent": 0.36,
"previous_close": 596.08,
"open": 596.50,
"high": 599.00,
"low": 595.80,
"volume": 45230000
},
"expiration": "2026-02-21",
"report": {
"mode": "yellow-improving",
"modeLabel": "YELLOW (Improving)",
"modeRationale": "Daily leading weekly recovery, but weekly trend still red.",
"narrative": {
"headline": "Gamma flip at $600 is the key pivot today.",
"story": "Price is consolidating just below the key gamma strike...",
"keyWatch": "$600 gamma strike",
"invalidation": "Close below $593"
},
"scenarios": {
"bull": { "probability": 30, "trigger": "Break above $600", "target": "$605", "action": "Add to longs" },
"base": { "probability": 50, "trigger": "Chop $595-600", "target": "$597.50", "action": "Hold" },
"bear": { "probability": 20, "trigger": "Lose $593", "target": "$588", "action": "Cut longs" }
},
"alertLevels": [
{ "price": 605, "level": "Call Wall", "type": "trim", "action": "Take 50% off", "tier": "T1" }
]
},
"key_levels": {
"call_wall": 605.00,
"put_wall": 593.00,
"hedge_wall": 597.00,
"max_pain": 597.00,
"key_gamma_strike": 600.00,
"expected_move": { "upper": 604.50, "lower": 591.50, "percent": 1.08 },
"days_to_expiration": 5
},
"timeframe_analysis": {
"timeframes": [
{
"timeframe": "Daily",
"interval": "daily",
"bx_trender": { "trend": "bullish", "signal": "buy", "oscillator": 1.23 },
"rsi": { "value": 55.2, "status": "neutral" },
"smi": { "value": 12.5, "signal": 8.3, "crossover": "bullish_cross", "zone": "above_zero" },
"structure": { "pattern": "Higher Highs / Higher Lows", "trend": "bullish" },
"ema": { "status": "above", "description": "Price above 8/21/55 EMA" },
"verdict": { "bias": "bullish", "strength": "moderate" }
}
],
"alignment": {
"isAligned": false,
"bias": "mixed",
"bullishCount": 3,
"bearishCount": 2,
"summary": "3/5 timeframes bullish"
}
},
"formatted_text": "$SPY ▫️ $598.23 (+0.36%)\n🟡 YELLOW (Improving)\n\nGamma flip at $600 is the key pivot today.\n...",
"timestamp": "2026-02-14T19:00:00.000Z"
}
Error Responses
All endpoints return errors in a consistent format:
{
"error": "ERROR_CODE",
"message": "Human-readable description of the error."
}
| Status | Error Code | Description |
|---|---|---|
| 400 | MISSING_PARAMETER | Required parameter not provided |
| 400 | INVALID_PARAMETER | Parameter value is invalid |
| 401 | UNAUTHORIZED | Missing or invalid API key |
| 403 | FORBIDDEN | API key is valid but tier is insufficient (FREE tier) |
| 404 | SYMBOL_NOT_FOUND | Symbol does not exist or has no options data |
| 404 | NO_DATA | No data available for the given parameters |
| 429 | RATE_LIMITED | Rate limit exceeded — wait and retry |
| 502 | UPSTREAM_ERROR | Gateway or data provider error |
| 502 | AI_PARSE_ERROR | AI returned an unparseable response (retry) |
| 503 | SERVICE_UNAVAILABLE | AI service is not configured |
Quick Start
- Generate an API key from your Account Settings page (requires PRO tier)
- Test connectivity with the status endpoint:
curl -H "X-API-Key: tvk_YOUR_KEY" https://thetavantage.com/api/v1/status
- Fetch GEX data for any symbol:
curl -H "X-API-Key: tvk_YOUR_KEY" \
"https://thetavantage.com/api/v1/gex?symbol=SPY"
- Get key levels for trading decisions:
curl -H "X-API-Key: tvk_YOUR_KEY" \
"https://thetavantage.com/api/v1/key-levels?symbol=AAPL"
- Build a heatmap with the grid endpoint:
curl -H "X-API-Key: tvk_YOUR_KEY" \
"https://thetavantage.com/api/v1/heatmap?symbol=QQQ&greek=gamma&range=0.05"
- Generate a daily report with AI analysis:
curl -H "X-API-Key: tvk_YOUR_KEY" \
"https://thetavantage.com/api/v1/report?symbol=SPY"
All responses include a
timestampfield in ISO 8601 format. Data is live during market hours and cached briefly outside trading sessions.
Use Cases & Integrations
The Theta Vantage API returns standard JSON over HTTPS, making it easy to integrate with any language, framework, or platform.
🤖 AI Agents & LLM Tools
Feed real-time Greek exposure and key level data directly into AI agent frameworks:
- OpenClaw — Register Theta Vantage endpoints as tools for autonomous trading agents. Give your agent real-time GEX, key levels, and gamma profile data to make informed decisions.
- LangChain / LangGraph — Build custom tools that call the API and return structured market data to your LLM chains. Example: a tool that fetches key levels and gamma environment before generating a trade thesis.
- CrewAI — Equip your market analyst agents with live Greek exposure data. A "Risk Analyst" agent can monitor gamma profile shifts while a "Strategist" agent acts on key level changes.
- OpenAI Function Calling / GPTs — Define API endpoints as functions for ChatGPT or custom GPTs to call. Users can ask natural language questions like "What's the GEX picture for SPY right now?" and get live data.
- Claude MCP (Model Context Protocol) — Expose Theta Vantage endpoints as MCP tools so Claude can fetch live options analytics during conversations.
Example: OpenClaw tool definition
@tool("get_gamma_exposure")
def get_gex(symbol: str) -> dict:
"""Fetch real-time gamma exposure data for a stock symbol."""
response = requests.get(
f"https://thetavantage.com/api/v1/gex?symbol={symbol}",
headers={"X-API-Key": os.environ["TV_API_KEY"]}
)
return response.json()
📊 Custom Dashboards & Alerts
- Grafana / Datadog — Poll endpoints on a schedule and visualize GEX trends, key level movements, and gamma profile shifts over time.
- Google Sheets / Excel — Use
IMPORTDATAor Power Query to pull key levels and max pain into spreadsheets for tracking. - Discord / Slack Bots — Post daily key levels or gamma environment alerts to your trading channels.
- Retool / Streamlit — Build internal tools that display heatmaps and exposure data alongside your portfolio.
🔧 Trading Systems
- Algorithmic Trading — Use gamma profile and key levels to set dynamic support/resistance zones for entries and exits.
- Risk Management — Monitor GEX and VEX shifts to adjust position sizing based on dealer hedging pressure.
- Backtesting — Pull current Greek data to compare against historical patterns and validate strategies.
Tip: The
/api/v1/gamma-profileendpoint'sgamma_environmentfield tells you whether the market is in a positive or negative gamma regime — a key signal for volatility expectations.