Overview Authentication Rate Limits Endpoints WebSocket Errors Plans
API Reference

Greeks Analytics API

Greeks provides derived options analytics — not raw market data. Every endpoint computes actionable signals in real-time: Greeks, GEX, unusual flow, max pain, and full market overviews.

Base URL
https://greeks.pro
All responses are JSON with Content-Type: application/json.

What you can build

  • Real-time options flow scanners and unusual activity alerts
  • Gamma exposure dashboards for market makers and traders
  • Max pain calculators for expiration week strategies
  • Full-stack options analytics platforms with live WebSocket feeds
  • Algorithmic signals from IV surface and term structure data

Common Parameters

All analytics endpoints share these query parameters:

ParameterTypeRequiredDescription
symbol
string
string Required Any US stock or ETF ticker symbol (e.g. AAPL, SPY, TSLA). Case-insensitive.
expiration
int64 | "all"
string Optional Unix timestamp for a specific expiration date, or "all" to include every available expiration. Omit for nearest expiry only.

Security

Authentication

All API requests require a valid API key. Keys follow the format grk_<48 hex characters> and are scoped to your user account and plan tier.

Never expose your API key in client-side code or public repositories. Keys can be rotated at any time from your Settings page.

Methods

You can authenticate using any of three methods. HTTP header methods are preferred.

Header (preferred)
X-API-Key: grk_abc123…
Bearer Token
Authorization: Bearer grk_abc123…
Query Parameter (WebSocket only)
?key=grk_abc123…
Required for WebSocket connections where headers cannot be set.
# Using X-API-Key header (recommended) curl https://greeks.pro/api/analytics/maxpain \ -H "X-API-Key: grk_your_key_here" \ -G -d "symbol=AAPL"
const res = await fetch('https://greeks.pro/api/analytics/maxpain?symbol=AAPL', { headers: { 'X-API-Key': 'grk_your_key_here' } }); const data = await res.json(); console.log(data);
import requests res = requests.get( 'https://greeks.pro/api/analytics/maxpain', headers={'X-API-Key': 'grk_your_key_here'}, params={'symbol': 'AAPL'} ) data = res.json()

Quotas

Rate Limits & Quotas

Rate limits are enforced per user account using a sliding 60-second window. Daily quotas reset at midnight UTC.

Response Headers

Every response includes rate limit metadata in the headers:

HeaderDescription
X-RateLimit-LimitMaximum requests allowed per 60-second window
X-RateLimit-RemainingRequests remaining in current window
X-Daily-LimitMaximum requests allowed per day
X-Daily-RemainingRequests remaining today
Retry-AfterSeconds to wait before retrying (only on 429 responses)

Plan Limits

Plan Requests / min Requests / day
Free 10 600
Trader 60 5,000
Pro 300 50,000
Institutional 1,000 Unlimited
When rate limited (429), wait the number of seconds in Retry-After before retrying. Exponential backoff is recommended for server-side integrations.

REST API

Endpoints

All endpoints are read-only GET requests that return derived analytics computed from live options chain data.

