gexstream api Open the app →
API Documentation

The GEXStream REST API

Key-authenticated, server-to-server access to the same gamma-exposure metrics the dashboard shows — a live snapshot per ticker, and hourly history for research.

For personal use. API access is included with paid Flow and Quant subscriptions for personal, non-commercial use. Data is for education only, not financial advice — read the full disclaimer and the API terms below.

Overview

Two endpoints, both read-only:

GET /api/v1/snapshot/{ticker} · paid Flow & Quant
GET /api/v1/history/{ticker}?days=30 · paid Flow & Quant

The base URL is https://gexstream.com. All responses are JSON. Only tickers in the tracked screener universe are served — anything else is a 404.

Get your key from the app: sign in, open the account menu, choose api, and create a key in the API Access section. The key is shown exactly once — store it in a secrets manager, not in code.

Authentication

Send your key in the X-API-Key header on every request. Keys are never accepted as query parameters — they must not appear in URLs or server logs. A User-Agent header is required; requests without one are rejected with 400.

curl -H "X-API-Key: gxs_your_key_here" \ -H "User-Agent: my-strategy/1.0" \ https://gexstream.com/api/v1/snapshot/SPY
  • One active key per account. Creating a new key (rotation) invalidates the old one immediately.
  • Revoking a key takes effect immediately, not at a cache expiry.
  • One client at a time: your key binds to the first client address that uses it. Requests from a second address get a 409 with retry_after_seconds until the binding lapses (10 minutes idle) or you release it from the account modal. IPv6 clients are bound at their /64 prefix.

GET /api/v1/snapshot/{ticker}

PAID FLOW & QUANT

The latest computed metrics for one ticker. Values refresh on a rolling cache and may be up to 5 minutes old — polling faster than that returns the same data.

Example response (Quant; Flow responses omit the dex/vex/cex/oi objects entirely):

{
  "ticker": "SPY",
  "asof": "2026-07-30T15:42:11Z",
  "spot": 585.42,
  "gex":  { "net": 1.24e9, "ratio": 1.85, "zero_gamma": 580.0,
            "max_strike": 590.0, "min_strike": 570.0 },
  "vgex": { "net": 4.1e8, "ratio": 1.32, "zero_vgamma": 582.0,
            "max_strike": 590.0, "min_strike": 575.0 },
  "flow": { "ratio": 0.92, "net": -1.4e6 },
  "iv":   { "call": 0.142, "put": 0.163, "skew": -0.021 },
  "dex":  { "net": 2.2e9, "ratio": 1.10, "zero_delta": 578.0,
            "max_strike": 585.0, "min_strike": 560.0 },
  "vex":  { "net": -3.0e8, "ratio": 0.85, "zero_vanna": 583.0,
            "max_strike": 600.0, "min_strike": 570.0 },
  "cex":  { "net": 1.1e8, "ratio": 1.05, "zero_charm": 581.0,
            "max_strike": 585.0, "min_strike": 575.0 },
  "oi":   { "total": 1.8e7, "ratio": 1.22, "max_strike": 600.0,
            "min_strike": 550.0, "pct_chg": 1.4 }
}
  • spot is omitted (not zero) when no fresh price is available — it is only served from the last 15 minutes.
  • oi.pct_chg is omitted until the prior-session baseline is known.
  • The response schema only ever grows — fields are added, never renamed or removed.

GET /api/v1/history/{ticker}

PAID FLOW & QUANT

Hourly history for one ticker. One query parameter: days, which must be 30, 60, or 90 (default 90). Any other value is a 400.

Example response (Quant; Flow rows carry gex/vgex/flow/iv/volume plus spot, and omit the dex/vex/cex/oi objects entirely — the same family split as the snapshot):

GET /api/v1/history/SPY?days=30

{
  "ticker": "SPY",
  "resolution": "1h",
  "days": 30,
  "rows": [
    {
      "t": "2026-07-01T14:00:00Z",
      "spot": 578.10,
      "gex":  { "net": 9.8e8, "ratio": 1.61, "zero_gamma": 574.0,
                "max_strike": 580.0, "min_strike": 565.0 },
      "vgex": { ... },
      "flow": { "ratio": 1.05, "net": 2.1e6 },
      "iv":   { "call": 0.151, "put": 0.170, "skew": -0.019 },
      "volume": { "calls": 812345, "puts": 640321 },
      "dex": { ... }, "vex": { ... }, "cex": { ... },
      "oi":  { "total": 1.7e7, "ratio": 1.18,
               "max_strike": 600.0, "min_strike": 550.0 }
    },
    ...
  ]
}
  • Rows are hourly buckets; t is the bucket timestamp (UTC, RFC 3339). New data lands hourly.
  • volume (per-hour call/put volume sums) exists only in history, and oi.pct_chg exists only in snapshots.
  • A family object is omitted from a row when that hour has no data for it.

