# 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](https://gexstream.com/disclaimer) and the [API terms](https://gexstream.com/api-docs#tos) 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 objects entirely):

```
{
  "ticker": "SPY",
  "asof": "2026-07-30T15:42:11Z",
  "spot": 585.42,
  "gex":  { "net": 1.24e9, "ratio": 0.85, "zero_gamma": 580.0,
            "max_strike": 590.0, "min_strike": 570.0 },
  "vgex": { "net": 4.1e8, "ratio": 0.72, "zero_vgamma": 582.0,
            "max_strike": 590.0, "min_strike": 575.0 },
  "flow": { "ratio": 0.42, "net": -1.4e6 },
  "iv":   { "call": 0.142, "put": 0.163, "skew": -0.021 },
  "dex":  { "net": 2.2e9, "ratio": 0.71, "zero_delta": 578.0,
            "max_strike": 585.0, "min_strike": 560.0 },
  "vex":  { "net": -3.0e8, "ratio": 0.31, "zero_vanna": 583.0,
            "max_strike": 600.0, "min_strike": 570.0 },
  "cex":  { "net": 1.1e8, "ratio": 0.64, "zero_charm": 581.0,
            "max_strike": 585.0, "min_strike": 575.0 },
  "oi":   { "total": 1.8e7, "ratio": 0.61, "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/oi plus spot, and omit the dex/vex/cex 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": 0.79, "zero_gamma": 574.0,
                "max_strike": 580.0, "min_strike": 565.0 },
      "vgex": { ... },
      "flow": { "ratio": 0.58, "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": 0.59,
               "max_strike": 600.0, "min_strike": 550.0 }
    },
    ...
  ]
}
```

- Rows are hourly buckets; t is the *start* of the hour the row covers (UTC, RFC 3339). A session's last row starts one hour before the close (15:00 ET, which is 19:00Z in daylight time and 20:00Z in standard time; earlier on a half day), and no row starts at or after the close. 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](https://gexstream.com/docs).

| Family | Fields | Tier |
| --- | --- | --- |
| gex | net, ratio, zero_gamma, max_strike, min_strike | Flow, Quant |
| vgex | net, ratio, zero_vgamma, max_strike, min_strike | Flow, Quant |
| flow | ratio, net | Flow, Quant |
| iv | call, put, skew | Flow, Quant |
| volume | calls, puts (history rows only) | Flow, Quant (history) |
| dex | net, ratio, zero_delta, max_strike, min_strike | Quant |
| vex | net, ratio, zero_vanna, max_strike, min_strike | Quant |
| cex | net, ratio, zero_charm, max_strike, min_strike | Quant |
| oi | total, ratio, max_strike, min_strike, pct_chg (snapshot only) | Flow, Quant |

spot and asof/t appear at the top level for all tiers. On an expiration day, vex and cex stop being computable about 5 minutes before the close; until the next session they hold their last computed value.

### Limits & quotas

| Limit | Flow | Quant |
| --- | --- | --- |
| Snapshot requests / day | 800 | 3,000 |
| History requests / day | 15 | 50 |
| Distinct tickers / day | 2 | 4 |
| Request pacing | 1 request/second per key, burst of 3 | 1 request/second per key, burst of 3 |
| Concurrency | 1 in-flight request per key | 1 in-flight request per key |
| Clients | 1 at a time (IP-bound; 10-minute idle release) | 1 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 UTC time (RFC 3339) at which the metrics in the response were read from the calculation store. It is *not* the time the response was sent, and it is not a market event timestamp. That read can be up to about 5 minutes old when the response goes out. Two responses for the same ticker with the same timestamp carry the same metrics, so use it to order and de-duplicate your own pulls. The spot price is the exception: it is read on every request, so it can differ between two responses that share a timestamp.
- In history rows, t *is* the data timestamp: the start of the hour 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 |
| --- | --- | --- |
| 405 | method not allowed | Only GET is supported. |
| 400 | User-Agent header required | Identify your client. |
| 429 | rate limit exceeded | Per-IP burst limit, evaluated before authentication. Retry-After: 1. |
| 401 | invalid or revoked API key | Missing, unknown, rotated-away, or revoked key. |
| 409 | key in use from another client | Another address holds the binding. Carries retry_after_seconds; release the binding from the account modal to move sooner. |
| 429 | rate limit exceeded | A request is already in flight on this key, or per-key pacing (1/s, burst 3) exceeded. Retry-After: 1. |
| 403 | API access requires a Flow or Quant subscription / API access requires a paid Flow or Quant subscription | Tier gate, identical on both endpoints. The second form means the subscription is not currently paid — a trial, for example. |
| 400 | invalid days parameter | History only: days must be 30, 60, or 90. |
| 404 | unknown ticker | Not in the tracked universe, or tracked but with no data to return. |
| 429 | daily request quota exceeded / daily ticker limit exceeded | Daily budgets spent. Carries resets_at (midnight ET) and the quota headers. |
| 503 | service temporarily unavailable | Transient backend condition (including just after a restart). Retry with backoff. |

