Optionomics API Reference

Optionomics API · v1

Build on the data behind the terminal.

Everything Optionomics records and derives, over plain JSON: the options chain with Greeks and dealer positioning, session flow rankings, dark pool levels, insider and Congressional trading, market-moving events, a scored news feed, and the trade-idea research layer with its public track record.

30 documented endpoints
15 yrs of options history
1000/min rate limit, headers included
JSON no SDK required

Base URL https://optionomics.ai — the API is served from the same origin as the product, over HTTPS only.

Authentication

Every request (except the public track record) authenticates with two headers: X-USER-EMAIL, the email on your account, and X-USER-TOKEN, an API key that account issued. The pair must match — a token presented against someone else's email is refused.

Create and revoke keys under the developer console. A key is shown once, at creation; store it in a secret manager, not in code. Keys can be issued with an expiry — an expired key stops authenticating — and each key records when it was last used, so a leaked key is visible and individually revocable.

Authorization: Bearer <token> is also accepted, without the email header, if your HTTP client prefers standard bearer auth.

API access is part of the Vega plan — every endpoint below except the public track record requires it, and each carries its badge.

Your first request
curl "https://optionomics.ai/api/v1/stocks/SPY/metrics" \
  -H "X-USER-EMAIL: [email protected]" \
  -H "X-USER-TOKEN: $OPTIONOMICS_API_KEY"

Playground

Every endpoint on this page can be sent from this page. Each one carries a Try it bar with its parameters already filled in from the example beside it — press Send and the answer, its status, its timing and your remaining allowance appear underneath.

first: everything except the public track record needs a key, and the playground will not send a request it knows will answer 401. Signed in on the Vega plan, a key is one click; otherwise paste one you already hold. Either way it is kept in this browser tab and nowhere else — not in a cookie, not on our side, and gone when the tab closes.

The request is your browser's own, straight at /api/v1 on this origin, with the two headers documented above and no session cookie. Nothing proxies it and nothing rewrites it, so what you see is what your own client will get — including the rate limit, which these requests spend from the same 1,000 a minute your keys do.

Edit a parameter and the cURL, Python and JavaScript blocks above the bar follow it. The snippet you copy is the request you just watched work.

What the browser sends
GET /api/v1/stocks/NVDA/metrics?date=2026-08-05
X-USER-EMAIL: [email protected]
X-USER-TOKEN: ••••••••••••••••

HTTP/2 200
x-ratelimit-remaining: 998
{"symbol": "NVDA", "date": "2026-08-05", …}

Rate limits

Each account may make 1,000 requests per minute across all endpoints. Every authenticated response reports where you stand, and a request past the ceiling answers 429 with a Retry-After header — back off for exactly that long and continue.

X-RateLimit-Limit Your per-minute ceiling.
X-RateLimit-Remaining Requests left in the current window.
X-RateLimit-Reset When the window resets — Unix seconds, UTC.
Retry-After On 429 only: seconds until you may retry.
Rate limit headers
HTTP/2 200
content-type: application/json
x-ratelimit-limit: 1000
x-ratelimit-remaining: 987
x-ratelimit-reset: 1786552260

HTTP/2 429
retry-after: 22
{"error": "Rate limit exceeded. Retry after 22 seconds.", "retry_after": 22}

Errors

Errors are JSON with a human-readable error message, plus per-field details where validation failed. Two statuses are deliberately distinct: 402 means no active subscription (subscribe), 403 means your plan does not include the feature (upgrade) — clients can branch on the code to send readers to the right screen.

400A required parameter is missing.
401Missing or invalid credentials.
402No active subscription.
403Plan does not include this feature.
404 No such resource — unknown symbols answer this.
422 A filter or parameter value nobody offers. The API refuses rather than silently ignoring, so a broken filter is a loud bug, not quiet wrong data.
429Rate limit exceeded.
500Something failed on our side.
Error body
{
  "error": "Invalid period"
}

{
  "error": "Unprocessable entity",
  "details": {"body": ["can't be blank"]}
}

Pagination

List endpoints page with page and per_page, and answer a pagination envelope naming the current page, the page size, and the total. Page caps are documented per endpoint; a page beyond the cap answers 422 rather than quietly serving page one — a silently reset cursor sends infinite scrolls in circles.

Pagination envelope
{
  "articles": ["…"],
  "pagination": {
    "current_page": 2,
    "per_page": 25,
    "total_count": 214,
    "total_pages": 9
  }
}

Data freshness

The API serves recorded and derived data on an ingestion cadence — flow rankings minutes behind the tape, chains and metrics per session, disclosures as the official sources publish. It is built for research, screening and analytics, not as a real-time quote or execution feed, and no endpoint here streams.

Where freshness matters the payload says so: disclosure rows carry their full pipeline lifecycle, events record when they became known, and feeds that resolve a date tell you which session actually answered.

Timestamps are ISO 8601 in UTC unless marked otherwise; epoch fields are noted per endpoint. Market-schedule semantics (session dates, before/after the bell) follow US Eastern time.

Reading timestamps
"published_at": "2026-08-05T13:42:10.000000Z"   // UTC instant
"date": "2026-08-05"                            // ET trading session
"timestamp": 1786550340000                      // epoch milliseconds
"timing": "after_close"                         // derived server-side

Market data

The symbol universe Optionomics tracks, and everything recorded per symbol and session: quotes, the full options chain with Greeks and exposures, daily candles, and more than seventy derived volatility and positioning metrics.

Data is ingested on a session cadence. Quotes and chains reflect the most recent completed ingestion for the requested session — this is research and analytics data, not a streaming market-data feed.

List tickers

GET /api/v1/tickers Vega plan

The smallest possible universe payload: bare symbols, for autocompletes and membership checks. Cached server-side for an hour — listings and delistings are at most a daily event.

When you also need company names and instrument types, use List stocks instead.

Response body

Field Type Description
tickers array of string Every tracked symbol, A→Z.

Errors

401 Missing or invalid API credentials.
GET /api/v1/tickers
curl "https://optionomics.ai/api/v1/tickers" \
  -H "X-USER-EMAIL: [email protected]" \
  -H "X-USER-TOKEN: $OPTIONOMICS_API_KEY"
Try it
Response example
{
  "tickers": ["AAPL", "AMD", "AMZN", "IWM", "MSFT", "NFLX", "NVDA", "QQQ", "SPY", "TSLA"]
}

List stocks

GET /api/v1/stocks Vega plan

The same universe as List tickers, carrying what a picker renders: the company name and the instrument type. Cached server-side for an hour.

Response body

Field Type Description
stocks array of object Tracked instruments, A→Z.
stocks[].symbol string Ticker symbol.
stocks[].name string Company or fund name.
stocks[].type string Instrument type — a common stock, an ETF, an index.

Errors

401 Missing or invalid API credentials.
GET /api/v1/stocks
curl "https://optionomics.ai/api/v1/stocks" \
  -H "X-USER-EMAIL: [email protected]" \
  -H "X-USER-TOKEN: $OPTIONOMICS_API_KEY"
Try it
Response example
{
  "stocks": [
    {"symbol": "AAPL", "name": "Apple Inc.", "type": "stock"},
    {"symbol": "SPY", "name": "SPDR S&P 500 ETF Trust", "type": "etf"}
  ]
}

Get a quote

GET /api/v1/stocks/{symbol}/quote Vega plan

The recorded quote for a trading session: OHLC, last, volume, and the change against the previous close. A session with no recorded quote answers quote: null — an explicit null, never an omitted key or an empty array — so a typed client can decode "nothing yet" cleanly.

regime is the market-behaviour classification the symbol is currently in (trend, range, volatility expansion, …) with the model's confidence. It describes the live session, so it rides along regardless of the date you ask about, and is null when no classification exists.

Parameters

Name Type Description
symbol path required string Ticker symbol. Unknown symbols answer 404.
date date (YYYY-MM-DD) The session to read. An unparseable value falls back to today (US Eastern). Default: today (US Eastern)

Response body

Field Type Description
symbol string The symbol echoed back.
date date The session the quote describes.
quote object | null last, open, high, low, previous_close, change, change_percent, volume. Null when the session has no recorded quote.
regime object | null The live regime classification: `regime` (string) and `confidence` (0–100).

Errors

401 Missing or invalid API credentials.
404 No such symbol.
GET /api/v1/stocks/{symbol}/quote
curl "https://optionomics.ai/api/v1/stocks/SPY/quote" \
  -H "X-USER-EMAIL: [email protected]" \
  -H "X-USER-TOKEN: $OPTIONOMICS_API_KEY"
Try it
Response example
{
  "symbol": "SPY",
  "date": "2026-08-05",
  "quote": {
    "last": 632.25,
    "open": 629.8,
    "high": 634.1,
    "low": 628.4,
    "previous_close": 630.51,
    "change": 1.74,
    "change_percent": 0.28,
    "volume": 41250000
  },
  "regime": {"regime": "trend_up", "confidence": 82}
}

Get the options chain

GET /api/v1/stocks/{symbol}/options Vega plan

The full recorded chain for a session, ordered by expiration then strike: pricing, sizes, volume and open interest, the Greeks, and the derived exposure figures (dollar gamma, delta and gamma exposure, notional OI).

Numeric analytics ship as strings — "strike": "315.0" — which is the shape this endpoint has always had and shipped clients parse. Integer counts (volume, open interest, sizes, dte) are JSON numbers.

iv_per_trading_day is the one-session standard-deviation equivalent of annualized IV (IV ÷ √252). The older iv_per_day field is retained for compatibility and is deprecated — do not build on it.

Parameters

Name Type Description
symbol path required string Ticker symbol. Unknown symbols answer 404.
date date (YYYY-MM-DD) The session's chain to read. Default: today (US Eastern)

Response body

