gexbot api

research

REST endpoint for on-demand gbR options chart assets, 3D volatility surfaces, and tabular CSV/JSON datasets across US optionable equities.

GET/research/{ticker}/{metric}Research Tier
Official Endpoint Specification

Research API Specification & Interactive Builder

The complete REST endpoint specification, accepted parameter schemas, response models, and interactive URL testing tools are maintained directly on the platform.

View Full API Specification & Builder on gexbot.com ↗

Endpoint Overview

The Research API computes on-demand Greek exposures, volatility surfaces, open interest profiles, and price-spread parity. It serves index options, ETFs, and all US optionable equities.

GET /research/{ticker}/{metric}

Architecture & Service Base URLs

  • API Gateway: /research/{ticker}/{metric}
  • Asset Storage & CDN: https://assets.gexbot.com/ (or https://r.gex.bot/). The url field of a descriptor already starts with gbR/.

Operating Hours & Data Cadence

  • Regular Market Hours (09:30–16:00 ET):
    • Evaluates live option market quotes using the gbR pricing model.
    • Caches requests on 15-minute floor intervals on-demand.
  • Index Option Extended Hours (16:00–16:15 ET):
    • Index options (such as SPX and NDX) trade until 16:15 ET.
    • Requests submitted at or after 16:15 ET include trades from this 15-minute post-close window.
  • Premarket Hours (Before 09:30 ET):
    • Open Interest (OI) refreshes daily at 08:00 ET.
    • Calculations use previous session quotes under the gbR model. The premarket cache refreshes once after 08:00 ET.
    • Option volume metrics remain disabled until market open at 09:30 ET.
  • After Hours, Final Snapshots & Weekends:
    • The final scheduled End-of-Day (EOD) snapshot generates every evening at 23:00 UTC (19:00 EDT / 18:00 EST).
    • After 17:00 ET, all after-hours queries return the stabilized closing snapshot from the session.
    • Queries on weekends and market holidays return the cached snapshot from the previous trading session.

Option Expiration & Settlement Cadence

  • Settlement Timestamps:
    • AM-Settled Series: Standard monthly index contracts expire at 10:00 ET on their expiration date.
    • PM-Settled Series: Daily and weekly equity and index contracts expire at 16:00 ET on their expiration date.
  • Expired Series Filtering:
    • Contracts drop immediately from active expirations and calculations once the market clock reaches their expiration timestamp.
    • DTE resolution, exposure metrics, and API responses exclude expired contracts automatically.

Authentication & Headers

All requests require a Research API key (prefix research_). You can create one when your account has the Research add-on. The endpoint refuses gexbot keys, including Quant keys, with 403. Pass the key in the Authorization header as a Bearer token:

Authorization: Bearer <YOUR_API_KEY>
User-Agent: <YOUR_APP_NAME>/1.0
Accept: application/json
HeaderTypeRequiredDescription
AuthorizationstringYesBearer token format: Bearer <YOUR_API_KEY>.
User-AgentstringYesUnique identifier for your client application.
AcceptstringYesSet to application/json, or text/csv for the csv format.

Path Parameters

ParameterTypeRequiredExampleDescription
tickerstringYesSPX, NVDA, AAPLTicker symbol of the underlying asset (1 to 6 letters, not case-sensitive). Digits, dots and slashes are not accepted.
metricstringYesgex_oi, iv_mid, oiThe analytical metric or Greek exposure to calculate.

Metric Aliases

The API translates legacy and shorthand metric names to internal engines. Metric names are not case-sensitive.

Request AliasCanonical Engine MetricCategory
oiopen_interestMarket Data
parityput_call_parityMarket Data
gamma_wallgamma_wall_absMarket Data
vol_triggergamma_flipMarket Data
iv_askask_ivImplied Volatility
iv_midmid_ivImplied Volatility
iv_bidbid_ivImplied Volatility
extrinsictime_valueMarket Data
intrinsicintrinsic_valueMarket Data

Query Parameters

The view and type values are case-sensitive. All other values are not. Only the value true (any case) turns a boolean on. Any other value is false. A start_dte or end_dte value that is not an integer resets both parameters to their defaults. For chart formats an empty expiration window moves to the nearest expiration.

ParameterTypeDefaultAccepted ValuesDescription
formatstringwebpwebp, png, jpeg, svg, pdf, json, csvResponse payload format. Image formats return an asset descriptor.
viewstringskewskew, term, surface, mirror (implied-volatility metrics only)Chart visualization mode. mirror applies to iv_bid, iv_mid and iv_ask only. Other metrics fall back to skew.
typestringline (bar for oi, volume and exposure metrics; scatter for parity)bar, line, histogram, scatterSeries render style.
themestringdarkdark, lightColor palette for rendered chart images.
strikesinteger15 (50 for oi and volume, 30 for exposure metrics)Integer 5-250 (values outside the range are clamped)Number of strike intervals calculated around spot price.
start_dteinteger0Integer 0-1000Start days-to-expiration boundary (inclusive).
end_dteinteger98 (365 for view=term, 64 for max_pain)Integer 0-1000End days-to-expiration boundary (inclusive).
expiration_filterstringNonem (monthly), w (weekly), q (quarterly)Restricts calculations to specific expiration types.
contract_filterstringallall, calls, putsFilters calculation contracts by option side.
moneyness_filterstringNone (ntm for iv_bid, iv_mid and iv_ask)otm, ntm, itm, atm, d10, d15, d20, d25Filters contracts by moneyness or delta bucket. Default is ntm for iv_bid, iv_mid and iv_ask.
contract_aggbooleantruetrue, falseWhen true, nets calls and puts into one value per strike. When false, keeps calls and puts as separate rows.
expiry_aggbooleanfalsetrue, falseWhen true, aggregates all expiries across each strike.
skew_adjbooleanfalsetrue, falseAdjusts Greek calculations for volatility skew.
limit_ybooleantruetrue, falseClamps the Y-axis scale to remove extreme statistical outliers. Send limit_y=false to disable the clamp.
seriesstringNonedeltas, moneyness, strikesFor IV term view, plots term structure across delta tiers.