### Terms of use

Accepted when you create a key; the [full Terms and Conditions](https://gexstream.com/terms) (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.**

### AI assistants (Claude and ChatGPT)

PAID FLOW & QUANT

Connect Claude or ChatGPT to your GEXStream account and ask about gamma exposure in plain language. The assistant calls read-only GEXStream tools through the Model Context Protocol (MCP). You connect it by signing in and approving access on a GEXStream consent screen (OAuth): no API key is needed, and the assistant never sees your password. A connection lasts up to 90 days, or until it goes 30 days without use, and resetting your GEXStream password disconnects every assistant; the assistant then asks you to reconnect.

https://gexstream.com/mcp · server URL

- **Claude (web and desktop):** GEXStream is in [Claude's connector directory](https://claude.ai/directory/gexstream): open it, click Connect, then approve access on the GEXStream consent screen. If the directory is not available on your plan, add it as a custom connector instead: [Open the prefilled connector form](https://claude.ai/customize/connectors?modal=add-custom-connector&connectorName=GEXStream&connectorUrl=https%3A%2F%2Fgexstream.com%2Fmcp), confirm it, then connect and approve access on the GEXStream consent screen. On Claude Team and Enterprise plans, only organization Owners can add custom connectors.
- **Claude Code:** add the server from a terminal, then run /mcp inside Claude Code, select gexstream and choose Authenticate. Because Claude Code runs on your computer, the consent screen says so; approve only a connection you started yourself.

```
claude mcp add --transport http gexstream https://gexstream.com/mcp
```

- **ChatGPT:** GEXStream is in the [ChatGPT plugin directory](https://chatgpt.com/plugins/plugin_asdk_app_6adce196b4148191a5e6cb064176f3c1): open Plugins in ChatGPT, search for GEXStream, click Connect, then approve access on the GEXStream consent screen. Where the directory is not available, choose Custom Tool and enter the server URL above with OAuth as its authentication.

The assistant can call five tools, all read-only:

| Tool | What it does |
| --- | --- |
| get_gex_snapshot | The latest metrics for one ticker (up to about 5 minutes old), with the families your plan includes. Uses one snapshot request. |
| get_gex_history | History for one ticker over 30, 60 or 90 days, built from hourly bars: one row per trading session by default, or every hourly bar of the most recent 1 to 5 sessions. Uses one history request. |
| list_tickers | The tickers the tools accept (the tracked universe), with an optional prefix filter. Uses no daily limit. |
| get_usage | Your remaining snapshot requests, history requests and new tickers for today, the tickers already used, and when the limits reset. Uses no daily limit. |
| describe_fields | What each field in the snapshot and history results means. Uses no daily limit. |

- **Limits are shared with the REST API.** The snapshot and history tools draw on the same daily budgets as your API key: the same snapshot and history request quotas in the [limits table](https://gexstream.com/api-docs#limits), and the same distinct-ticker breadth (Flow 2, Quant 4 per US Eastern day). There is one budget per account, however many assistants you connect.
- An assistant may make several tool calls to answer one question, so a budget can run down faster than the number of questions you ask. Ask it to call get_usage to see what is left.
- **Up to three connections per account.** Each assistant is one connection, and so is each computer running Claude Code. Connecting another disconnects the oldest. A connector removed only inside the assistant still counts until you disconnect it in the account menu.
- **Eligibility is the same as for the API:** a paid Flow or Quant subscription. Trials are excluded.
- **What is shared:** the market data the assistant requests and your daily usage. The assistant cannot change your account, plan or settings, and never receives your password or payment information. Anthropic and OpenAI process tool results under their own terms and privacy policies.
- **Personal use only.** The [Terms and Conditions](https://gexstream.com/terms) apply to connector data as they do to the API: do not share or publicly display GEXStream data, including in shared chats, links, projects or published files.
- **To disconnect,** open the account menu, choose manage account, and use Disconnect in the AI assistants row. That is the reliable way to revoke access: removing the connector in your assistant's settings may not notify GEXStream, so do both if you want the assistant's stored access ended immediately.

---

Canonical page: https://gexstream.com/api-docs