Field Type Description
symbol string The symbol echoed back.
date date The session the chain describes.
underlying_price string | null Spot recorded on the chain; null when the session has no contracts.
options array of object The contracts, by expiration then strike.
options[].symbol string OCC contract symbol — {STOCK}{YYMMDD}{C/P}{STRIKE×1000}.
options[].type string "call" or "put".
options[].expiration_date date Contract expiration.
options[].strike / price / bid / ask string Pricing, as strings.
options[].delta / gamma / theta / vega / rho / theo string | null Greeks as recorded on the chain snapshot; theo is a theoretical price where one was computed, and null on most rows.
options[].implied_volatility string Annualized IV as a decimal — "0.993" is 99.3%.
options[].volume / open_interest / bid_size / ask_size / dte integer Counts, as JSON numbers.
options[].gamma_dollar / delta_exposure / gamma_exposure / notional_oi string Derived dollar exposures per contract.
options[].moneyness string Percent in (positive) or out (negative) of the money.
options[].iv_per_trading_day string | null One-session σ equivalent of annualized IV (IV ÷ √252).

Errors

401 Missing or invalid API credentials.
404 No such symbol.
GET /api/v1/stocks/{symbol}/options
curl "https://optionomics.ai/api/v1/stocks/SPY/options" \
  -H "X-USER-EMAIL: [email protected]" \
  -H "X-USER-TOKEN: $OPTIONOMICS_API_KEY"
Try it
Response example
{
  "symbol": "SPY",
  "date": "2026-08-05",
  "underlying_price": "632.25",
  "options": [
    {
      "symbol": "SPY260805C00630000",
      "type": "call",
      "expiration_date": "2026-08-05",
      "strike": "630.0",
      "price": "2.61",
      "bid": "2.59",
      "ask": "2.63",
      "bid_size": 120,
      "ask_size": 95,
      "volume": 18240,
      "open_interest": 9481,
      "dte": 0,
      "implied_volatility": "0.142",
      "delta": "0.61",
      "gamma": "0.081",
      "theta": "-0.92",
      "vega": "0.11",
      "rho": "0.01",
      "theo": null,
      "moneyness": "0.36",
      "gamma_dollar": "323.6",
      "delta_exposure": "578341.0",
      "gamma_exposure": "3067752.4",
      "notional_oi": "597303000.0",
      "iv_per_day": "0.142",
      "iv_per_trading_day": "0.008945"
    }
  ]
}

Get price history

GET /api/v1/stocks/{symbol}/price_history Vega plan

Daily OHLCV bars ending at the requested session, oldest first so a chart plots left to right without sorting. Sixty sessions are found inside a 120-calendar-day window, so holidays and halts never shorten the answer.

regime_markers annotates the bars where the symbol's detected market regime changed — each marker carries the axis position, a label like "Trend Up 85%", and a hex color, ready to draw.

Parameters

Name Type Description
symbol path required string Ticker symbol. Unknown symbols answer 404.
date date (YYYY-MM-DD) The window's last session. Default: today (US Eastern)

Response body

Field Type Description
symbol string The symbol echoed back.
candles array of object Up to 60 bars, oldest first: date, open, high, low, close, volume.
regime_markers array of object Regime transitions on charted days: date, time (epoch ms, midnight ET), x_axis_key, x_axis_index, regime, confidence, label, color.

Errors

401 Missing or invalid API credentials.
404 No such symbol.
GET /api/v1/stocks/{symbol}/price_history
curl "https://optionomics.ai/api/v1/stocks/NVDA/price_history" \
  -H "X-USER-EMAIL: [email protected]" \
  -H "X-USER-TOKEN: $OPTIONOMICS_API_KEY"
Try it
Response example
{
  "symbol": "NVDA",
  "candles": [
    {"date": "2026-05-12", "open": 121.4, "high": 124.9, "low": 120.8, "close": 124.1, "volume": 182000000},
    {"date": "2026-05-13", "open": 124.3, "high": 126.2, "low": 123.5, "close": 125.7, "volume": 164000000}
  ],
  "regime_markers": [
    {
      "date": "2026-05-13",
      "time": 1778990400000,
      "x_axis_key": "2026-05-13",
      "x_axis_index": 1,
      "regime": "trend_up",
      "confidence": 85,
      "label": "Trend Up 85%",
      "color": "#22c55e"
    }
  ]
}

Get metrics

GET /api/v1/stocks/{symbol}/metrics Vega plan

Everything the analytics pipeline derives from a session's chain, in one object: volume, open interest and premium split by side; put/call ratios across five bases; the IV surface (rank, percentile, term structure, skew, wings); realized vol and the IV−RV premium; dealer positioning (total GEX, gamma flip strike, call and put walls, DDE); the expected move; and max-pain analytics.

A session with no recorded chain answers "metrics": [] with underlying_price: null under HTTP 200 — an empty list, deliberately, because that is the published shape clients already decode.

A small set of legacy keys is always null (they are retained for compatibility with the original payload): vrp_20, price_vs_expected_move, max_pain_accuracy, breakout_probability, iv_vs_historical, historical_move_accuracy, unusual_oi_change, iv_momentum, retail_trade_confidence_score, delta_hedged_carry, strangle_edge_1m.

Parameters

Name Type Description
symbol path required string Ticker symbol. Unknown symbols answer 404.
date date (YYYY-MM-DD) The session to read. Default: today (US Eastern)

Response body

Field Type Description
symbol string The symbol echoed back.
date date The session the metrics describe.
underlying_price number | null Spot recorded on the chain.
metrics object | [] The metric map — or an empty array when the session has no chain. Highlights below; the example carries a representative subset.
metrics.pcr_volume / pcr_open_interest / pcr_premium / pcr_gamma_exposure / pcr_delta_exposure number Put/call ratios on five bases.
metrics.iv_rank / iv_percentile / atm_iv / iv30 / iv60 / iv90 number The IV surface and its history-relative position.
metrics.rv5 / rv10 / rv20 / rv30 / rv60 / iv_minus_rv20 number Realized volatility windows and the IV−RV premium.
metrics.total_gex / gamma_flip_strike / call_wall / put_wall / total_dde number Dealer positioning. total_gex is 0, never null, when exposures have not run.
metrics.straddle_px / expected_move_pct / expected_move_upper / expected_move_lower number The ATM straddle and the expected move it implies.
metrics.max_pain_strike / max_pain_distance / pain_zone_strength / max_pain_sentiment number | string Max-pain analytics.

Errors

401 Missing or invalid API credentials.
404 No such symbol.
GET /api/v1/stocks/{symbol}/metrics
curl "https://optionomics.ai/api/v1/stocks/SPY/metrics" \
  -H "X-USER-EMAIL: [email protected]" \
  -H "X-USER-TOKEN: $OPTIONOMICS_API_KEY"
Try it
Response example
{
  "symbol": "SPY",
  "date": "2026-08-05",
  "underlying_price": 632.25,
  "metrics": {
    "call_volume": 2841520,
    "put_volume": 2456013,
    "pcr_volume": 0.864,
    "pcr_open_interest": 1.12,
    "atm_iv": 0.138,
    "iv_rank": 0.31,
    "iv_percentile": 42.5,
    "rv20": 0.11,
    "iv_minus_rv20": 0.028,
    "total_gex": 1845000000.0,
    "gamma_flip_strike": 618.0,
    "call_wall": 640.0,
    "put_wall": 620.0,
    "straddle_px": 7.42,
    "expected_move_pct": 1.17,
    "max_pain_strike": 628.0,
    "vrp_20": null
  }
}

Get the exposure heatmap

GET /api/v1/stocks/{symbol}/heatmap Vega plan

The chain's exposure surface, shaped for plotting: a thirty-strike window chosen around spot, the expirations on the other axis, and one cell per strike-expiration pair that has exposure. Empty cells are omitted, so the strikes and expirations axes ship alongside the cells — the grid's shape is not reconstructible from the cells alone.

Three metrics are served: gamma, vanna and charm exposure. An unrecognised metric falls back to gamma rather than erroring.

Without a date, the latest recorded chain for the symbol is used — not the latest calendar day — so a client polling without parameters always gets the newest grid.

Parameters

Name Type Description
symbol path required string Ticker symbol. Unknown symbols answer 404 with an error body.
metric string gamma_exposure, vanna_exposure or charm_exposure. Anything else is read as gamma_exposure. Default: gamma_exposure
date date (YYYY-MM-DD) The session's chain to grid. Default: latest recorded chain

Response body

Field Type Description
symbol string The symbol echoed back.
date date The chain's session.
metric string The metric actually served.
current_price number Spot recorded on the chain.
closest_strike number The strike nearest spot — what a table scrolls to.
strikes array of number The grid's strike axis.
expirations array of date The grid's expiration axis.
cells array of object Sparse, strike-major: strike, expiration, value. Pairs with no exposure are absent.

Errors

401 Missing or invalid API credentials.
404 Unknown symbol (JSON error body), or no recorded chain (empty body).
GET /api/v1/stocks/{symbol}/heatmap
curl "https://optionomics.ai/api/v1/stocks/SPY/heatmap?metric=gamma_exposure" \
  -H "X-USER-EMAIL: [email protected]" \
  -H "X-USER-TOKEN: $OPTIONOMICS_API_KEY"
Try it
Response example
{
  "symbol": "SPY",
  "date": "2026-08-05",
  "metric": "gamma_exposure",
  "current_price": 632.25,
  "closest_strike": 632.0,
  "strikes": [620.0, 625.0, 630.0, 632.0, 635.0, 640.0],
  "expirations": ["2026-08-05", "2026-08-07", "2026-08-21"],
  "cells": [
    {"strike": 630.0, "expiration": "2026-08-05", "value": 184250000.0},
    {"strike": 632.0, "expiration": "2026-08-05", "value": 96020000.0}
  ]
}

Options flow

How the session's options premium actually traded: leaderboards of net bullish and bearish positioning, the largest call and put premium by symbol, one symbol's cumulative net flow through a window, and the support and resistance levels derived from the chain and from off-exchange prints.

Rankings are computed from the recorded tape for a trading session and cached briefly server-side. They describe the session as ingested — they are not a live stream.

All flow rankings

GET /api/v1/flow/aggregates Vega plan

Bullish, bearish, top calls and top puts together — one request where a dashboard would otherwise make four. The four are slices of one computation server-side, so this costs no more than any single ranking.

Each row is a symbol with its trade count and total premium in dollars.