GET /api/analytics/maxpain Free+
Returns the max pain strike for each expiration — the price at which options sellers collectively pay out the least. Useful for identifying magnetic price levels heading into expiration week.
Parameters
ParameterTypeRequiredDescription
symbol string Required Ticker symbol (e.g. AAPL)
expiration int64 | "all" Optional Unix timestamp or "all" for all expirations
curl "https://greeks.pro/api/analytics/maxpain?symbol=NDAQ&expiration=all" \ -H "X-API-Key: grk_your_key_here"
const res = await fetch( 'https://greeks.pro/api/analytics/maxpain?symbol=NDAQ&expiration=all', { headers: { 'X-API-Key': 'grk_your_key_here' } } ); const { symbol, spotPrice, results } = await res.json();
import requests data = requests.get( 'https://greeks.pro/api/analytics/maxpain', headers={'X-API-Key': 'grk_your_key_here'}, params={'symbol': 'NDAQ', 'expiration': 'all'} ).json()
Response Schema
{ "symbol": "NDAQ", "spotPrice": 81.40, "timestamp": 1748390400, "results": [ { "expiration": 1748390400, // unix timestamp "dte": 7, // days to expiration "maxPainStrike": 80, // strike in dollars "totalPainAtMax": 1284000, // aggregate pain at max pain strike "spotDistance": 1.40, // spot - maxPainStrike "spotDistancePct": 1.72 // percent distance from spot } ] }
GET /api/analytics/greeks Trader+
Returns full Black-Scholes Greeks for every options contract on the chain: delta, gamma, theta, vega, rho, implied volatility, theoretical price and mispricing. Ideal for building scanner tools or risk dashboards.
Parameters
ParameterTypeRequiredDescription
symbol string Required Ticker symbol
expiration int64 | "all" Optional Filter to a specific expiration date
curl "https://greeks.pro/api/analytics/greeks?symbol=NDAQ&expiration=1773964800" \ -H "X-API-Key: grk_your_key_here"
const res = await fetch( 'https://greeks.pro/api/analytics/greeks?symbol=NDAQ&expiration=1773964800', { headers: { 'X-API-Key': 'grk_your_key_here' } } ); const { contracts } = await res.json(); // Filter ITM calls with delta > 0.5 const hotCalls = contracts.filter(c => c.type === 'call' && c.delta > 0.5);
import requests data = requests.get( 'https://greeks.pro/api/analytics/greeks', headers={'X-API-Key': 'grk_your_key_here'}, params={'symbol': 'NDAQ', 'expiration': 1773964800} ).json()
Response Schema
{ "symbol": "NDAQ", "spotPrice": 81.40, "timestamp": 1748390400, "contracts": [ { "contractSymbol": "NDAQ250516C00080000", "type": "call", "strike": 80, "expiration": 1747353600, "dte": 7, "iv": 0.2341, // implied volatility (decimal) "delta": 0.6821, "gamma": 0.0821, "theta": -0.0412, // daily theta decay "vega": 0.0523, "rho": 0.0128, "theoreticalPrice": 1.92, "mispricing": 0.08, // market - theoretical "inTheMoney": true } ] }
GET /api/analytics/gex Trader+
Returns Gamma Exposure (GEX) and Delta Exposure (DEX) by strike. GEX quantifies the hedging pressure market makers must apply — positive GEX stabilizes price, negative GEX amplifies moves. The gamma flip level is the strike where net GEX crosses zero.
Parameters
ParameterTypeRequiredDescription
symbol string Required Ticker symbol
expiration int64 | "all" Optional Recommended: use "all" for accurate aggregate GEX
curl "https://greeks.pro/api/analytics/gex?symbol=NDAQ&expiration=all" \ -H "X-API-Key: grk_your_key_here"
const res = await fetch( 'https://greeks.pro/api/analytics/gex?symbol=NDAQ&expiration=all', { headers: { 'X-API-Key': 'grk_your_key_here' } } ); const { totalNetGEX, gammaFlip, strikes } = await res.json(); const regime = totalNetGEX > 0 ? 'Stable' : 'Volatile';
import requests data = requests.get( 'https://greeks.pro/api/analytics/gex', headers={'X-API-Key': 'grk_your_key_here'}, params={'symbol': 'NDAQ', 'expiration': 'all'} ).json() regime = 'Stable' if data['totalNetGEX'] > 0 else 'Volatile'
Response Schema
{ "symbol": "NDAQ", "spotPrice": 81.40, "timestamp": 1748390400, "totalNetGEX": 4821000, // positive = dealers long gamma (market stabilizing) "gammaFlip": 78.50, // strike where net GEX = 0 "strikes": [ { "strike": 80, "callGEX": 2100000, // call gamma exposure (positive) "putGEX": -840000, // put gamma exposure (negative) "netGEX": 1260000, "callDEX": 980000, "putDEX": -610000, "netDEX": 370000 } ] }
GET /api/analytics/flow Trader+
Detects unusual options activity by scanning for contracts where volume significantly exceeds open interest — a signal that new positions are being opened. Returns ranked signals with severity classification.
Parameters
ParameterTypeRequiredDescription
symbol string Required Ticker symbol
expiration int64 | "all" Optional Use "all" to scan all expirations for maximum coverage
curl "https://greeks.pro/api/analytics/flow?symbol=NDAQ&expiration=all" \ -H "X-API-Key: grk_your_key_here"
const res = await fetch( 'https://greeks.pro/api/analytics/flow?symbol=NDAQ&expiration=all', { headers: { 'X-API-Key': 'grk_your_key_here' } } ); const { signals } = await res.json(); // Get high-severity signals only const highAlert = signals.filter(s => s.severity === 'high');
import requests data = requests.get( 'https://greeks.pro/api/analytics/flow', headers={'X-API-Key': 'grk_your_key_here'}, params={'symbol': 'NDAQ', 'expiration': 'all'} ).json() high_signals = [s for s in data['signals'] if s['severity'] == 'high']
Response Schema
{ "symbol": "NDAQ", "spotPrice": 81.40, "timestamp": 1748390400, "signals": [ { "contractSymbol": "NDAQ250516C00085000", "type": "call", // "call" | "put" "strike": 85, "expiration": 1747353600, "dte": 7, "volumeOIRatio": 8.42, // volume / open interest "iv": 0.3812, "signal": "unusual_volume", // "unusual_volume" | "opening_position" "severity": "high" // "high" | "medium" } ] }
GET /api/analytics/overview Pro+
Returns the full market overview in a single call — sentiment analysis, GEX summary, max pain, expected moves, IV term structure, IV surface, and top unusual flow. This is the most comprehensive endpoint and powers the full dashboard.
Parameters
ParameterTypeRequiredDescription
symbol string Required Ticker symbol
expiration int64 | "all" Optional Recommended: "all" for full accuracy across all metrics
curl "https://greeks.pro/api/analytics/overview?symbol=NDAQ&expiration=all" \ -H "X-API-Key: grk_your_key_here"
const res = await fetch( 'https://greeks.pro/api/analytics/overview?symbol=NDAQ&expiration=all', { headers: { 'X-API-Key': 'grk_your_key_here' } } ); const overview = await res.json(); console.log(overview.sentiment.sentiment); // "bullish" | "bearish" | "neutral"
import requests overview = requests.get( 'https://greeks.pro/api/analytics/overview', headers={'X-API-Key': 'grk_your_key_here'}, params={'symbol': 'NDAQ', 'expiration': 'all'} ).json()
Response Schema
{ "symbol": "NDAQ", "spotPrice": 81.40, "timestamp": 1748390400, "riskFreeRate": 0.0525, "sentiment": { "sentiment": "bullish", // "bullish" | "bearish" | "neutral" "putCallVolumeRatio": 0.612, "putCallOIRatio": 0.784 }, "gexSummary": { "totalNetGEX": 4821000, "gammaFlip": 78.50 }, "maxPain": [ { "expiration": 1747353600, "dte": 7, "maxPainStrike": 80, "totalPainAtMax": 1284000, "spotDistance": 1.40, "spotDistancePct": 1.72 } ], "expectedMoves": [ { "dte": 7, "atmStrike": 81, "lowerBound": 79.20, "upperBound": 83.60, "moveAmount": 2.20, "movePercent": 2.70 } ], "termStructure": [ { "dte": 7, "atmIV": 0.2341, "expiration": 1747353600 } ], "ivSurface": [ /* 2D array of {strike, dte, iv} */ ], "topFlow": [ { "contractSymbol": "NDAQ250516C00085000", "type": "call", "strike": 85, "dte": 7, "volumeOIRatio": 8.42, "iv": 0.3812, "signal": "unusual_volume", "severity": "high" } ] }
WS /ws/analytics Pro+
Real-time analytics streaming over WebSocket. The server pushes fresh derived data at your configured interval — no polling required. One active session per API key. See the WebSocket Protocol section for the full protocol reference.
Connection URL
wss://greeks.pro/ws/analytics?key=grk_your_key_here
Subscribe Message
{ "symbol": "AAPL", // required "interval": 5, // seconds between pushes (min: 3, default: 5) "subscribe": ["overview", "gex", "flow"] // omit for all streams }

Real-time

WebSocket Protocol

The analytics WebSocket provides a continuous push feed of derived data. Connect, subscribe, and receive structured JSON messages — no polling loop required.

One session per API key. Opening a second connection closes the first. If you receive close code 4001, do not attempt to reconnect — another session is already active.

Message Types

All server-to-client messages are JSON objects with a kind field:

kindWhen sentData field
subscribedImmediately after successful subscriptionObject with interval and streams[]
overviewEvery interval (if subscribed)Full overview object (same as REST)
greeksEvery interval (if subscribed)Greeks object
gexEvery interval (if subscribed)GEX object
flowEvery interval (if subscribed)Flow signals
maxpainEvery interval (if subscribed)Max pain results
errorOn validation or server errorError message string

Close Codes

CodeMeaningAction
1000Normal closeSafe to reconnect
1001Server shutdownReconnect with backoff
1006Abnormal / connection lostReconnect with backoff
4001Duplicate session detectedDo NOT reconnect

Full Client Example

class GreeksStream { constructor(apiKey, symbol, opts = {}) { this.apiKey = apiKey; this.symbol = symbol; this.interval = opts.interval || 5; this.streams = opts.streams || ['overview', 'gex', 'flow']; this.handlers = {}; this.ws = null; this._noDuplicate = false; } on(kind, fn) { this.handlers[kind] = fn; return this; // chainable } connect() { const url = `wss://greeks.pro/ws/analytics?key=${this.apiKey}`; this.ws = new WebSocket(url); this.ws.onopen = () => { this.ws.send(JSON.stringify({ symbol: this.symbol, interval: this.interval, subscribe: this.streams })); }; this.ws.onmessage = (e) => { const msg = JSON.parse(e.data); if (this.handlers[msg.kind]) { this.handlers[msg.kind](msg.data, msg); } }; this.ws.onclose = (e) => { if (e.code === 4001) { console.warn('Duplicate session — not reconnecting'); this._noDuplicate = true; return; } // Reconnect with backoff for other close codes if (!this._noDuplicate) { setTimeout(() => this.connect(), 3000); } }; this.ws.onerror = (err) => console.error('WS error', err); } disconnect() { if (this.ws) this.ws.close(); } } // Usage const stream = new GreeksStream('grk_your_key_here', 'AAPL', { interval: 5, streams: ['overview', 'gex', 'flow'] }); stream .on('subscribed', (data) => console.log('Streaming', data.streams)) .on('overview', (data) => updateDashboard(data)) .on('gex', (data) => updateGEXChart(data.strikes)) .on('flow', (data) => renderFlowTable(data.signals)) .on('error', (msg) => console.error('Server error:', msg)) .connect();

Errors

Error Codes

All errors return a JSON body: {"error": "message"}. HTTP status codes follow standard conventions.

Status Meaning Recommended Action
400 Invalid or missing request parameters Inspect error field and fix request params (e.g. missing symbol)
401 Invalid or missing API key Check the key format (grk_…) and redirect user to login if needed
403 Insufficient plan for this endpoint Show an upgrade prompt — user's plan doesn't include this endpoint
403 Symbol limit reached User has reached the max tracked symbols for their plan; prompt to upgrade
429 Rate limit exceeded Read Retry-After header and wait that many seconds before retrying
500 Internal server error (data fetch failed) Retry with exponential backoff — usually a transient data source unavailability

Error Handling Example

async function fetchWithRetry(url, key, maxRetries = 3) { for (let attempt = 0; attempt < maxRetries; attempt++) { const res = await fetch(url, { headers: { 'X-API-Key': key } }); if (res.status === 429) { const wait = parseInt(res.headers.get('Retry-After') || '60'); await new Promise(r => setTimeout(r, wait * 1000)); continue; } if (res.status === 401) { window.location.href = '/login'; throw new Error('Unauthorized'); } if (res.status === 403) { const { error } = await res.json(); showUpgradePrompt(error); throw new Error(error); } if (res.status >= 500 && attempt < maxRetries - 1) { await new Promise(r => setTimeout(r, Math.pow(2, attempt) * 1000)); continue; } return res.json(); } }
import time, requests def fetch_with_retry(url, key, max_retries=3): for attempt in range(max_retries): r = requests.get(url, headers={'X-API-Key': key}) if r.status_code == 429: wait = int(r.headers.get('Retry-After', 60)) time.sleep(wait) continue if r.status_code == 403: raise PermissionError(r.json()['error']) if r.status_code >= 500 and attempt < max_retries - 1: time.sleep(2 ** attempt) continue r.raise_for_status() return r.json()

Pricing

Plans & Limits

Each plan unlocks progressively more endpoints and higher rate limits. All plans can access any supported US stock or ETF ticker symbol.

Free Trader Pro Institutional
Requests / min 10 60 300 1,000
Requests / day 600 5,000 50,000 Unlimited
Max Pain
Greeks
GEX / DEX
Unusual Flow
Full Overview
WebSocket Stream
SLA / Priority Support
View Pricing & Upgrade