In this short guide, we will learn how to fix the Yahoo Finance 429 error ("Too Many Requests") when accessing stock data via API. This common issue occurs when Yahoo Finance detects automated requests without proper browser headers, blocking your API calls with rate limit errors.
Problem: 429 Too Many Requests Error
When making direct API requests to Yahoo Finance, you'll encounter the 429 error with the message "Edge: Too Many Requests" because Yahoo's CDN blocks requests without valid User-Agent headers.
Error Example
import requests
url = "https://query1.finance.yahoo.com/v8/finance/chart/AAPL"
params = {"interval": "1m", "range": "1d", "prepost": "true"}
response = requests.get(url, params=params)
print(f"Status Code: {response.status_code}")
print(f"Error Message: {response.text[:100]}")
Output Result:
Status Code: 429
Error Message: Edge: Too Many Requests
Solution: Add User-Agent Headers
1. Simple Fix: Add Browser User-Agent
Add a User-Agent header to make your request appear as a legitimate browser request, bypassing Yahoo's rate limiting.
import requests
symbol = "TSLA"
url = f"https://query1.finance.yahoo.com/v8/finance/chart/{symbol}"
headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36'
}
params = {"interval": "1m", "range": "1d", "prepost": "true"}
response = requests.get(url, params=params, headers=headers)
data = response.json()
print(f"Status Code: {response.status_code}")
print(f"Symbol: {data['chart']['result'][0]['meta']['symbol']}")
print(f"Current Price: ${data['chart']['result'][0]['meta']['regularMarketPrice']:.2f}")
Output Result:
Status Code: 200
Symbol: TSLA
Current Price: $245.38
2. Complete Headers Setup for Reliability
For production applications, use a complete set of browser headers to avoid detection and rate limiting.
import requests
import time
def get_stock_data(symbol):
url = f"https://query1.finance.yahoo.com/v8/finance/chart/{symbol}"
headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36',
'Accept': 'application/json',
'Accept-Language': 'en-US,en;q=0.9',
'Referer': 'https://finance.yahoo.com/'
}
params = {"interval": "1d", "range": "1mo"}
response = requests.get(url, params=params, headers=headers)
if response.status_code == 200:
return response.json()
else:
return None
stocks = ['AAPL', 'MSFT', 'NVDA']
for stock in stocks:
data = get_stock_data(stock)
if data:
price = data['chart']['result'][0]['meta']['regularMarketPrice']
print(f"{stock}: ${price:.2f}")
time.sleep(1)
Output Result:
AAPL: $185.64
MSFT: $372.55
NVDA: $738.45
3. Rate Limiting Best Practices
Implement request delays and retry logic to avoid hitting rate limits even with proper headers.
import requests
import time
from requests.adapters import HTTPAdapter
from urllib3.util.retry import Retry
def create_session():
session = requests.Session()
retry = Retry(total=3, backoff_factor=1, status_forcelist=[429, 500, 502, 503, 504])
adapter = HTTPAdapter(max_retries=retry)
session.mount('https://', adapter)
session.headers.update({
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36'
})
return session
session = create_session()
url = "https://query1.finance.yahoo.com/v8/finance/chart/GOOGL"
response = session.get(url, params={"interval": "1d", "range": "5d"})
print(f"Request successful: {response.status_code == 200}")
print(f"Data received: {len(response.content)} bytes")
Output Result:
Request successful: True
Data received: 15847 bytes