Parameters

Name Type Description
date date (YYYY-MM-DD) The session to rank. An unparseable value falls back to the latest session rather than erroring — this endpoint is polled by widgets. Default: latest session
limit integer Rows per ranking, capped at 100. Default: server default

Response body

Field Type Description
bullish_flow / bearish_flow / top_calls / top_puts array of object Each an array of {symbol, trade_count, total_premium}.

Errors

401 Missing or invalid API credentials.
GET /api/v1/flow/aggregates
curl "https://optionomics.ai/api/v1/flow/aggregates?limit=10" \
  -H "X-USER-EMAIL: [email protected]" \
  -H "X-USER-TOKEN: $OPTIONOMICS_API_KEY"
Try it
Response example
{
  "bullish_flow": [
    {"symbol": "NVDA", "trade_count": 1204, "total_premium": 48211000.5},
    {"symbol": "AAPL", "trade_count": 861, "total_premium": 21830420.0}
  ],
  "bearish_flow": [
    {"symbol": "TSLA", "trade_count": 954, "total_premium": 30125800.0}
  ],
  "top_calls": [
    {"symbol": "NVDA", "trade_count": 2210, "total_premium": 61240000.0}
  ],
  "top_puts": [
    {"symbol": "SPY", "trade_count": 3105, "total_premium": 55018200.0}
  ]
}

Top bullish flow

GET /api/v1/flow/bullish Vega plan

One ranking on its own, for a widget that renders a single list. The response is a bare JSON array of rows — no envelope.

The same rows appear under the corresponding key of All flow rankings.

Parameters

Name Type Description
date date (YYYY-MM-DD) The session to rank. Unparseable values fall back to the latest session. Default: latest session
limit integer Rows returned, capped at 100. Default: server default

Response body

Field Type Description
[].symbol string Ticker symbol.
[].trade_count integer Number of qualifying trades behind the row.
[].total_premium number Premium in dollars, signed by the ranking's direction.

Errors

401 Missing or invalid API credentials.
GET /api/v1/flow/bullish
curl "https://optionomics.ai/api/v1/flow/bullish?limit=10" \
  -H "X-USER-EMAIL: [email protected]" \
  -H "X-USER-TOKEN: $OPTIONOMICS_API_KEY"
Try it
Response example
[
  {"symbol": "NVDA", "trade_count": 1204, "total_premium": 48211000.5},
  {"symbol": "AAPL", "trade_count": 861, "total_premium": 21830420.0}
]

Top bearish flow

GET /api/v1/flow/bearish Vega plan

One ranking on its own, for a widget that renders a single list. The response is a bare JSON array of rows — no envelope.

The same rows appear under the corresponding key of All flow rankings.

Parameters

Name Type Description
date date (YYYY-MM-DD) The session to rank. Unparseable values fall back to the latest session. Default: latest session
limit integer Rows returned, capped at 100. Default: server default

Response body

Field Type Description
[].symbol string Ticker symbol.
[].trade_count integer Number of qualifying trades behind the row.
[].total_premium number Premium in dollars, signed by the ranking's direction.

Errors

401 Missing or invalid API credentials.
GET /api/v1/flow/bearish
curl "https://optionomics.ai/api/v1/flow/bearish?limit=10" \
  -H "X-USER-EMAIL: [email protected]" \
  -H "X-USER-TOKEN: $OPTIONOMICS_API_KEY"
Try it
Response example
[
  {"symbol": "NVDA", "trade_count": 1204, "total_premium": 48211000.5},
  {"symbol": "AAPL", "trade_count": 861, "total_premium": 21830420.0}
]

Top call premium

GET /api/v1/flow/top_calls Vega plan

One ranking on its own, for a widget that renders a single list. The response is a bare JSON array of rows — no envelope.

The same rows appear under the corresponding key of All flow rankings.

Parameters

Name Type Description
date date (YYYY-MM-DD) The session to rank. Unparseable values fall back to the latest session. Default: latest session
limit integer Rows returned, capped at 100. Default: server default

Response body

Field Type Description
[].symbol string Ticker symbol.
[].trade_count integer Number of qualifying trades behind the row.
[].total_premium number Premium in dollars, signed by the ranking's direction.

Errors

401 Missing or invalid API credentials.
GET /api/v1/flow/top_calls
curl "https://optionomics.ai/api/v1/flow/top_calls?limit=10" \
  -H "X-USER-EMAIL: [email protected]" \
  -H "X-USER-TOKEN: $OPTIONOMICS_API_KEY"
Try it
Response example
[
  {"symbol": "NVDA", "trade_count": 1204, "total_premium": 48211000.5},
  {"symbol": "AAPL", "trade_count": 861, "total_premium": 21830420.0}
]

Top put premium

GET /api/v1/flow/top_puts Vega plan

One ranking on its own, for a widget that renders a single list. The response is a bare JSON array of rows — no envelope.

The same rows appear under the corresponding key of All flow rankings.

Parameters

Name Type Description
date date (YYYY-MM-DD) The session to rank. Unparseable values fall back to the latest session. Default: latest session
limit integer Rows returned, capped at 100. Default: server default

Response body

Field Type Description
[].symbol string Ticker symbol.
[].trade_count integer Number of qualifying trades behind the row.
[].total_premium number Premium in dollars, signed by the ranking's direction.

Errors

401 Missing or invalid API credentials.
GET /api/v1/flow/top_puts
curl "https://optionomics.ai/api/v1/flow/top_puts?limit=10" \
  -H "X-USER-EMAIL: [email protected]" \
  -H "X-USER-TOKEN: $OPTIONOMICS_API_KEY"
Try it
Response example
[
  {"symbol": "NVDA", "trade_count": 1204, "total_premium": 48211000.5},
  {"symbol": "AAPL", "trade_count": 861, "total_premium": 21830420.0}
]

Net flow for a symbol

GET /api/v1/flow/net Vega plan

Two cumulative time series — net call premium and net put premium — bucketed at the requested resolution. This is the series behind the net-flow chart: each point is the running total through the window, so the last point is the window's net figure.

symbol is required; there is no sensible default for a series about one ticker, and the endpoint answers 400 without one.

Parameters

Name Type Description
symbol required string Ticker symbol. Absent or blank answers 400.
from integer (Unix seconds) Window start. Resolved to its Eastern market date. Default: 30 days back
to integer (Unix seconds) Window end. Resolved to its Eastern market date. Default: today
resolution string Bucket size for the series, e.g. 5m. Default: server default
dte_min integer Only trades in contracts with at least this many days to expiry.
dte_max integer Only trades in contracts with at most this many days to expiry.

Response body

Field Type Description
net_calls array of object Cumulative call premium: {time, value}. time is epoch milliseconds (UTC), value is dollars.
net_puts array of object Cumulative put premium, same shape. Typically negative.

Errors

400 Symbol required.
401 Missing or invalid API credentials.
GET /api/v1/flow/net
curl "https://optionomics.ai/api/v1/flow/net?symbol=SPY" \
  -H "X-USER-EMAIL: [email protected]" \
  -H "X-USER-TOKEN: $OPTIONOMICS_API_KEY"
Try it
Response example
{
  "net_calls": [
    {"time": 1786551000000, "value": 1250000.5},
    {"time": 1786551300000, "value": 1431200.0}
  ],
  "net_puts": [
    {"time": 1786551000000, "value": -730500.0},
    {"time": 1786551300000, "value": -692100.0}
  ]
}

Get flow levels

GET /api/v1/levels Vega plan

Price levels where options positioning concentrates — premium walls, gamma shelves — classified as support, resistance or pivot, each with a 0–100 strength score and a human-readable label naming its source.

Without a symbol the endpoint answers for SPY, the long-standing default. Recomputed on a one-minute cadence at most; responses are cached for sixty seconds.

Parameters

Name Type Description
symbol string Ticker symbol. Default: SPY

Response body

Field Type Description
symbol string The symbol echoed back.
current_price number The reference spot.
levels array of object {price, type, strength, label}; type is support, resistance or pivot.

Errors

401 Missing or invalid API credentials.
404 No such symbol, or no recent price to anchor the levels to.
GET /api/v1/levels
curl "https://optionomics.ai/api/v1/levels?symbol=SPY" \
  -H "X-USER-EMAIL: [email protected]" \
  -H "X-USER-TOKEN: $OPTIONOMICS_API_KEY"
Try it
Response example
{
  "symbol": "SPY",
  "current_price": 632.25,
  "levels": [
    {"price": 630.0, "type": "support", "strength": 85, "label": "PUT Premium $2.1M"},
    {"price": 640.0, "type": "resistance", "strength": 78, "label": "CALL Premium $1.8M"}
  ]
}

Get dark pool levels

GET /api/v1/dark_pool_levels Vega plan

The same shape as flow levels, from a different tape: price levels where off-exchange (dark pool) volume concentrates. Where repeated size prints at a price, that price tends to act as a shelf.

Same default (SPY), same sixty-second cache, same error behaviour.

Parameters

Name Type Description
symbol string Ticker symbol. Default: SPY

Response body

Field Type Description
symbol string The symbol echoed back.
current_price number The reference spot.
levels array of object {price, type, strength, label}.

Errors

401 Missing or invalid API credentials.
404 No such symbol, or no recent price to anchor levels to. A tracked symbol with no qualifying prints answers 200 with an empty levels array.
GET /api/v1/dark_pool_levels
curl "https://optionomics.ai/api/v1/dark_pool_levels?symbol=SPY" \
  -H "X-USER-EMAIL: [email protected]" \
  -H "X-USER-TOKEN: $OPTIONOMICS_API_KEY"
Try it
Response example
{
  "symbol": "SPY",
  "current_price": 632.25,
  "levels": [
    {"price": 628.5, "type": "support", "strength": 92, "label": "Dark Pool $48M @ 628.50"}
  ]
}

Insider & Congress trading

Official ownership disclosures, normalized into one queryable feed: corporate insiders' SEC Form 4 filings, and Congressional periodic transaction reports from the House, the Senate and OGE-278 filings.