Response Schemas

1. Image Asset Descriptor Response

When format is webp, png, svg, jpeg, or pdf, the server returns a JSON object containing the relative asset URL:

{
  "url": "gbR/QUFQTF9za2V3X2NvbnRyYWN0X2FnZ18yMDI2MDcwOFQxNTQ4MDU.svg",
  "name": "QUFQTF9za2V3X2NvbnRyYWN0X2FnZ18yMDI2MDcwOFQxNTQ4MDU.svg",
  "content_type": "image/svg+xml",
  "description": "$AAPL skew 20260708T154805",
  "time_stamp": "20260708T154805",
  "model_ts": "2026-07-08T15:45:00-04:00",
  "model": "gbR"
}
FieldTypeDescription
urlstringRelative asset path. Resolve against https://r.gex.bot/ to fetch the file.
namestringAsset filename. Matches the last path segment of url.
content_typestringMIME type of the rendered file.
descriptionstringSummary containing ticker, metric, and generation timestamp.
time_stampstringGeneration timestamp in YYYYMMDDTHHMMSS format.
model_tsstring or nullISO-8601 timestamp of the options-chain snapshot the chart used.
modelstringVolatility model of the request. Default gbR.

2. Tabular Data Response (format=csv and format=json)

When format=csv the endpoint returns text/csv with Content-Disposition: attachment; filename="SPX_data.csv". When format=json it returns application/json: an array of row objects with the same columns, with Content-Disposition: attachment; filename="SPX_data.json".

  • Skew view columns: idx_strike_price, idx_expiration_date (absent when expiry_agg=true), idx_call_put_flag (absent when contract_agg=true, the default) and the metric id in upper case, for example GEX_OI.
  • Term view columns: idx_expiration_date, idx_call_put_flag (absent when contract_agg=true) and the metric.
  • Surface view: one row per strike and expiration with the metric.
  • gamma_flip, vol_trigger, gamma_wall and gamma_wall_abs return the gamma-flip table instead.
  • skew_adj and expiration_filter have no effect on csv or json output.

Example header with contract_agg=false:

idx_strike_price,idx_expiration_date,idx_call_put_flag,GEX_OI

Error Handling & Rate Limits

HTTP StatusError ReasonResponse Body / Behavior
400 Bad RequestUnknown or restricted metric, or an invalid parameter.{"error": "invalid request"}. Other messages: Invalid ticker., Invalid metric., Ticker ZZZZ is not a valid symbol., GEX_OI does not support skew adjustment., Volume-based metrics are unavailable during pre-market hours. Please wait for market open., User-Agent not found., Authorization header not found.
401 UnauthorizedInvalid API key. A missing Authorization header returns 400.The response carries no {"error": ...} body.
403 ForbiddenThe key is not a Research API key.The response carries no {"error": ...} body.
403 ForbiddenThe requested format is not available to this key.{"error": "This research data format is not available for restricted commercial access."}
429 Too Many RequestsQuery quota exceeded for the current window.{"error": "Rate limit exceeded."}
500 Internal Server ErrorThe research service failed.{"error": "Failed to reach upstream research service."}, or a research-service message such as Failed to load data. or Failed to build chart.

Code Examples

BASE_URL="<your host and version>"

# Request SVG chart asset descriptor
curl -X GET "$BASE_URL/research/SPX/gex_oi?format=svg&strikes=25&contract_agg=true" \
  -H "Authorization: Bearer <YOUR_API_KEY>" \
  -H "User-Agent: MyResearchApp/1.0" \
  -H "Accept: application/json"

# Request raw CSV dataset
curl -X GET "$BASE_URL/research/AAPL/gex_oi?format=csv&start_dte=0&end_dte=30" \
  -H "Authorization: Bearer <YOUR_API_KEY>" \
  -H "User-Agent: MyResearchApp/1.0" \
  -H "Accept: text/csv"
import requests

API_KEY = "YOUR_API_KEY"
BASE_URL = "<your host and version>"
headers = {
    "Authorization": f"Bearer {API_KEY}",
    "User-Agent": "PythonClient/1.0",
    "Accept": "application/json",
}

# Fetch chart asset descriptor
url = f"{BASE_URL}/research/NVDA/iv_mid"
params = {
    "format": "webp",
    "view": "term",
    "start_dte": 0,
    "end_dte": 180
}

response = requests.get(url, headers=headers, params=params)
data = response.json()
image_url = f"https://assets.gexbot.com/{data['url']}"
print(f"Chart available at: {image_url}")
const API_KEY = 'YOUR_API_KEY';
const BASE_URL = '<your host and version>';

async function fetchResearchCSV(ticker: string, metric: string) {
  const url = new URL(`${BASE_URL}/research/${ticker}/${metric}`);
  url.searchParams.set('format', 'csv');
  url.searchParams.set('start_dte', '0');
  url.searchParams.set('end_dte', '98');

  const res = await fetch(url.toString(), {
    headers: {
      'Authorization': `Bearer ${API_KEY}`,
      'User-Agent': 'NodeApp/1.0',
      'Accept': 'text/csv',
    },
  });

  if (!res.ok) {
    throw new Error(`Request failed with status ${res.status}`);
  }

  const csvData = await res.text();
  return csvData;
}

On this page