Get historical stock price data
curl --request GET \
--url https://api.financialdatasets.ai/prices \
--header 'X-API-KEY: <api-key>'import requests
url = "https://api.financialdatasets.ai/prices"
headers = {"X-API-KEY": "<api-key>"}
response = requests.get(url, headers=headers)
print(response.text)const options = {method: 'GET', headers: {'X-API-KEY': '<api-key>'}};
fetch('https://api.financialdatasets.ai/prices', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.financialdatasets.ai/prices",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "GET",
CURLOPT_HTTPHEADER => [
"X-API-KEY: <api-key>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"net/http"
"io"
)
func main() {
url := "https://api.financialdatasets.ai/prices"
req, _ := http.NewRequest("GET", url, nil)
req.Header.Add("X-API-KEY", "<api-key>")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.get("https://api.financialdatasets.ai/prices")
.header("X-API-KEY", "<api-key>")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.financialdatasets.ai/prices")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Get.new(url)
request["X-API-KEY"] = '<api-key>'
response = http.request(request)
puts response.read_body{
"ticker": "<string>",
"prices": [
{
"open": 123,
"close": 123,
"high": 123,
"low": 123,
"volume": 123,
"time": "<string>"
}
],
"next_page_url": "<string>"
}{
"error": "Bad Request",
"message": "Invalid request parameters"
}{
"error": "Unauthorized",
"message": "Invalid API key provided"
}{
"error": "Payment Required",
"message": "This endpoint requires a paid subscription. Please upgrade your plan."
}{
"error": "Not Found",
"message": "Ticker XXXX not found"
}Stock Prices
Stock Price API (Historical OHLCV)
Historical end-of-day stock prices (open, high, low, close, and volume) for 15,000+ US tickers, by day, week, month, or year, with 3+ years of history.
GET
/
prices
Get historical stock price data
curl --request GET \
--url https://api.financialdatasets.ai/prices \
--header 'X-API-KEY: <api-key>'import requests
url = "https://api.financialdatasets.ai/prices"
headers = {"X-API-KEY": "<api-key>"}
response = requests.get(url, headers=headers)
print(response.text)const options = {method: 'GET', headers: {'X-API-KEY': '<api-key>'}};
fetch('https://api.financialdatasets.ai/prices', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.financialdatasets.ai/prices",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "GET",
CURLOPT_HTTPHEADER => [
"X-API-KEY: <api-key>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"net/http"
"io"
)
func main() {
url := "https://api.financialdatasets.ai/prices"
req, _ := http.NewRequest("GET", url, nil)
req.Header.Add("X-API-KEY", "<api-key>")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.get("https://api.financialdatasets.ai/prices")
.header("X-API-KEY", "<api-key>")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.financialdatasets.ai/prices")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Get.new(url)
request["X-API-KEY"] = '<api-key>'
response = http.request(request)
puts response.read_body{
"ticker": "<string>",
"prices": [
{
"open": 123,
"close": 123,
"high": 123,
"low": 123,
"volume": 123,
"time": "<string>"
}
],
"next_page_url": "<string>"
}{
"error": "Bad Request",
"message": "Invalid request parameters"
}{
"error": "Unauthorized",
"message": "Invalid API key provided"
}{
"error": "Payment Required",
"message": "This endpoint requires a paid subscription. Please upgrade your plan."
}{
"error": "Not Found",
"message": "Ticker XXXX not found"
}Overview
The Financial Datasets stock prices API returns historical end-of-day (EOD) prices for a stock ticker: open, high, low, close, and volume (OHLCV), by day, week, month, or year. It covers 15,000+ US tickers with 3+ years of history, updated at the end of each day. The prices come from Databento, our market data partner (data provenance). For the latest price, use the price snapshot endpoint. You can call it as a REST endpoint with an API key, or from Claude, ChatGPT, Cursor, and other AI apps through the MCP server, or pay per request with x402. Pricing starts at $20. The data is perfect for backtesting trading strategies, analyzing price patterns, rendering charts, and more. To get started, please create an account and grab your API key at financialdatasets.ai. You will use the API key to authenticate your API requests.Coverage
| Tickers | Years of Coverage | Updated |
|---|---|---|
| 15,000+ | 3+ years | End of day |
Available Tickers
You can fetch a list of available tickers with aGET request to:
https://api.financialdatasets.ai/prices/tickers/
Required Parameters
ticker— the stock ticker symbol (e.g., AAPL, NVDA)interval—day,week,month, oryearstart_date— start date in YYYY-MM-DD formatend_date— end date in YYYY-MM-DD format
Getting Started
There are only 3 steps for making a successful API call:- Add your API key to the header of the request as
X-API-KEY. - Add the required query params:
ticker,interval,start_date, andend_date. - Execute the API request.
Example
Prices
import requests
# add your API key to the headers
headers = {
"X-API-KEY": "your_api_key_here"
}
# set your query params
ticker = 'AAPL'
interval = 'day' # possible values are {'day', 'week', 'month', 'year'}
start_date = '2025-01-02'
end_date = '2025-01-05'
# create the URL
url = (
f'https://api.financialdatasets.ai/prices/'
f'?ticker={ticker}'
f'&interval={interval}'
f'&start_date={start_date}'
f'&end_date={end_date}'
)
# make API request
response = requests.get(url, headers=headers)
# parse prices from the response
prices = response.json().get('prices')
Example Response
{
"prices": [
{
"ticker": "AAPL",
"open": 243.85,
"close": 243.36,
"high": 244.15,
"low": 241.91,
"volume": 40230800,
"time": "2025-01-02"
},
{
"ticker": "AAPL",
"open": 243.36,
"close": 245.00,
"high": 245.55,
"low": 242.80,
"volume": 38420500,
"time": "2025-01-03"
},
...
]
}
FAQ
How far back do the prices go?
3+ years.Which intervals are available?
day, week, month, and year. Set interval together with start_date and end_date.
Where does the price data come from?
From Databento, our market data partner. Databento delivers real-time and historical market data direct from colocation sites.Can an AI agent use this data?
Yes. Claude, ChatGPT, Cursor, and other MCP clients reach it through the Financial Datasets MCP server. An agent with a wallet can also pay per request with x402, with no account.Authorizations
API key for authentication.
Query Parameters
The stock ticker symbol (e.g. AAPL, MSFT).
The time interval for the price data.
Available options:
day, week, month, year The start date for the price data (format: YYYY-MM-DD).
The end date for the price data (format: YYYY-MM-DD).
Opaque pagination cursor from a previous response's next_page_url. When provided, all other query parameters are ignored: the cursor carries the original request's filters. Treat it as opaque; do not construct or modify it.