Every row links back to its official source document and carries its full pipeline lifecycle, so you can audit both what was filed and when this API learned of it. Congressional filings report value bands rather than exact figures — the shape preserves that honestly with value_min and value_max.

List insider trades

GET /api/v1/insider_trades Vega plan

SEC Form 4 filings — officers, directors and 10% owners reporting their own transactions — as a filtered, paged feed, newest filing first by default.

Alongside the rows, stats aggregates the entire filtered feed: totals, the purchase/sale split, estimated value, and the average lag between trade date and filing date.

An unknown filter value is refused with 422 rather than ignored — a client sending period=forever has a bug, and a quietly unfiltered answer would hide it.

Parameters

Name Type Description
period string 30d, 90d, 1y, 3y or all. Default: 1y
transaction_type string purchase, sale, award, exercise, gift, disposition, conversion, expiration or other.
min_value string A value floor: 1000, 15000, 50000, 100000, 500000, 1000000.
symbol string Narrow to one traded ticker. Unknown symbols answer 404.
query string Free-text search over filers and issuers.
sort string filed_desc, traded_desc, value_desc, filer_asc or ticker_asc. Default: filed_desc
page integer 1–20. Beyond the cap answers 422. Default: 1
per_page integer Rows per page, up to 100. Default: 25

Response body

Field Type Description
trades array of object The filings, in the shape described below.
trades[].id uuid Stable row identifier.
trades[].source string The filing feed: sec_form4, house_periodic_transaction, senate_periodic_transaction, oge_278_transaction.
trades[].source_kind string insider or politician.
trades[].ticker / issuer_name / issuer_cik / asset_description string | null What was traded. Political filings sometimes name assets no ticker maps to.
trades[].filer_name / filer_cik / filer_role / filer_title string | null Who filed — the insider's role, or the member's chamber.
trades[].transaction_type string | null purchase, sale, award, exercise, gift, disposition, conversion, expiration or other.
trades[].transaction_date / filed_at date / datetime | null When it traded, and when the filing landed — the gap is the filing lag.
trades[].shares / share_price / value number | null Exact figures where the filing reports them.
trades[].value_min / value_max number | null Congressional filings report value bands, not exact figures; the band's ends land here.
trades[].derivative boolean Whether the filing reports a derivative position.
trades[].shares_owned_following_transaction / acquired_disposed_code / ownership_type / transaction_code / form_type / accession_number / amendment_of_accession_number mixed | null The filing's own bookkeeping, passed through.
trades[].source_url / source_document_url url | null Links to the official source. Only vouched-for official domains are rendered; anything else is null.
trades[].provenance object {filing_form} — which form the row was parsed from.
trades[].lifecycle object The row's pipeline timestamps: source_published_at, source_fetched_at, normalized_at, last_seen_at, reprocessed_at.
stats object Aggregates over the whole filtered feed, not the page.
stats.total_trades / purchases / sales integer Row counts under the current filters.
stats.estimated_value number Total traded value. An estimate: congressional bands count at their midpoint.
stats.average_filing_lag integer | null Mean days between trade and filing, rounded to whole days.
stats.latest_filing_at datetime | null The newest filing under the current filters.
freshness object The newest lifecycle timestamps across the returned rows.
pagination object {current_page, per_page, total_count, total_pages}.

Errors

401 Missing or invalid API credentials.
404 symbol names a ticker nobody tracks.
422 An unknown filter value, a kind param (the URL fixes it), or a page past 20.
GET /api/v1/insider_trades
curl "https://optionomics.ai/api/v1/insider_trades?period=90d&transaction_type=purchase" \
  -H "X-USER-EMAIL: [email protected]" \
  -H "X-USER-TOKEN: $OPTIONOMICS_API_KEY"
Try it
Response example
{
  "trades": [
    {
      "id": "0d7f0e0e-3c9f-4a57-9e5e-1a2b3c4d5e6f",
      "source": "sec_form4",
      "source_kind": "insider",
      "ticker": "NVDA",
      "issuer_name": "NVIDIA Corp",
      "issuer_cik": "0001045810",
      "asset_description": null,
      "filer_name": "Jane Executive",
      "filer_cik": "0009999999",
      "filer_role": "officer",
      "filer_title": "EVP, Operations",
      "form_type": "4",
      "transaction_type": "sale",
      "transaction_code": "S",
      "transaction_date": "2026-08-03",
      "filed_at": "2026-08-04T21:10:12Z",
      "acquired_disposed_code": "D",
      "ownership_type": "D",
      "derivative": false,
      "shares": 12000,
      "share_price": 128.44,
      "value": 1541280.0,
      "value_min": null,
      "value_max": null,
      "shares_owned_following_transaction": 288000,
      "accession_number": "0001045810-26-000123",
      "amendment_of_accession_number": null,
      "source_url": "https://www.sec.gov/Archives/edgar/data/1045810/000104581026000123.xml",
      "source_document_url": "https://www.sec.gov/Archives/edgar/data/1045810/xslF345X05/doc4.xml",
      "provenance": {"filing_form": "4"},
      "lifecycle": {
        "source_published_at": "2026-08-04T21:10:12Z",
        "source_fetched_at": "2026-08-04T21:14:02Z",
        "normalized_at": "2026-08-04T21:14:05Z",
        "last_seen_at": "2026-08-05T02:00:11Z",
        "reprocessed_at": null
      }
    }
  ],
  "stats": {
    "total_trades": 1832,
    "estimated_value": 4821400312.5,
    "purchases": 411,
    "sales": 1298,
    "politician_trades": 0,
    "insider_trades": 1832,
    "average_filing_lag": 2,
    "latest_filing_at": "2026-08-05T21:45:00Z"
  },
  "freshness": {
    "latest_source_published_at": "2026-08-05T21:45:00Z",
    "latest_source_fetched_at": "2026-08-05T21:49:31Z",
    "latest_normalized_at": "2026-08-05T21:49:33Z",
    "latest_last_seen_at": "2026-08-06T02:00:09Z",
    "latest_reprocessed_at": null
  },
  "pagination": {"current_page": 1, "per_page": 25, "total_count": 1832, "total_pages": 74}
}

List Congress trades

GET /api/v1/congress_trades Vega plan

Periodic transaction reports from members of Congress — House, Senate and OGE-278 filings — as the same filtered, paged feed shape as insider trades, including stats over the whole filtered feed.

Congressional filings report value bands: expect value_min and value_max on these rows, with value null unless the filing gave an exact figure. estimated_value in stats counts bands at their midpoint.

state narrows to the filer's state — two-letter postal codes.

Parameters

Name Type Description
period string 30d, 90d, 1y, 3y or all. Default: 1y
transaction_type string purchase, sale, award, exercise, gift, disposition, conversion, expiration or other.
min_value string A value floor: 1000, 15000, 50000, 100000, 500000, 1000000.
symbol string Narrow to one traded ticker. Unknown symbols answer 404.
query string Free-text search over filers and issuers.
sort string filed_desc, traded_desc, value_desc, filer_asc or ticker_asc. Default: filed_desc
page integer 1–20. Beyond the cap answers 422. Default: 1
per_page integer Rows per page, up to 100. Default: 25
state string Two-letter state code, e.g. CA. Malformed values answer 422; a valid code with no filings answers an empty feed.

Response body

Field Type Description
trades array of object The filings — same row shape as insider trades (see above).
stats object Aggregates over the whole filtered feed, not the page.
stats.total_trades / purchases / sales integer Row counts under the current filters.
stats.estimated_value number Total traded value. An estimate: congressional bands count at their midpoint.
stats.average_filing_lag integer | null Mean days between trade and filing, rounded to whole days.
stats.latest_filing_at datetime | null The newest filing under the current filters.
freshness / pagination object As on List insider trades.

Errors

401 Missing or invalid API credentials.
404 symbol names a ticker nobody tracks.
422 An unknown filter value, a malformed state, a kind param, or a page past 20.
GET /api/v1/congress_trades
curl "https://optionomics.ai/api/v1/congress_trades?period=90d" \
  -H "X-USER-EMAIL: [email protected]" \
  -H "X-USER-TOKEN: $OPTIONOMICS_API_KEY"
Try it
Response example
{
  "trades": [
    {
      "id": "7b1f22aa-90c1-45e7-8a3e-55d4c9b2f101",
      "source": "house_periodic_transaction",
      "source_kind": "politician",
      "ticker": "MSFT",
      "issuer_name": "Microsoft Corp",
      "asset_description": "Microsoft Corporation - Common Stock",
      "filer_name": "A. Representative",
      "filer_role": "house",
      "transaction_type": "purchase",
      "transaction_date": "2026-07-21",
      "filed_at": "2026-08-02T14:30:00Z",
      "derivative": false,
      "shares": null,
      "share_price": null,
      "value": null,
      "value_min": 15001,
      "value_max": 50000,
      "source_url": "https://disclosures-clerk.house.gov/...",
      "source_document_url": null,
      "provenance": {"filing_form": "PTR"},
      "lifecycle": {
        "source_published_at": "2026-08-02T14:30:00Z",
        "source_fetched_at": "2026-08-02T15:00:41Z",
        "normalized_at": "2026-08-02T15:00:44Z",
        "last_seen_at": "2026-08-06T02:00:09Z",
        "reprocessed_at": null
      }
    }
  ],
  "stats": {
    "total_trades": 640,
    "estimated_value": 41230500.0,
    "purchases": 302,
    "sales": 289,
    "politician_trades": 640,
    "insider_trades": 0,
    "average_filing_lag": 11,
    "latest_filing_at": "2026-08-05T18:12:00Z"
  },
  "freshness": {
    "latest_source_published_at": "2026-08-05T18:12:00Z",
    "latest_source_fetched_at": "2026-08-05T18:30:12Z",
    "latest_normalized_at": "2026-08-05T18:30:15Z",
    "latest_last_seen_at": "2026-08-06T02:00:09Z",
    "latest_reprocessed_at": null
  },
  "pagination": {"current_page": 1, "per_page": 25, "total_count": 640, "total_pages": 26}
}

List all disclosures

GET /api/v1/disclosure_trades Vega plan

