REST API Reference

Developer API Documentation

Programmatic access to StashGamma end-of-day stock data — pick a date range, get back real OHLCV bars for any U.S.-listed symbol, going back 15 years.

Overview

The Developer API has one endpoint: daily end-of-day OHLCV bars for a symbol, over a date range you choose. All requests are read-only (GET) and require an API key. Base URL:

https://www.stashgamma.com/api/dataapi/v1

Authentication

Pass your API key via either header — both are accepted, use whichever your HTTP client/library makes more convenient:

X-Api-Key: sg_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

# or

Authorization: Bearer sg_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

Get a key from Profile → Developer API — the Free tier is instant and self-serve, no payment required.*

* No credit card, ever — subject to the fair-use throttling limits below (300 req/hour · 800/day · 4,000/week). Keys that repeatedly exceed a window may see additional cooldown beyond the standard Retry-After.

Rate limits

PlanPricePer hourPer dayPer week
Free$03008004000

Every response (success or error) includes rate-limit headers so you can self-throttle without guessing:

X-RateLimit-Plan: free
X-RateLimit-Limit-Hour: 300
X-RateLimit-Remaining-Hour: 297
X-RateLimit-Limit-Day: 800
X-RateLimit-Remaining-Day: 790
X-RateLimit-Limit-Week: 4000
X-RateLimit-Remaining-Week: 3950

A 429 also includes a standard Retry-After header (seconds until the exceeded window resets).

GET /v1/eod/{symbol}

Daily OHLCV bars for one symbol, optionally sliced to a date range.

ParamTypeRequiredNotes
symbolpathyese.g. QQQ, case-insensitive
fromquerynoYYYY-MM-DD, default = 30 days before to
toquerynoYYYY-MM-DD, default = today

Example request

curl -H "X-Api-Key: YOUR_API_KEY" \
  "https://www.stashgamma.com/api/dataapi/v1/eod/QQQ?from=2026-07-01&to=2026-08-01"

Example response — 200 OK

{
  "symbol": "QQQ",
  "from": "2026-07-01",
  "to": "2026-08-01",
  "count": 23,
  "bars": [
    { "date": "2026-07-01", "open": 611.2, "high": 614.8, "low": 609.5, "close": 613.1, "volume": 28451200 },
    { "date": "2026-07-02", "open": 613.4, "high": 615.0, "low": 611.9, "close": 614.2, "volume": 24310500 }
  ]
}

Code examples

Working, copy-pasteable examples for curl, Python, JavaScript, Node.js, Java, Go, Excel, and a Jupyter notebook are in the step-by-step quickstart guide. Downloadable source for all of them (plus MCP client examples):

LanguageFile
Pythoneod_quickstart.py
Node.jseod-quickstart.mjs
JavaStashGammaEodExample.java
Gomain.go
Jupyter / pandasstashgamma_eod_quickstart.ipynb
MCP (Python & Node clients)mcp/

Every example reads the key from an environment variable (STASHGAMMA_API_KEY) and demonstrates backing off on a 429 using the Retry-After header — copy that pattern into your own client.

MCP endpoint (for AI agents)

If you're wiring StashGamma data into Claude or another MCP-capable agent instead of calling the REST endpoint directly, point it at the Streamable HTTP MCP endpoint below. Same API key, same rate-limit bucket as /v1/eod/{symbol} — a tool call and a REST call against the same key draw from the same hour/day/week quota.

https://www.stashgamma.com/api/dataapi/mcp

Auth is the same X-Api-Key / Authorization: Bearer header, sent alongside the JSON-RPC POST body — most MCP client configs let you set custom headers per server.

Some hosted AI assistants only give you a box for a server URL, with no way to add a header. For those, put the key in the URL instead — either form works, and both are treated exactly like the header:

https://www.stashgamma.com/api/dataapi/mcp/YOUR_API_KEY
https://www.stashgamma.com/api/dataapi/mcp?key=YOUR_API_KEY

A URL with a key in it is a secret — it can end up in that assistant's saved settings and logs. If one leaks, rotate the key from Profile → Developer API and the old URL stops working immediately. When a header is also sent, the header wins.

Three read-only tools are exposed:

ToolArgumentsReturns
get_eod_datasymbol (required), from/to (optional, YYYY-MM-DD)Same OHLCV bar shape as the REST endpoint
get_latest_quotesymbol (required)Most recent daily bar plus change vs the previous close
get_api_usagenonePlan, used/remaining requests per hour/day/week — does not count against quota

Stateless — every call is a single JSON response (no SSE stream, no session to keep alive). Rate-limit/auth errors come back as a tool result with isError: true rather than an HTTP error, so your agent can see and react to the reason (e.g. "retry in Ns") directly.

Step-by-step setup, ready-to-drop config files, and code samples for each client:

  • Claude Code / Claude Desktop — drop a url + headers entry into your MCP server config.
  • OpenAI — the Responses API takes this same endpoint as a built-in type: "mcp" tool.
  • Hosted assistants with a URL-only connector form — paste the key-in-URL form above and choose "no authentication" if asked.
  • ChatGPT Custom GPTs — connect via an OpenAPI schema (Actions) instead of MCP; a ready-made schema is provided.
  • Your own agent/script — call get_eod_data directly via the official Python or Node.js MCP SDK.

Full walkthrough for each: Connect via MCP.

Error codes

StatusWhenExample body
400Missing symbol in path, or `from`/`to` malformed/inverted{"error":"\"from\" must be on or before \"to\"","success":false}
401Missing API key (no X-Api-Key / Authorization header){"error":"Missing API key. Pass it via the X-Api-Key header or Authorization: Bearer <key>.","success":false}
401Malformed, unknown, expired, suspended, or revoked key{"error":"This API key has expired — resubscribe to get a new one","success":false}
404No EOD data for that symbol{"error":"No EOD data for symbol ZZZZ","success":false}
429Hour/day/week rate limit exceeded for your plan{"error":"Rate limit exceeded for the hour window (101/100). Try again in 1800s.","success":false}

Status & support

Live uptime and per-endpoint health (tested daily, automatically) are on the API status page. Questions or issues: contact support.