A complete walkthrough — from zero to a parsed array of daily OHLCV bars — using StashGamma's free EOD data API. No card required for any of this.*
* No credit card, ever — the free key is throttled under a fair-use policy of 300 requests/hour, 800/day, and 4,000/week (see Step 5).
Sign up, then go to Profile → Developer API and click "Get free key". Your key looks like sg_live_....
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"
import requests
resp = requests.get(
"https://www.stashgamma.com/api/dataapi/v1/eod/QQQ",
params={"from": "2026-07-01", "to": "2026-08-01"},
headers={"X-Api-Key": "YOUR_API_KEY"},
)
bars = resp.json()["bars"]
print(bars[0]) # {'date': '2026-07-01', 'open': 611.2, 'high': 614.8, ...}Plain fetch — no dependencies, works in any modern browser or a client-side React/Vue/Svelte component.
const res = await fetch(
"https://www.stashgamma.com/api/dataapi/v1/eod/QQQ?from=2026-07-01&to=2026-08-01",
{ headers: { "X-Api-Key": "YOUR_API_KEY" } }
);
const { bars } = await res.json();
console.log(bars[0]); // { date: '2026-07-01', open: 611.2, high: 614.8, ... }Node 18+ has fetch built in, so the browser snippet above works unchanged in a .mjs file or any ESM-configured project. For an older Node runtime, or if you're already using axios elsewhere in the codebase:
// npm install axios
const axios = require('axios');
async function getEodBars(symbol, from, to) {
const { data } = await axios.get(
`https://www.stashgamma.com/api/dataapi/v1/eod/${symbol}`,
{
params: { from, to },
headers: { 'X-Api-Key': process.env.STASHGAMMA_API_KEY },
}
);
return data.bars;
}
getEodBars('QQQ', '2026-07-01', '2026-08-01').then((bars) => {
console.log(bars[0]); // { date: '2026-07-01', open: 611.2, high: 614.8, ... }
});Keep the key out of source control — read it from an environment variable (process.env.STASHGAMMA_API_KEY) rather than hardcoding it.
Java 11+'s built-in java.net.http.HttpClient — no third-party HTTP library required.
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
public class StashGammaEodExample {
public static void main(String[] args) throws Exception {
HttpClient client = HttpClient.newHttpClient();
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create(
"https://www.stashgamma.com/api/dataapi/v1/eod/QQQ?from=2026-07-01&to=2026-08-01"))
.header("X-Api-Key", System.getenv("STASHGAMMA_API_KEY"))
.GET()
.build();
HttpResponse<String> response =
client.send(request, HttpResponse.BodyHandlers.ofString());
System.out.println(response.statusCode()); // 200
System.out.println(response.body()); // {"symbol":"QQQ","bars":[...]}
}
}Pair with a JSON library (Jackson, Gson) to deserialize response.body() into a typed Bar[] instead of parsing raw strings.
Standard library only — net/http and encoding/json.
package main
import (
"encoding/json"
"fmt"
"net/http"
"os"
)
type EodResponse struct {
Symbol string `json:"symbol"`
Bars []struct {
Date string `json:"date"`
Open float64 `json:"open"`
High float64 `json:"high"`
Low float64 `json:"low"`
Close float64 `json:"close"`
Volume int64 `json:"volume"`
} `json:"bars"`
}
func main() {
req, _ := http.NewRequest("GET",
"https://www.stashgamma.com/api/dataapi/v1/eod/QQQ?from=2026-07-01&to=2026-08-01", nil)
req.Header.Set("X-Api-Key", os.Getenv("STASHGAMMA_API_KEY"))
resp, err := http.DefaultClient.Do(req)
if err != nil {
panic(err)
}
defer resp.Body.Close()
var eod EodResponse
json.NewDecoder(resp.Body).Decode(&eod)
fmt.Printf("%+v\n", eod.Bars[0])
}For research or backtesting, load the bars straight into a pandas DataFrame and plot close price against volume:
import pandas as pd
import requests
resp = requests.get(
"https://www.stashgamma.com/api/dataapi/v1/eod/QQQ",
params={"from": "2025-08-01", "to": "2026-08-01"},
headers={"X-Api-Key": "YOUR_API_KEY"},
)
df = pd.DataFrame(resp.json()["bars"])
df["date"] = pd.to_datetime(df["date"])
df = df.set_index("date").sort_index()
df["daily_return"] = df["close"].pct_change()
df["close"].plot(title="QQQ close (via StashGamma EOD API)")Full runnable notebook (price/volume chart, rolling volatility column, retry-on-429 handling) — download stashgamma_eod_quickstart.ipynb.
No macros, no add-ins — Excel's built-in Power Query can call the API and drop the bars straight into a table that refreshes on demand (Data → Get Data → From Other Sources → Blank Query, then Advanced Editor):
let
Symbol = "QQQ",
From = "2026-07-01",
To = "2026-08-01",
ApiKey = "YOUR_API_KEY",
Url = "https://www.stashgamma.com/api/dataapi/v1/eod/" & Symbol
& "?from=" & From & "&to=" & To,
Source = Json.Document(
Web.Contents(Url, [Headers=[#"X-Api-Key"=ApiKey]])
),
Bars = Source[bars],
ToTable = Table.FromList(Bars, Splitter.SplitByNothing(), null, null, ExtraValues.Error),
Expanded = Table.ExpandRecordColumn(
ToTable, "Column1", {"date", "open", "high", "low", "close", "volume"},
{"Date", "Open", "High", "Low", "Close", "Volume"}
)
in
ExpandedPrefer a plain formula over Power Query? Excel's native =WEBSERVICE() / =FILTERXML() combo works for a quick single-cell pull too, but Power Query is the better fit for anything you plan to refresh or chart, since it lands as a real table.
For Google Sheets instead: =IMPORTDATA() can't send a custom X-Api-Key header, so use an =IMPORTJSON() custom function or a small Apps Script UrlFetchApp.fetch() call that sets the header explicitly.
Every response carries X-RateLimit-Remaining-* headers for the hour/day/week windows. If you hit the free tier's limit you'll get a 429 with a Retry-After header — back off for that many seconds and retry. Full field-by-field reference is in the API documentation.
Free forever, no credit card — get a key and make your first call in minutes.
Get Started FreeFree Stock Data API
Start here — the free tier, no card required, 300 requests/hour.
Historical Stock Data API
15 years of daily OHLCV across U.S.-listed tickers, for backtesting & research.
Free Stock Market APIs Compared
How the free tier stacks up against Alpha Vantage, IEX, and others.
OHLCV Data API
What OHLCV data is and exactly how the response is shaped.
MCP Server for Stock Data
Connect Claude, OpenAI, ChatGPT, or another MCP-capable agent directly to the data.
Full API Documentation
Auth, endpoint reference, rate-limit headers, and error codes.
Ready to try it? Get your free API key — no card required.