The combined feed both dedicated endpoints draw from, with a kind lens to pick a side: all, insider, politician, or both. Use this when you want one stream across both populations; use the dedicated endpoints when you want stats alongside the rows.

This is the original disclosure endpoint and its response shape is frozen: {trades, freshness, pagination}, no stats.

Parameters

Name Type Description
kind string all, insider, politician or both. Default: all
source string One filing feed: sec_form4, house_periodic_transaction, senate_periodic_transaction or oge_278_transaction. Must belong to the chosen kind.
period string 30d, 90d, 1y, 3y or all. Default: 1y
transaction_type string purchase, sale, award, exercise, gift, disposition, conversion, expiration or other.
min_value string A value floor: 1000, 15000, 50000, 100000, 500000, 1000000.
symbol string Narrow to one traded ticker. Unknown symbols answer 404.
query string Free-text search over filers and issuers.
sort string filed_desc, traded_desc, value_desc, filer_asc or ticker_asc. Default: filed_desc
page integer 1–20. Beyond the cap answers 422. Default: 1
per_page integer Rows per page, up to 100. Default: 25

Response body

Field Type Description
trades array of object The filings, in the row shape described under List insider trades.
freshness object The newest lifecycle timestamps across the returned rows.
pagination object {current_page, per_page, total_count, total_pages}.

Errors

401 Missing or invalid API credentials.
404 symbol names a ticker nobody tracks.
422 An unknown filter value, or a page past 20.
GET /api/v1/disclosure_trades
curl "https://optionomics.ai/api/v1/disclosure_trades?kind=both&period=30d" \
  -H "X-USER-EMAIL: [email protected]" \
  -H "X-USER-TOKEN: $OPTIONOMICS_API_KEY"
Try it
Response example
{
  "trades": [
    {"id": "…", "source": "sec_form4", "source_kind": "insider", "ticker": "NVDA", "…": "…"},
    {"id": "…", "source": "senate_periodic_transaction", "source_kind": "politician", "ticker": "MSFT", "…": "…"}
  ],
  "freshness": {
    "latest_source_published_at": "2026-08-05T21:45:00Z",
    "latest_source_fetched_at": "2026-08-05T21:49:31Z",
    "latest_normalized_at": "2026-08-05T21:49:33Z",
    "latest_last_seen_at": "2026-08-06T02:00:09Z",
    "latest_reprocessed_at": null
  },
  "pagination": {"current_page": 1, "per_page": 25, "total_count": 2472, "total_pages": 99}
}

List a symbol's disclosures

GET /api/v1/stocks/{symbol}/disclosure_trades Vega plan

Exactly List all disclosures with the ticker fixed by the path. A symbol nobody tracks answers 404 — an empty feed would read as "this company files nothing" rather than "no such company".

Parameters

Name Type Description
symbol path required string Ticker symbol. Unknown symbols answer 404.
kind string all, insider, politician or both. Default: all
period string 30d, 90d, 1y, 3y or all. Default: 1y
transaction_type string purchase, sale, award, exercise, gift, disposition, conversion, expiration or other.
min_value string A value floor: 1000, 15000, 50000, 100000, 500000, 1000000.
query string Free-text search over filers and issuers.
sort string filed_desc, traded_desc, value_desc, filer_asc or ticker_asc. Default: filed_desc
page integer 1–20. Beyond the cap answers 422. Default: 1
per_page integer Rows per page, up to 100. Default: 25

Response body

Field Type Description
trades / freshness / pagination object As on List all disclosures.

Errors

401 Missing or invalid API credentials.
404 No such symbol.
422 An unknown filter value, or a page past 20.
GET /api/v1/stocks/{symbol}/disclosure_trades
curl "https://optionomics.ai/api/v1/stocks/NVDA/disclosure_trades" \
  -H "X-USER-EMAIL: [email protected]" \
  -H "X-USER-TOKEN: $OPTIONOMICS_API_KEY"
Try it
Response example
{
  "trades": [
    {"id": "…", "source": "sec_form4", "source_kind": "insider", "ticker": "NVDA", "…": "…"}
  ],
  "freshness": {"latest_normalized_at": "2026-08-05T21:49:33Z", "…": "…"},
  "pagination": {"current_page": 1, "per_page": 25, "total_count": 96, "total_pages": 4}
}

News & events

The market's information flow: a de-duplicated, sentiment-scored news feed across major financial publishers, and the macro and market event feed — the macro prints (CPI, payrolls, GDP), Fed communications and filing events — with released figures.

News collapses to one row per story regardless of how many places carried it, and every event row is dated both by when it happens and by when it became known — the field that keeps backtests honest.

List news

GET /api/v1/news Vega plan

Stories from major financial publishers, de-duplicated by story rather than by URL — the same wire story carried in five places is one row. Each story carries its publisher, the full set of tickers it is about, and a sentiment reading once analysed.

symbol matches every story about the company, and tickers on each row is that full set — a story naming three companies appears under all three.

sort=importance weighs publication quality against age, so this morning's strongest stories rank first and nothing stale lingers — useful when only the top few rows will be read.

An unknown filter value is refused with 422 rather than ignored.

Parameters

Name Type Description
symbol string Every story about this ticker.
category string ticker or macro. macro includes re-categorised stories that kept a macro topic.
topic string One macro topic, e.g. federal-reserve.
publisher string A publisher domain, e.g. reuters.com.
sentiment string negative, neutral or positive.
from date or datetime Window start — 2026-08-01 or 2026-08-01T14:30:00Z. A bare date opens at midnight UTC.
to date or datetime Window end. A bare date closes at the end of its day.
sort string latest (publication order) or importance. Default: latest
page integer 1–40. Beyond the cap answers 422. Default: 1
per_page integer Rows per page, up to 100. Default: 25

Response body

Field Type Description
articles array of object The stories.
articles[].id uuid Stable story identifier.
articles[].headline string The headline.
articles[].summary string | null The publisher's description, where one was available.
articles[].url url The publisher's own link.
articles[].publisher string | null Publisher domain, e.g. reuters.com.
articles[].category / topic string | null ticker or macro, and the macro topic where one applies.
articles[].tickers array of string Every company the story is about.
articles[].published_at datetime Publication time, UTC.
articles[].sentiment object | null {label, confidence, analyzed_at}. label is negative/neutral/positive; confidence is the classifier's 0–1 confidence in that label — the direction lives in the label, not the number. Null until analysed.
pagination object {current_page, per_page, total_count, total_pages}.

Errors

401 Missing or invalid API credentials.
422 An unknown category/sentiment/sort, an unreadable date, or a page past 40.
GET /api/v1/news
curl "https://optionomics.ai/api/v1/news?per_page=25&symbol=NVDA" \
  -H "X-USER-EMAIL: [email protected]" \
  -H "X-USER-TOKEN: $OPTIONOMICS_API_KEY"
Try it
Response example
{
  "articles": [
    {
      "id": "b3a9d1c2-77aa-4dfe-9c1b-2f8e5a6d7c88",
      "headline": "NVIDIA unveils next-generation data-center GPU",
      "summary": "The chipmaker announced its successor platform at its developer conference.",
      "url": "https://www.reuters.com/technology/nvidia-unveils-...",
      "publisher": "reuters.com",
      "category": "ticker",
      "topic": null,
      "tickers": ["NVDA", "TSM"],
      "published_at": "2026-08-05T13:42:10.000000Z",
      "sentiment": {
        "label": "positive",
        "confidence": 0.94,
        "analyzed_at": "2026-08-05T13:50:02.000000Z"
      }
    }
  ],
  "pagination": {"current_page": 1, "per_page": 25, "total_count": 214, "total_pages": 9}
}

List a symbol's news

GET /api/v1/stocks/{symbol}/news Vega plan

Exactly List news with symbol fixed by the path — every story about the company, including ones that merely mention it. A symbol nobody tracks answers 404.

Parameters

Name Type Description
symbol path required string Ticker symbol. Unknown symbols answer 404.
All List news filters apply: category, sentiment, from/to, sort, page, per_page.

Response body

Field Type Description
articles / pagination object As on List news.

Errors

401 Missing or invalid API credentials.
404 No such symbol.
422 An unknown filter value, an unreadable date, or a page past 40.
GET /api/v1/stocks/{symbol}/news
curl "https://optionomics.ai/api/v1/stocks/NVDA/news" \
  -H "X-USER-EMAIL: [email protected]" \
  -H "X-USER-TOKEN: $OPTIONOMICS_API_KEY"
Try it
Response example
{
  "articles": [
    {"id": "…", "headline": "NVIDIA unveils next-generation data-center GPU", "tickers": ["NVDA", "TSM"], "…": "…"}
  ],
  "pagination": {"current_page": 1, "per_page": 25, "total_count": 38, "total_pages": 2}
}

List events

GET /api/v1/events Vega plan

Scheduled and released market events as a programmatic feed: the macro prints (CPI, payrolls, GDP), Fed communications and filing events. Released rows carry the figures — actual, previous, and forecast where a source publishes one — with the unit that makes the number readable.

With no window the feed answers the next 30 days, ascending: its resting question is what is coming. History is a from away, and order=desc reads it newest first. Windows clamp to a year.

A symbol filter means that symbol's rows alone. Market-wide rows have no ticker — omit the filter to read the macro tape.

Every row carries known_at — when this system learned the event existed — which is what keeps an event-driven backtest from trading on announcements before they were announced.

Parameters

Name Type Description
kinds string (comma-separated) Which kinds to serve: macro, fed, treasury, commodity, company_catalyst — and filing, which is off by default. treasury, commodity and company_catalyst are accepted and reserved; today's feed populates macro, fed and filing. Unknown kinds answer 422. Default: macro,fed,treasury,commodity,company_catalyst
importance integer A floor, 0–5. importance=4 keeps the prints that move markets. Default: 0
region string A region code, e.g. US.
status string scheduled, released, revised or cancelled.
symbol string One company's events. Market-wide rows carry no symbol.
from date (YYYY-MM-DD) Window start. Default: today
to date (YYYY-MM-DD) Window end. Clamped to a year after from. Default: from + 30 days
order string asc (calendar order) or desc (newest first). Default: asc
page integer 1–40. Beyond the cap answers 422. Default: 1
per_page integer Rows per page, up to 200. Default: 50

