GuidesSTOCK APIS

Free stock market APIs for a JavaScript web app

We called 11 stock data APIs from Chromium and Firefox on 26 October 2026: 6 send CORS headers and work from fetch() with no backend, namely Alpha Vantage, Twelve Data, Finnhub, Financial Modeling Prep (FMP), Massive and Marketstack. Tiingo, EODHD and Yahoo Finance send no CORS headers, and Stooq and IEX Cloud are no longer usable. Twelve Data and Alpha Vantage have demo keys you can try without signing up.

Results by API

From a page on http://127.0.0.1 in Chromium 156 and Firefox 157, plus curl, we called each API with fetch() using a demo key where one exists and a fake key otherwise, then checked whether the browser could read the response. We also ran each URL through the cors.dev free proxy. For APIs outside finance, see free public APIs.

Stock APIs called with fetch() from a browser page, checked October 2026
APIKeyCORSFree limitData on the free plan
Alpha Vantageapikey=, demo works for IBMYes25 requests a dayEnd of day, live data is paid
Twelve Dataapikey=, demo works for AAPLYes8 a minute, 800 a dayReal-time US, no display rights
Finnhubtoken= in the URLYes60 a minuteReal-time US quotes
Financial Modeling Prepapikey=, no demo keyYes250 a dayEnd of day, 5 years
Massive (Polygon.io)apiKey=Yes5 a minuteEnd of day, 2 years
Marketstackaccess_key=Yes100 a monthEnd of day, 1 year
Tiingotoken=No50 an hour, 1,000 a dayDaily prices
EOD Historical Dataapi_token=No20 a dayEnd of day, 1 year
Yahoo Finance chartNoneNo, works through the proxyNo published limitUnofficial endpoint
StooqNoneBlocked by a browser checkNot usableCSV downloads blocked
IEX CloudNo longer issuedHost does not answerShut down in August 2024None

Finnhub accepts your API key as ?token= in the URL or as an X-Finnhub-Token header, but its CORS preflight response sets Access-Control-Allow-Headers to Origin only, so from a browser the key has to go in the URL. Twelve Data allows the Authorization header in its preflight too. Polygon.io is now Massive: polygon.io redirects to massive.com, and both api.polygon.io and api.massive.com answer the same API, so older Polygon code still runs.

Try it with a demo key

Twelve Data's docs use apikey=demo, which works for AAPL. Ask for MSFT with the demo key and you get HTTP 401 with "status":"error" and a message that the demo key is only for initial familiarity.

Twelve Data: 30 daily closes with the demo key
const url = new URL('https://api.twelvedata.com/time_series');
url.search = new URLSearchParams({ symbol: 'AAPL', interval: '1day', outputsize: '30', apikey: 'demo' });

const data = await fetch(url).then((response) => response.json());
if (data.status === 'error') throw new Error(`${data.code}: ${data.message}`);

console.table(data.values.map(({ datetime, close }) => ({ date: datetime, close: Number(close) })));

Alpha Vantage's apikey=demo works for IBM only. Any other symbol returns HTTP 200 with an Information message telling you to claim a free key. Alpha Vantage reports problems this way, so check the body, not response.ok.

Alpha Vantage: a quote with the demo key
const url = 'https://www.alphavantage.co/query?function=GLOBAL_QUOTE&symbol=IBM&apikey=demo';
const data = await fetch(url).then((response) => response.json());

// Alpha Vantage reports quota and key problems with HTTP 200 and an Information field
const quote = data['Global Quote'];
if (!quote) throw new Error(data.Information ?? JSON.stringify(data));

console.log(quote['01. symbol'], quote['05. price'], quote['07. latest trading day']);

EODHD has a demo token that works for AAPL.US, TSLA.US, VTI.US, AMZN.US, MCD.US and BTC-USD.CC, but it does not help in a browser, because EODHD sends no Access-Control-Allow-Origin header. FMP has no working demo key: apikey=demo returns HTTP 401 "Invalid API KEY".

Free limits and licenses

Each provider's pricing page on 26 October 2026 listed these terms for free accounts:

  • Alpha Vantage: 25 requests per day. Real-time and 15-minute delayed US data are premium-only, so the free tier only gives you end-of-day and historical data.
  • Twelve Data (Basic): 8 API credits per minute and 800 per day, covering real-time US stocks and ETFs, forex and crypto. The license is restricted to "internal non-display usage", so showing the data in an app requires a paid plan.
  • Finnhub: 60 API calls per minute (with a 30 calls per second cap across all plans) for personal use. It includes real-time US stock quotes, while historical candles require a premium plan.
  • Financial Modeling Prep (FMP Basic): 250 calls per day and 500 MB of bandwidth per 30 days, with end-of-day data and 5 years of history. Displaying or redistributing FMP data requires a separate licensing agreement.
  • Massive (Stocks Basic): 5 API calls per minute for individual use, with end-of-day data and 2 years of history.
  • Marketstack (Free): 100 requests per month for non-commercial use, with HTTPS included, end-of-day data and 1 year of history.
  • Tiingo (Starter): 50 requests per hour, 1,000 per day, 500 unique symbols per month and 1 GB of bandwidth a month, for internal use only. No CORS, so it needs a server.
  • EODHD (Free): 20 API calls per day, with end-of-day data and 1 year of history. No CORS either.