Field reference

Metrics are grouped into family objects. Your tier decides which families you receive — a family you are not entitled to is absent, never zeroed. For what each metric means and how it is computed, see the metrics documentation.

Family Fields Tier
gexnet, ratio, zero_gamma, max_strike, min_strikeFlow, Quant
vgexnet, ratio, zero_vgamma, max_strike, min_strikeFlow, Quant
flowratio, netFlow, Quant
ivcall, put, skewFlow, Quant
volumecalls, puts (history rows only)Flow, Quant (history)
dexnet, ratio, zero_delta, max_strike, min_strikeQuant
vexnet, ratio, zero_vanna, max_strike, min_strikeQuant
cexnet, ratio, zero_charm, max_strike, min_strikeQuant
oitotal, ratio, max_strike, min_strike, pct_chg (snapshot only)Quant

spot and asof/t appear at the top level for all tiers.

Limits & quotas

Limit Flow Quant
Snapshot requests / day8003,000
History requests / day1550
Distinct tickers / day24
Request pacing1 request/second per key, burst of 3
Concurrency1 in-flight request per key
Clients1 at a time (IP-bound; 10-minute idle release)
  • Trial accounts have no API access. The API requires an active paid Flow or Quant subscription; keys cannot be created during a trial. Accounts in a past-due grace period keep access.
  • Daily quotas reset at midnight US/Eastern (calendar day, not a rolling 24 hours).
  • Only successful (2xx) responses consume quota — errors and rejections cost you nothing.
  • The distinct-ticker count is cumulative for the day: once a ticker is counted, repeat requests for it are always allowed; a new ticker past the cap is refused even with request quota remaining.

Every 200 (and daily-quota 429) carries your remaining budget:

X-RateLimit-Remaining-Day: 2994
X-Tickers-Remaining-Day: 3
X-RateLimit-Reset: 2026-07-31T04:00:00Z

Freshness & asof

  • Snapshot: values may be up to 5 minutes old. Polling faster than once per ~5 minutes per ticker returns the same underlying data.
  • History: hourly buckets; new rows land hourly.
  • asof is the server time the response was generated (UTC, RFC 3339). It is not a data timestamp — the metrics behind it may be up to the cache age older. Use it to order and de-duplicate your own pulls, not to timestamp market events.
  • In history rows, t is the data timestamp: the hourly bucket the row aggregates.
  • Metrics are computed during US market hours; outside them, snapshots serve the last computed state.

Errors

Every failure returns a JSON envelope with an error message, plus retry_after_seconds on 409 and resets_at on daily-quota 429s. Checks run in a fixed order — the table below is that precedence, top to bottom (e.g. a bad method on a bound-elsewhere key is a 405, not a 409):

Status Message Meaning
405method not allowedOnly GET is supported.
400User-Agent header requiredIdentify your client.
429rate limit exceededPer-IP burst limit, evaluated before authentication. Retry-After: 1.
401invalid or revoked API keyMissing, unknown, rotated-away, or revoked key.
409key in use from another clientAnother address holds the binding. Carries retry_after_seconds; release the binding from the account modal to move sooner.
429rate limit exceededA request is already in flight on this key, or per-key pacing (1/s, burst 3) exceeded. Retry-After: 1.
403API access requires a Flow or Quant subscription / API access requires a paid Flow or Quant subscriptionTier gate, identical on both endpoints. The second form means the subscription is not currently paid — a trial, for example.
400invalid days parameterHistory only: days must be 30, 60, or 90.
404unknown tickerNot in the tracked universe.
429daily request quota exceeded / daily ticker limit exceededDaily budgets spent. Carries resets_at (midnight ET) and the quota headers.
503service temporarily unavailableTransient backend condition (including just after a restart). Retry with backoff.

Terms of use

Accepted when you create a key; the full Terms and Conditions (Section 14) govern. In summary:

  • Personal use only. Your subscription and your key are for you, not for a product, team, or service.
  • No redistribution. Do not resell, relay, or share data obtained through the API.
  • No public display of API-derived data — no public dashboards, feeds, bots, or posts built on it.
  • One client at a time. The binding limit above is a term, not just a mechanism.
  • Keys are revocable at our discretion, at any time and without notice.
  • API responses may contain key-specific identifying characteristics.