Response body

Field Type Description
from / to date The window actually served.
events array of object The rows, in calendar order.
events[].id uuid Stable event identifier.
events[].kind string macro, fed, treasury, commodity, company_catalyst or filing.
events[].title string The event's name.
events[].summary string | null A sentence of context, where the provider gave one.
events[].ticker string | null The company, for company-scoped rows; null for market-wide ones.
events[].region string | null Region code.
events[].date date The event's session.
events[].scheduled_at datetime | null The precise scheduled moment, where known.
events[].known_at datetime | null When this system learned the event existed — the backtest-honesty field.
events[].importance integer 0–5.
events[].status string scheduled, released, revised or cancelled.
events[].actual / forecast / previous number | null The figures, once released. forecast is carried only where a source publishes one; many prints ship actual and previous alone.
events[].unit string | null What the numbers are denominated in — percent, thousands of jobs — so a release added upstream cannot be rendered wrongly.
pagination object {current_page, per_page, total_count, total_pages}.
meta object {kinds, importance, max_window_days} — the filters actually applied.

Errors

401 Missing or invalid API credentials.
422 An unknown kind/status/order, or a page past 40.
GET /api/v1/events
curl "https://optionomics.ai/api/v1/events?importance=4&kinds=macro,fed" \
  -H "X-USER-EMAIL: [email protected]" \
  -H "X-USER-TOKEN: $OPTIONOMICS_API_KEY"
Try it
Response example
{
  "from": "2026-08-06",
  "to": "2026-09-05",
  "events": [
    {
      "id": "e1f5a6b7-8c9d-4e0f-a1b2-c3d4e5f6a7b8",
      "kind": "macro",
      "title": "CPI (July)",
      "summary": "Consumer Price Index, month over month.",
      "ticker": null,
      "region": "US",
      "date": "2026-08-12",
      "scheduled_at": "2026-08-12T12:30:00.000000Z",
      "known_at": "2026-07-01T09:00:00.000000Z",
      "importance": 5,
      "status": "scheduled",
      "actual": null,
      "forecast": null,
      "previous": 0.3,
      "unit": "percent"
    }
  ],
  "pagination": {"current_page": 1, "per_page": 50, "total_count": 19, "total_pages": 1},
  "meta": {
    "kinds": ["macro", "fed", "treasury", "commodity", "company_catalyst"],
    "importance": 4,
    "max_window_days": 366
  }
}

Earnings analyses

AI readings of companies' earnings filings — 10-Qs, 10-Ks and the rest — each with a sentiment call, a confidence, a summary, highlights and risks, guidance as stated, and a comparison to the prior quarter.

The filings are public SEC records, collected and read here; every row links to the official document so the reading can be checked against its source.

List a symbol's filing analyses

GET /api/v1/stocks/{symbol}/earning_filings Vega plan

Every analysed filing for a symbol, newest first. By default the list is the periodic reports — 10-Q and 10-K — because that is where the quarters live; forms widens or narrows it.

An unknown form type is refused with 422 rather than ignored, the same discipline as every other filter on this API.

Parameters

Name Type Description
symbol path required string Ticker symbol. Unknown symbols answer 404.
forms string (comma-separated) Form types to include, e.g. forms=8-K,10-Q. Unknown forms answer 422. Default: 10-Q,10-K

Response body

Field Type Description
symbol string The symbol echoed back.
forms array of string The form filter applied.
filings array of object The filings with their readings, in the shape below.
filings[].filing_id / form_type / filed_at / period_of_report mixed The SEC filing the reading is of: its id, form (10-Q, 10-K, …), and dates.
filings[].ticker string The company that filed.
filings[].document_url url | null The filing's primary document at the official source.
filings[].status string Where the reading stands. A filing that failed analysis is a row with no reading, not an absent row.
filings[].sentiment / confidence / has_analysis mixed The reading's headline: the sentiment call, the 0–1 confidence behind it, and whether a full analysis exists.
filings[].analysis object | null The full reading, when one exists.
filings[].analysis.summary string What the quarter said, in a paragraph.
filings[].analysis.highlights / risks array of object {title, detail, severity} entries — what stood out, and what to watch.
filings[].analysis.guidance object | null Management's forward guidance as read from the filing. Keys with nothing to say are pruned; a filing with no guidance sends null, not a map of blanks.
filings[].analysis.financial_metrics object | null The figures the reading extracted, where the filing stated them.
filings[].analysis.comparison_to_prior object | null How this quarter reads against the one before it.

Errors

401 Missing or invalid API credentials.
402 No active subscription.
403 Plan does not include AI insights.
404 No such symbol.
422 An unknown form type.
GET /api/v1/stocks/{symbol}/earning_filings
curl "https://optionomics.ai/api/v1/stocks/NVDA/earning_filings" \
  -H "X-USER-EMAIL: [email protected]" \
  -H "X-USER-TOKEN: $OPTIONOMICS_API_KEY"
Try it
Response example
{
  "symbol": "NVDA",
  "forms": ["10-Q", "10-K"],
  "filings": [
    {
      "filing_id": "f2a7c9e1-4b6d-4f8a-9c0e-1d2f3a4b5c6d",
      "form_type": "10-Q",
      "filed_at": "2026-05-28T20:31:00Z",
      "period_of_report": "2026-04-26",
      "ticker": "NVDA",
      "document_url": "https://www.sec.gov/Archives/edgar/data/1045810/…/nvda-20260426.htm",
      "status": "analyzed",
      "sentiment": "positive",
      "confidence": 0.92,
      "has_analysis": true,
      "error_message": null,
      "analysis": {
        "summary": "Data-center revenue drove another record quarter; margins held despite supply costs.",
        "sentiment": "positive",
        "confidence": 0.92,
        "highlights": [
          {"title": "Data-center growth", "detail": "Segment revenue up strongly year over year.", "severity": null}
        ],
        "risks": [
          {"title": "Customer concentration", "detail": "A small number of customers drive a large revenue share.", "severity": "medium"}
        ],
        "guidance": {"direction": "raised", "revenue": "Above prior outlook"},
        "financial_metrics": {"revenue": "44.1B", "gross_margin": "71.3%"},
        "comparison_to_prior": {"sentiment_shift": "steady", "revenue_trend": "accelerating"}
      }
    }
  ]
}

Get a filing's analysis

GET /api/v1/earning_filings/{id} Vega plan

The same full shape as the list rows, for one filing — plus previous_sentiment, the sentiment of the filing before it, which is what makes the comparison's sentiment_shift legible without a second request.

Parameters

Name Type Description
id path required uuid The filing's id, from the list.

Response body

Field Type Description
filing_id … analysis mixed The full row shape documented on the list endpoint.
previous_sentiment string | null The prior filing's sentiment call, or null for a company's first.

Errors

401 Missing or invalid API credentials.
402 No active subscription.
403 Plan does not include AI insights.
404 No such filing.
GET /api/v1/earning_filings/{id}
curl "https://optionomics.ai/api/v1/earning_filings/f2a7c9e1-4b6d-4f8a-9c0e-1d2f3a4b5c6d" \
  -H "X-USER-EMAIL: [email protected]" \
  -H "X-USER-TOKEN: $OPTIONOMICS_API_KEY"
Try it
Response example
{
  "filing_id": "f2a7c9e1-4b6d-4f8a-9c0e-1d2f3a4b5c6d",
  "form_type": "10-Q",
  "filed_at": "2026-05-28T20:31:00Z",
  "period_of_report": "2026-04-26",
  "ticker": "NVDA",
  "document_url": "https://www.sec.gov/Archives/edgar/data/1045810/…/nvda-20260426.htm",
  "status": "analyzed",
  "sentiment": "positive",
  "confidence": 0.92,
  "has_analysis": true,
  "error_message": null,
  "analysis": {
    "summary": "Data-center revenue drove another record quarter; margins held despite supply costs.",
    "sentiment": "positive",
    "confidence": 0.92,
    "highlights": [
      {"title": "Data-center growth", "detail": "Segment revenue up strongly year over year.", "severity": null}
    ],
    "risks": [
      {"title": "Customer concentration", "detail": "A small number of customers drive a large revenue share.", "severity": "medium"}
    ],
    "guidance": {"direction": "raised", "revenue": "Above prior outlook"},
    "financial_metrics": {"revenue": "44.1B", "gross_margin": "71.3%"},
    "comparison_to_prior": {"sentiment_shift": "steady", "revenue_trend": "accelerating"}
  },
  "previous_sentiment": "positive"
}

Trade ideas & commentary

The research layer: machine-generated trade ideas with their theses, levels and monitored outcomes; on-demand conditions assessments that re-read an idea against the market right now; the public track record every pipeline is held to; and the desk's running market commentary.

One of these endpoints is public by design: the track record answers without a key, because a performance claim you cannot verify without paying is not a claim.

List trade ideas

GET /api/v1/trade_ideas Vega plan

Every published idea for a screen date: the setup, the thesis, entry, target and stop, the generating pipeline's rolling track record, and how the idea has moved since publication.

dates lists every session that has published ideas, and the requested date resolves against it — a weekend or a pre-scan morning answers the nearest published session rather than an empty feed a client cannot tell from an outage. live says whether the served session is the current one.

Ideas are research output, not investment advice — every idea carries the track record that lets you weigh it.

Parameters

Name Type Description
date date (YYYY-MM-DD) The screen date. Resolves to the nearest session that published. Default: latest published session

Response body