Your free key is public in the browser

When you ship a free API key in frontend JavaScript, every visitor can see it in the browser's network tab. Anyone can copy that key and burn through your quota: 25 requests a day at Alpha Vantage, 800 a day at Twelve Data.

On a public site, do not call keyed stock APIs from the browser. Fetch prices on a server or in a scheduled job, cache them, and serve the cached JSON; API proxy without a server compares the ways to do that. For a personal dashboard or a tool on GitHub Pages, let each user paste their own free key, and keep it in localStorage on their device.

Finnhub: a real-time quote with the user's own key
const apiKey = localStorage.getItem('finnhubKey') ?? prompt('Paste your Finnhub API key');
localStorage.setItem('finnhubKey', apiKey);

// The X-Finnhub-Token header fails the CORS preflight, so the key goes in the URL
const url = `https://finnhub.io/api/v1/quote?symbol=AAPL&token=${encodeURIComponent(apiKey)}`;
const response = await fetch(url);
const data = await response.json();
if (response.status === 401) localStorage.removeItem('finnhubKey');
if (!response.ok) throw new Error(data.error ?? `HTTP ${response.status}`);

console.log({ price: data.c, change: data.d, percent: data.dp, previousClose: data.pc });

The cors.dev free proxy is no way around this. It refuses URLs that carry keys, such as apikey= or token=, with HTTP 400 and X-Cors-Error: credential_in_url. That is on purpose: a private key should never pass through a public relay. Authorization headers and API keys through a proxy explains what Pro forwards and why it does not make a key secret. Tiingo and EODHD keys belong on a server.

No key at all: Yahoo Finance, Stooq and IEX Cloud

Yahoo Finance's chart endpoint takes no key and returns JSON over GET, but sends no CORS headers. Called directly from our servers it answered 429 Too Many Requests; through the cors.dev free proxy it returned HTTP 200 and about 1.7 KB of JSON for 5 days of AAPL. The Yahoo Finance API guide has the endpoints, ranges and code.

Stooq used to be the keyless CSV fallback. Now every Stooq URL, the old CSV downloads included, answers with a JavaScript proof-of-work browser check, and the old quote CSV URL returns 404, so neither fetch() nor a proxy gets data. IEX Cloud shut down in August 2024, and on our test day cloud.iexapis.com accepted no connections.

For Bitcoin and other coins, see the crypto price API guide.

Good questions.

Is there a free stock API that works from JavaScript without a backend?

Yes. Alpha Vantage, Twelve Data, Finnhub, FMP, Massive and Marketstack all send CORS headers and work directly from browser fetch(). Yahoo Finance's chart endpoint also works without a backend through the cors.dev free proxy; see the Yahoo Finance API guide.

Which stock API has the most generous free tier?

It depends on whether you count requests per minute, requests per day or real-time data. Finnhub allows 60 calls per minute with real-time US stock quotes (no historical candles), while Twelve Data allows 8 credits per minute and 800 per day with real-time US stocks (for internal non-display use). For end-of-day data, Tiingo allows 1,000 requests per day (no CORS), FMP allows 250 per day, Massive allows 5 per minute, Alpha Vantage allows 25 per day, EODHD allows 20 per day (no CORS) and Marketstack allows 100 per month.

Is there a stock API with no API key?

Yahoo Finance's chart endpoint needs no key. It sends no CORS headers, but returns HTTP 200 through the cors.dev free proxy. Alpha Vantage and Twelve Data also offer apikey=demo for testing without signing up, restricted to IBM on Alpha Vantage and AAPL on Twelve Data.

Why does fetch() fail on Tiingo or EODHD?

Neither API sends the Access-Control-Allow-Origin response header that browsers require. Tiingo answers HTTP 200 to OPTIONS preflight requests without that header, and EODHD sends Access-Control-Allow-Methods and Access-Control-Allow-Headers while leaving out Access-Control-Allow-Origin.

Is the Alpha Vantage demo key enough for an app?

No, apikey=demo on Alpha Vantage only returns data for IBM. Requesting any other symbol returns an HTTP 200 response containing an "Information" message that tells you to claim a free key.

Is it safe to put my stock API key in frontend code?

Only on a page nobody else uses: every visitor can read a key in frontend JavaScript and use up your quota. For a public site, fetch the data on a server or scheduled job and cache it, or have users paste their own key in the browser.