Guides

Free Stock Market Data API Python Tutorial

FinzData's free tier provides the last 12 months of daily US stock bars, full COT history, SEC fundamentals as reported, and latest values for 158 macro series. You get 1,000 API calls per day with no credit card required. This guide shows how to get started and when a paid plan becomes necessary.

Updated 2026-10-11. Code on this page was run against live FinzData data before publishing.

Getting Your Free API Key

Visit api.finzdata.com to sign up for a free key. No credit card is needed. After registration, set the environment variable FINZDATA_API_KEY to your key value. The Python client reads this variable automatically.

Verify your key works by running a simple test: import finzdata as yf; print(yf.Ticker('AAPL').history(period='1mo')). If you see a DataFrame with Open, High, Low, Close, Volume columns, your key is valid.

The free tier does not require bundling or institutional access for basic data retrieval within its limits.

import finzdata as yf
import os
os.environ['FINZDATA_API_KEY'] = 'your_free_key_here'  # Set this once in your environment
print(yf.Ticker('AAPL').history(period='1mo'))

Pulling a Year of Daily Bars

Use yf.Ticker().history() with period='1y' to get the last 12 months of daily adjusted prices. This works for any active NYSE or Nasdaq stock and returns Open, High, Low, Close, Volume indexed by Date.

The free tier limits this to the most recent 12 months only. For example, if today is 2026-10-11, you get data from 2025-10-11 to 2026-10-10. Delisted stocks are not accessible in the free tier for history beyond 12 months.

To get unadjusted or split-only adjusted data, use the Client class with c.prices() and specify the adjust parameter.

import finzdata as yf
data = yf.Ticker('MSFT').history(period='1y')
print(data.head())
print(f'Rows: {len(data)}')

Accessing Commitments of Traders (COT) Data

The free tier includes full historical COT data for all report types. Use yf.Client().cot() with a report type and either code= or market= to fetch data. For example, legacy futures-only gold futures uses code='088691'.

Always prefer code= over market= when possible, as market= does a case-insensitive substring match and may return unintended results (e.g., 'GOLD' matches Micro Gold and Goldman Sachs index).

The COT data includes 136 columns such as date, open_interest_all, noncomm_positions_long_all, and comm_positions_short_all. No look-back bundle is needed for COT in the free tier.

import finzdata as yf
c = yf.Client()
gold_cot = c.cot(report='legacy_fo', code='088691', start='2020-01-01')
print(gold_cot[['date', 'open_interest_all', 'noncomm_positions_long_all']].head())

Fetching SEC Fundamentals

Use c.fundamentals() to get as-reported SEC XBRL data. Specify a ticker and concept like 'Revenues' or 'NetIncomeLoss'. The free tier returns all available filings as reported, without point-in-time filtering.

Each row includes cik, entity, concept, value, start, end, fy, fp, form, and filed date. This reflects what was publicly reported at the time of filing, not revised or restated values.

Point-in-time fundamentals (as_of) require a look-back bundle or Institutional plan, as they need historical vintages of XBRL data.

import finzdata as yf
c = yf.Client()
rev = c.fundamentals(ticker='AAPL', concept='Revenues')
print(rev[['entity', 'concept', 'value', 'filed']].head())

Getting Latest Macro Values

The free tier provides the latest values for 158 macro series from FRED/ALFRED. Use c.macro() with a series_id like 'CPIAUCSL' and no vintage parameter to get the most recent published value.

Each return includes series_id, date, and value. For example, c.macro('CPIAUCSL') gives the latest CPI-U series. No as_of or vintage parameters are needed for latest values.

Access to historical vintages, point-in-time macro data, or the full revision history requires a look-back bundle.

import finzdata as yf
c = yf.Client()
cpi = c.macro('CPIAUCSL')
print(cpi[['series_id', 'date', 'value']].tail())

Rate Limits and Free Tier Boundaries

The free tier allows 1,000 API calls per day. This applies to all endpoints: history, dividends, splits, COT, fundamentals, macro, and institutional_ownership. Exceeding this returns HTTP 429.

Data limits are stricter: daily bars are limited to the last 12 months. Intraday (1m, 5m), point-in-time fundamentals, macro vintages, liquidity data, and 13F history require a look-back bundle or Institutional plan.

You can always access the latest quarter of 13F ownership via c.institutional_ownership() for free, but historical holdings need paid access.

import finzdata as yf
c = yf.Client()
# This uses 1 call
c.macro('CPIAUCSL')
# This uses 1 call per ticker
yf.Ticker(['AAPL', 'MSFT']).history(period='1mo')
# Check your usage via account dashboard at https://finzdata.com/

When You Need a Paid Plan

Upgrade to a look-back bundle if you need: daily bars beyond 12 months, intraday bars (1m or 5m require 25+ years of history), delisted stock history, point-in-time fundamentals, macro vintages, liquidity data (FED_NET_LIQUIDITY, US_M2), or full 13F history.

The first 5 years of history costs $195 one-time, then $95 per additional 5 years, plus $19.95/month for daily updates. Hourly bars are included in all bundles; 1m and 5m need 25 years or more.

The Institutional plan at $975 one-time + $59.95/month includes everything: all history, daily updates, a commercial license, and no look-back restrictions.

Questions

Can I get intraday 1-minute data on the free tier?

No, 1-minute and 5-minute intraday bars require a look-back bundle with at least 25 years of history or an Institutional plan. Hourly bars are available with any bundle.

Does the free tier include delisted stock data like Lehman Brothers?

No, accessing delisted names' history beyond 12 months requires a look-back bundle. The free tier only provides the last 12 months for active stocks.

Is SEC fundamental data point-in-time available for free?

No, c.fundamentals() with an as_of parameter requires a look-back bundle or Institutional plan. The free tier only provides as-reported fundamentals without time travel.

How do I check my daily API usage?

The free tier resets your 1,000-call daily allowance at midnight UTC.