Field Type Description
trade_ideas array of object The published ideas.
trade_ideas[].id uuid Stable idea identifier.
trade_ideas[].symbol / direction / strategy string The setup: ticker, bullish/bearish/neutral, and the strategy label.
trade_ideas[].thesis / explanation string Why the idea exists, in prose.
trade_ideas[].status string open, closed or expired.
trade_ideas[].confidence_score number | null The generator's 0–1 confidence.
trade_ideas[].conviction_tier / historical_star_rating string / number How the idea ranks against its pipeline's history.
trade_ideas[].pipeline / pipeline_name / source string Which generator produced it.
trade_ideas[].track_record object The pipeline's rolling record: win_rate, sample_size, wilson_lower_bound, basis, as_of, sufficient, min_sample_size, window_days, description. Always present; members are null while the cohort is still thin.
trade_ideas[].levels object {entry, target, stop, current, peak}.
trade_ideas[].option_legs array | null The contract legs, for option strategies.
trade_ideas[].outcome_status / outcome_label / on_track mixed Where the monitored outcome stands.
trade_ideas[].generated_at / expires_at / monitoring_ends_at datetime | null The idea's clock.
trade_ideas[].receipt_url / share_card_url url | null The public receipt page and its share card.
metrics object Session aggregates: open/bullish/bearish/today/closed/expired/resolved counts, win_count, win_rate, positive_open_count, positive_open_rate, max_profit.
dates array of date Every session that has published ideas.
current_date date | null The session served.
live boolean Whether that session is the current one.

Errors

401 Missing or invalid API credentials.
402 No active subscription.
403 Plan does not include trade ideas.
GET /api/v1/trade_ideas
curl "https://optionomics.ai/api/v1/trade_ideas" \
  -H "X-USER-EMAIL: [email protected]" \
  -H "X-USER-TOKEN: $OPTIONOMICS_API_KEY"
Try it
Response example
{
  "trade_ideas": [
    {
      "id": "7f4d9db0-4f3b-4f1d-ae42-bbd48737ef14",
      "symbol": "NVDA",
      "direction": "bullish",
      "strategy": "buy_call",
      "thesis": "Sustained institutional call accumulation into a gamma shelf at 130.",
      "status": "open",
      "confidence_score": 0.78,
      "conviction_tier": "high",
      "historical_star_rating": 4,
      "pipeline": "swing",
      "pipeline_name": "Swing setups",
      "source": "Swing setups",
      "track_record": {
        "win_rate": 0.62,
        "sample_size": 148,
        "wilson_lower_bound": 0.54,
        "basis": "30d",
        "as_of": "2026-08-01"
      },
      "levels": {"entry": 128.4, "target": 138.0, "stop": 123.5, "current": 130.1, "peak": 131.2},
      "option_legs": [
        {"action": "buy", "type": "call", "strike": 130.0, "expiration": "2026-09-18"}
      ],
      "outcome_status": "monitoring",
      "outcome_label": "Monitoring",
      "on_track": true,
      "generated_at": "2026-08-05T13:35:00Z",
      "expires_at": "2026-09-04T20:00:00Z",
      "receipt_url": "https://optionomics.ai/r/8fk2…",
      "share_card_url": "https://optionomics.ai/r/8fk2…/card.png"
    }
  ],
  "metrics": {
    "open_count": 9,
    "bullish_count": 6,
    "bearish_count": 3,
    "today_count": 9,
    "closed_count": 0,
    "expired_count": 0,
    "resolved_count": 0,
    "win_count": 0,
    "win_rate": null,
    "positive_open_count": 5,
    "positive_open_rate": 0.56,
    "max_profit": 4.2
  },
  "dates": ["2026-08-05", "2026-08-04", "2026-08-03"],
  "current_date": "2026-08-05",
  "live": true
}

Get a trade idea

GET /api/v1/trade_ideas/{id} Vega plan

The idea plus its context in one response: related ideas on the same symbol, reader comments, the session's chart series, recent news for the symbol, and the community vote totals.

Only published, user-visible ideas are reachable — an idea held back from subscribers answers 404 even with a valid id, and a malformed id reads as not-found rather than an error: stale ids should read as gone.

Parameters

Name Type Description
id path required uuid The idea's id, from List trade ideas.

Response body

Field Type Description
trade_idea object The idea, in the same shape as List trade ideas rows.
related array of object Nearby ideas, same shape.
comments array of object {id, body, user_name (initials), user_id, created_at}.
chart object | null The session's intraday series with the idea's levels, shaped for a native renderer. Null when the session has no bars.
news array of object Recent stories on the symbol.
votes object {upvotes, downvotes, user_vote} — user_vote is yours, or null.

Errors

401 Missing or invalid API credentials.
402 No active subscription.
403 Plan does not include trade ideas.
404 No such idea, or not published.
GET /api/v1/trade_ideas/{id}
curl "https://optionomics.ai/api/v1/trade_ideas/7f4d9db0-4f3b-4f1d-ae42-bbd48737ef14" \
  -H "X-USER-EMAIL: [email protected]" \
  -H "X-USER-TOKEN: $OPTIONOMICS_API_KEY"
Try it
Response example
{
  "trade_idea": {"id": "7f4d9db0-4f3b-4f1d-ae42-bbd48737ef14", "symbol": "NVDA", "…": "…"},
  "related": [{"id": "…", "symbol": "NVDA", "…": "…"}],
  "comments": [
    {
      "id": "c1a2b3d4-…",
      "body": "Watching the 130 wall.",
      "user_name": "JD",
      "user_id": "u-…",
      "created_at": "2026-08-05T15:02:11Z"
    }
  ],
  "chart": {"…": "…"},
  "news": [{"headline": "…", "url": "…"}],
  "votes": {"upvotes": 14, "downvotes": 2, "user_vote": null}
}

Get the track record

GET /api/v1/trade_ideas/track_record No key required

The transparency table: for each idea pipeline, its resolved counts, win rates and Wilson lower bounds across rolling windows — the same numbers the public track-record page draws, as JSON.

win_definition publishes the exact scoring rule, including the two pipeline families scored by their own policies. The definition ships with the data so the numbers cannot be quietly redefined.

This endpoint requires no authentication. It is the proof surface, and proof you cannot fetch is not proof.

Response body

Field Type Description
generated_on date When the table was computed.
win_definition object {stock_threshold_pct, option_threshold_pct, window_days, default_window_days, policy_exceptions}.
min_sample_size integer Resolved ideas required before a window's rate is called sufficient.
pipelines array of object One row per pipeline.
pipelines[].kind / name string The pipeline's key and display name.
pipelines[].historical_star_rating number | null The pipeline's star rating.
pipelines[].open_count / awaiting_resolution_count integer What is still being monitored.
pipelines[].windows object Keyed by window (e.g. "30d"): {win_rate, wilson_lower_bound, resolved_count, wins, avg_peak_return_pct, sufficient} — or null.
GET /api/v1/trade_ideas/track_record
curl "https://optionomics.ai/api/v1/trade_ideas/track_record"
Try it
Response example
{
  "generated_on": "2026-08-06",
  "win_definition": {
    "stock_threshold_pct": 5,
    "option_threshold_pct": 10,
    "window_days": 30,
    "default_window_days": 30,
    "policy_exceptions": {
      "crush": "post_earnings_close_expected_move_containment",
      "market_pressure": "forward_close_direction"
    }
  },
  "min_sample_size": 30,
  "pipelines": [
    {
      "kind": "swing",
      "name": "Swing setups",
      "historical_star_rating": 4,
      "open_count": 12,
      "awaiting_resolution_count": 31,
      "windows": {
        "30d": {
          "win_rate": 0.62,
          "wilson_lower_bound": 0.54,
          "resolved_count": 148,
          "wins": 92,
          "avg_peak_return_pct": 6.8,
          "sufficient": true
        }
      }
    }
  ]
}

Get an idea's assessment

GET /api/v1/trade_ideas/{id}/assessment Vega plan

An assessment re-reads a published idea against the market as it is now: eighteen independent checks — trend, flow, positioning, volatility, event risk — each answering in favor, against, neutral or skipped, rolled into a verdict with a score and its reasons.

The verdict copy is deliberately a conditions read ("conditions currently align"), never an instruction to trade.

assessment is null when nobody has requested one yet — request one with the POST, then poll this until status is completed and fresh is true.

Parameters

Name Type Description
id path required uuid The idea's id.

Response body

Field Type Description
assessment object | null The latest assessment, or null when none has been requested.
assessment.status string pending, running, completed or failed.
assessment.favor_count / against_count / neutral_count / skipped_count integer The checks' tally.
assessment.checks array of object {key, label, verdict, reason} per check. The technical_analysis check additionally carries a data blob.
assessment.verdict object | null {value (take_now/wait/skip), score, headline, reasons: [{key, verdict, reason}]}.
assessment.spot_price / assessed_at / fresh mixed The read's anchor price, its time, and whether it is still fresh.

Errors

401 Missing or invalid API credentials.
402 No active subscription.
403 Plan does not include trade ideas.
404 No such idea.
GET /api/v1/trade_ideas/{id}/assessment
curl "https://optionomics.ai/api/v1/trade_ideas/7f4d9db0-4f3b-4f1d-ae42-bbd48737ef14/assessment" \
  -H "X-USER-EMAIL: [email protected]" \
  -H "X-USER-TOKEN: $OPTIONOMICS_API_KEY"
Try it
Response example
{
  "assessment": {
    "id": "a1b2c3d4-5e6f-7a8b-9c0d-e1f2a3b4c5d6",
    "status": "completed",
    "favor_count": 9,
    "against_count": 4,
    "neutral_count": 4,
    "skipped_count": 1,
    "spot_price": 130.1,
    "assessed_at": "2026-08-06T14:12:40Z",
    "fresh": true,
    "checks": [
      {
        "key": "options_flow",
        "label": "Options flow",
        "verdict": "favor",
        "reason": "Net call premium has stayed positive since publication."
      }
    ],
    "verdict": {
      "value": "take_now",
      "score": 0.71,
      "headline": "Conditions currently align with this idea",
      "reasons": [
        {"key": "options_flow", "verdict": "favor", "reason": "Flow still supports the thesis."}
      ]
    }
  }
}

Request an assessment

POST /api/v1/trade_ideas/{id}/assessment Vega plan

Answers 202 with the assessment in hand — a fresh one is reused, a running one is joined, and otherwise a new one is enqueued. All three are the same instruction to a client: show what there is, then poll the GET until status is completed.

The request body is empty; the idea id in the path is the whole input.

