Download 1-minute, 5-minute and Hourly Intraday Stock Data
FinzData provides intraday bars at 1-minute, 5-minute and hourly intervals for US equities. Access to 1-minute and 5-minute data requires a look-back bundle of 25 years or more, or an Institutional plan, while hourly bars are included in every bundle. Adjustments for splits and dividends can be applied during download, and data can be resampled to custom intervals using pandas.
Updated 2026-10-11. Code on this page was run against live FinzData data before publishing.
Setting up the FinzData client
Begin by installing the FinzData Python client via pip and setting your API key as an environment variable. The client is imported as yf to maintain familiarity with similar libraries.
Authentication is handled automatically through the FINZDATA_API_KEY environment variable, so no API key should be hard-coded in your scripts for security.
import finzdata as yf
import os
# Ensure FINZDATA_API_KEY is set in your environment
# Example: os.environ['FINZDATA_API_KEY'] = 'your-key-here' # Do not hard-code
c = yf.Client()Fetching 1-minute intraday data
Use the c.minutes() method to download 1-minute bars, specifying the symbol, date range, and interval. Adjustments for splits and dividends can be applied using the adjust parameter.
Note that 1-minute data requires either a look-back bundle with 25+ years of history or an Institutional plan; free keys and shorter bundles will return HTTP 403 errors for this interval.
The returned DataFrame includes symbol, timestamp (ts), and OHLCV columns indexed by time.
import finzdata as yf
import pandas as pd
# Needs a look-back bundle or the Institutional plan (free keys get HTTP 403)
c = yf.Client()
# 1-minute data for AAPL, last 10 trading days, split and dividend adjusted
df_1m = c.minutes(
symbol="AAPL",
start="2026-09-25",
end="2026-10-10",
interval="1min",
adjust="all"
)
print(df_1m.head())
print(f"Retrieved {len(df_1m)} rows of 1-minute data")Fetching 5-minute and hourly intraday data
The same c.minutes() method is used for 5-minute and hourly data by changing the interval parameter. Hourly data is available with every look-back bundle, while 5-minute data shares the same 25-year minimum requirement as 1-minute data.
All intraday intervals return data in long format with symbol, ts, open, high, low, close, and volume columns, making it straightforward to process uniformly.
For analysis requiring consistent formatting, consider adding a symbol column if working with multiple tickers.
import finzdata as yf
c = yf.Client()
# 5-minute data (requires 25+ year bundle or Institutional)
df_5m = c.minutes(
symbol="MSFT",
start="2026-09-01",
end="2026-09-30",
interval="5min",
adjust="none" # raw prices; use adjust="all" for split- and dividend-adjusted
)
# Hourly data (available in all bundles)
df_1h = c.minutes(
symbol="MSFT",
start="2026-09-01",
end="2026-09-30",
interval="1hour",
adjust="none" # Raw prices
)Resampling intraday data to higher frequencies
Once downloaded, 1-minute bars can be resampled to 5-minute, 15-minute, or any custom interval using pandas' resample method. This is useful when you need specific frequencies not directly available or want to align multiple instruments.
Resampling requires setting the timestamp as the index and applying aggregation rules: typically 'first' for open, 'max' for high, 'min' for low, 'last' for close, and 'sum' for volume.
This approach ensures you can derive any required interval from the highest-resolution data you have access to, maximizing flexibility in your analysis pipeline.
import finzdata as yf
import pandas as pd
# Needs a look-back bundle or the Institutional plan (free keys get HTTP 403)
c = yf.Client()
# Get 1-minute data
df_1m = c.minutes(
symbol="TSLA",
start="2026-10-01",
end="2026-10-03",
interval="1min",
adjust="all"
)
# Prepare for resampling
df_1m = df_1m.set_index('ts')
# Resample to 15-minute bars
df_15m = df_1m.resample('15min').agg({
'open': 'first',
'high': 'max',
'low': 'min',
'close': 'last',
'volume': 'sum'
}).dropna() # Remove incomplete periods
print(df_15m.head())Understanding data availability and plans
Intraday data availability depends on your subscription: free keys provide only the last 12 months of daily data, while look-back bundles add intraday bars based on tenure. Specifically, 1-minute and 5-minute intervals require bundles of 25 years or more, or an Institutional plan.
Hourly data is included in every look-back bundle regardless of duration, making it the most accessible intraday option. All bundles include daily and hourly bars, with finer granularity unlocking as look-back depth increases.
The Institutional plan ($975 once + $59.95/month) provides immediate access to all data frequencies, including 1-minute bars, along with commercial licensing rights.
# No code needed - this section explains plan requirements
# Refer to https://finzdata.com/pricing for current bundle and pricing detailsBest practices and common pitfalls
Always verify that your plan includes the requested intraday interval before running scripts to avoid authentication errors. Remember that adjusted data (splits and dividends) modifies historical prices to reflect corporate actions, which is essential for accurate return calculations.
When resampling 1-minute bars to 5-minute or hourly bars, aggregate open as first, high as max, low as min, close as last and volume as sum, and drop empty intervals. FinzData timestamps (the ts column) are New York exchange time and pre-market bars start at 04:00, so filter the regular session with between_time("09:30", "15:59") before you resample.
Intraday data volumes can be large; consider filtering to market hours (9:30–16:00 ET) to reduce noise and storage requirements, especially when working with 1-minute data over extended periods.
import finzdata as yf
# Needs 25+ years of look-back or the Institutional plan (free keys get HTTP 403)
c = yf.Client()
df = c.minutes(symbol="AAPL", start="2026-09-01", end="2026-09-30", interval="1min", adjust="all")
# ts is New York exchange time (pre-market bars start at 04:00)
df = df.set_index("ts")
rth = df.between_time("09:30", "15:59") # regular session only
print(f"{len(df)} bars in total, {len(rth)} in regular trading hours")Questions
Do I need a paid plan to access 1-minute intraday data?
Yes, accessing 1-minute intraday bars requires either a look-back bundle with 25 years or more of history or an Institutional plan. Free keys and shorter bundles do not include 1-minute or 5-minute data due to licensing constraints.
Can I adjust intraday data for splits and dividends?
Yes, the adjust parameter in c.minutes() supports 'none' (raw prices) and 'all' (split- and dividend-adjusted). Applying adjustments ensures historical prices reflect corporate actions, which is critical for accurate backtesting and return calculations.
What time zone are FinzData intraday timestamps in?
FinzData intraday timestamps (the ts column) are in New York exchange time, and pre-market bars start at 04:00. Use between_time("09:30", "15:59") to keep the regular session; if you need time-zone-aware data, call tz_localize("America/New_York").
Keep going
- Browse every stock
- 13F Holdings API Python Guide
- Accessing CFTC Commitments of Traders Data with FinzData Python
- Migrating from yfinance to FinzData
- Survivorship Bias Free Stock Data Download
- Point-in-Time Fundamentals and Macro Data for Bias-Free Backtesting
Get a free API key See pricing
Data for research, not investment advice.