Parameters

Name Type Description
id path required uuid The idea's id.

Response body

Field Type Description
assessment object The assessment as it stands — possibly still pending or running. Same shape as the GET.

Errors

401 Missing or invalid API credentials.
402 No active subscription.
403 Plan does not include trade ideas.
404 No such idea.
POST /api/v1/trade_ideas/{id}/assessment
curl -X POST "https://optionomics.ai/api/v1/trade_ideas/7f4d9db0-4f3b-4f1d-ae42-bbd48737ef14/assessment" \
  -H "X-USER-EMAIL: [email protected]" \
  -H "X-USER-TOKEN: $OPTIONOMICS_API_KEY"
Try it
Response example
{
  "assessment": {
    "id": "a1b2c3d4-5e6f-7a8b-9c0d-e1f2a3b4c5d6",
    "status": "running",
    "favor_count": 0,
    "against_count": 0,
    "neutral_count": 0,
    "skipped_count": 0,
    "spot_price": null,
    "assessed_at": null,
    "fresh": false,
    "checks": [],
    "verdict": null
  }
}

List market commentary

GET /api/v1/market_commentaries Vega plan

Machine-written commentary as the session develops: what flow is doing, where positioning is concentrating, what changed — each entry with a severity, the symbols it names, a trimmed snapshot of the market state it was written against, and per-symbol performance tracking once prices arrive.

Returns are signed by the thesis: a bearish call on a stock that fell reports a positive return.

metrics counts the whole day regardless of any category filter, so a filtered list still shows the day's true composition.

Parameters

Name Type Description
date date (YYYY-MM-DD) The session to read. Default: today (US Eastern)
category string Narrow to one commentary category.

Response body

Field Type Description
commentaries array of object The entries, newest first.
commentaries[].id uuid Stable entry identifier.
commentaries[].category / severity string The entry's category, and info/notable/critical.
commentaries[].headline / body string The commentary itself.
commentaries[].symbols array of string The tickers the entry names.
commentaries[].return_pct / peak_return_pct number | null The primary symbol's thesis-signed return since the entry.
commentaries[].market_snapshot object | null The trimmed state it was written against: direction, net_flow, call_premium, put_premium, sentiment_score, bullish_pct, bearish_pct, scan_time. Absent figures are omitted, not null.
commentaries[].performance_tracking array | null Per tracked symbol: {symbol, entry_price, current_price, peak_price, return_pct, peak_return_pct}. Symbols not yet tracked are omitted.
metrics object {today_count, critical_count, notable_count, info_count, category_counts}.
dates array of date Sessions with commentary.
current_date date The session served.
live boolean Whether that session is the current one.

Errors

401 Missing or invalid API credentials.
402 No active subscription.
403 Plan does not include market commentary.
GET /api/v1/market_commentaries
curl "https://optionomics.ai/api/v1/market_commentaries" \
  -H "X-USER-EMAIL: [email protected]" \
  -H "X-USER-TOKEN: $OPTIONOMICS_API_KEY"
Try it
Response example
{
  "commentaries": [
    {
      "id": "d4e5f6a7-…",
      "category": "flow_shift",
      "severity": "notable",
      "headline": "Call premium rotating into semis",
      "body": "Net call premium in NVDA and AMD has doubled off the morning lows…",
      "symbols": ["NVDA", "AMD"],
      "generated_at": "2026-08-06T15:20:00Z",
      "return_pct": 1.2,
      "peak_return_pct": 1.9,
      "market_snapshot": {
        "direction": "risk_on",
        "net_flow": 182000000.0,
        "call_premium": 640000000.0,
        "put_premium": 458000000.0,
        "bullish_pct": 58.2,
        "bearish_pct": 41.8
      },
      "performance_tracking": [
        {
          "symbol": "NVDA",
          "entry_price": 128.9,
          "current_price": 130.4,
          "peak_price": 131.2,
          "return_pct": 1.2,
          "peak_return_pct": 1.8
        }
      ]
    }
  ],
  "metrics": {
    "today_count": 14,
    "critical_count": 2,
    "notable_count": 7,
    "info_count": 5,
    "category_counts": {"flow_shift": 6, "positioning": 4, "volatility": 4}
  },
  "dates": ["2026-08-06", "2026-08-05"],
  "current_date": "2026-08-06",
  "live": true
}

MCP server

The same data, spoken natively to AI tooling: Optionomics runs a Model Context Protocol server, so Claude, ChatGPT, Cursor and any other MCP-capable client can query flow, chains, news, events, disclosures and the research layer directly — no glue code, no polling scripts.

The catalog below is read from the server's own registry, so this table is the list a connected client sees. Every tool is read-only.

Connect a client

The server speaks MCP over Streamable HTTP at https://optionomics.ai/mcp. Two credential shapes are accepted, because clients in the wild send one or the other: the same X-USER-EMAIL + X-USER-TOKEN pair the REST API takes, or Authorization: Bearer base64(email:token) for clients that only expose a single header.

The email and token must belong to the same account — a mismatched pair is refused rather than silently attributed. MCP access is part of the Vega plan; a valid key on a plan without it answers 403 with instructions, not a dead end.

Keys are the same ones the REST API uses, managed under Settings → API keys.

Every call your clients make is logged with its arguments, its response and its latency at MCP logs. A tool result is consumed by a model inside a client we do not run, so when an agent answers oddly, that log is where the reason is.

Client configuration
{
  "mcpServers": {
    "optionomics": {
      "type": "http",
      "url": "https://optionomics.ai/mcp",
      "headers": {
        "X-USER-EMAIL": "[email protected]",
        "X-USER-TOKEN": "paste-your-api-key"
      }
    }
  }
}

Install in your client

Paste the block into the file named beside it, then replace paste-your-api-key with a key from the developer console. The one-click buttons add the endpoint for you; they carry no key, because a link ends up in browser history and a key should not.

Claude Desktop

claude_desktop_config.json Settings → Developer → Edit Config
{
  "mcpServers": {
    "optionomics": {
      "type": "http",
      "url": "https://optionomics.ai/mcp",
      "headers": {
        "X-USER-EMAIL": "[email protected]",
        "X-USER-TOKEN": "paste-your-api-key"
      }
    }
  }
}

Claude Code

.mcp.json in your project root, checked in beside the code that uses it
{
  "mcpServers": {
    "optionomics": {
      "type": "http",
      "url": "https://optionomics.ai/mcp",
      "headers": {
        "X-USER-EMAIL": "[email protected]",
        "X-USER-TOKEN": "paste-your-api-key"
      }
    }
  }
}

Cursor

~/.cursor/mcp.json or .cursor/mcp.json for one project Add to Cursor
{
  "mcpServers": {
    "optionomics": {
      "type": "http",
      "url": "https://optionomics.ai/mcp",
      "headers": {
        "X-USER-EMAIL": "[email protected]",
        "X-USER-TOKEN": "paste-your-api-key"
      }
    }
  }
}

VS Code

.vscode/mcp.json or the user-level mcp.json Add to VS Code
{
  "servers": {
    "optionomics": {
      "type": "http",
      "url": "https://optionomics.ai/mcp",
      "headers": {
        "X-USER-EMAIL": "[email protected]",
        "X-USER-TOKEN": "paste-your-api-key"
      }
    }
  }
}

Prefer to check it works first? The console runs any tool in the browser and shows exactly what a client receives, and this server is listed for registries at /.well-known/mcp/server.json.

Tools & resources

23 tools and 2 resources, exactly as the server lists them.

Tool What it answers Arguments
stock_quote Get current or historical stock quote with OHLC, volume, and price change symbol* date
options_chain Get the options chain with Greeks for a stock, including strikes, prices, volume, and open interest symbol* date expiration_date limit option_type strike_max strike_min
option_metrics Get options metrics for a stock: put/call ratio, IV, GEX, DEX, max pain, and key levels symbol* date
options_flow Get aggregated options flow data: bullish/bearish flow, top calls, or top puts type* date limit
net_flow Get net call/put premium flow timeseries for a symbol with resolution and DTE filters symbol* dte_max dte_min from resolution to
unusual_activity Get unusual options activity alerts showing high-premium, high-volume trades that may indicate institutional activity date exclude_etfs limit
support_resistance_levels Get support and resistance levels derived from options flow activity for a given symbol date symbol
market_overview Get market overview including major indices prices, changes, and volume date
price_history Get daily OHLCV price history with period return, drawdown, average volume, and realized volatility symbol* days end_date
news Get recent ticker or macro market news headlines with summaries and source URLs hours limit symbol topic
gamma_exposure Get gamma exposure (GEX) levels, net dealer positioning, and support/resistance by strike symbol* date limit
trend_analysis Analyze price trend, momentum, volatility, and support/resistance over a recent lookback window symbol* end_date period
dark_pool_levels Get dark pool support and resistance levels based on large dark pool prints date symbol
iv_term_structure Analyze IV term structure, IV rank/percentile, and realized-vs-implied volatility context symbol* date
events Get market-moving events by date window, ticker, kind, and status from kind limit status symbol to
insider_trades Get SEC Form 4 insider trades with bounded filters and pagination limit min_value page period source symbol transaction_type
politician_trades Get public House, Senate, and OGE disclosure trades with bounded filters limit min_value page period source state symbol transaction_type
news_sentiment Get analyzed ticker or macro market-news sentiment with safe headline context hours limit symbol topic
trade_ideas Get published trade ideas for a session with levels, lifecycle status, and each idea's track record date
trade_idea_assessment Get the latest stored conditions assessment for a trade idea: check verdicts, counts, and the aggregate verdict trade_idea_id*
track_record Get the published trade-idea track record: rolling win rates, star ratings, and open counts for every strategy family
market_commentary Get generated market commentary for a session, optionally filtered by category category date
earnings_analyses Get analysed SEC filings for a symbol: summary, sentiment, highlights, risks, guidance, and quarter-over-quarter comparison symbol* forms limit

Resources

Available Symbols List of tracked stock symbols
Trading Days List of available trading days

Arguments marked * are required. Tool calls count toward the same 1,000-requests-per-minute allowance as the REST API.