Twelve Data
Twelve Data
REST and WebSocket API for stocks, forex, crypto, ETFs, and bonds with 100+ technical indicators.
Coverage
Markets by plan: 85 (Ultra), 76 (Pro), 27 (Grow), 3 (free Basic). The free Basic plan card lists real-time US equities and ETFs, real-time forex and real-time crypto, for internal testing and development only. Real-time and historical prices, fundamentals, earnings and 100+ technical indicators, depending on plan.
Verdict
Good for prototyping indicator-based strategies (100+ technical indicators). Free Basic is for testing and development only: Twelve Data bars production use, display to users and commercial use of free-tier data, so a live trading system needs a paid plan.
Get the free weekly email
Free weekly email of newly verified free data. Unsubscribe by emailing us.
By entering your email and clicking Subscribe, you agree to receive the Signal Lab weekly email from Quantum Data Technologies Ltd., 3200-650 West Georgia Street, Vancouver, BC V6B 4P7, Canada (signal-lab@qdt.ai). You can unsubscribe at any time: reply "unsubscribe" to any email or write to signal-lab@qdt.ai. See our Privacy Policy.
Use in your agent
Load Twelve Data daily prices into pandas and Parquet for testing. Checked against the provider's documentation on Oct 29, 2026.
Access
- A Basic API key is required. Put it in TWELVE_DATA_API_KEY.
- Free data is for internal testing, evaluation or development only.
Request
curl 'https://api.twelvedata.com/time_series?symbol=AAPL&interval=1day&outputsize=100&apikey='$TWELVE_DATA_API_KEYFormat
JSON: status and metadata plus values in reverse chronological order. OHLC and volume values are strings.
Load into pandas and Parquet
Needs Python 3 with requests, pandas and pyarrow.
"""Twelve Data daily AAPL prices -> pandas -> Parquet. Free tier testing only."""
import os
import requests
import pandas as pd
params = {"symbol": "AAPL", "interval": "1day", "outputsize": 100,
"apikey": os.environ["TWELVE_DATA_API_KEY"]}
r = requests.get("https://api.twelvedata.com/time_series", params=params, timeout=30)
r.raise_for_status()
body = r.json()
if body.get("status") == "error":
raise RuntimeError(body["message"])
df = pd.DataFrame(body["values"])
df["datetime"] = pd.to_datetime(df["datetime"])
for column in ("open", "high", "low", "close", "volume"):
df[column] = pd.to_numeric(df[column])
df = df.sort_values("datetime")
df.to_parquet("twelve_data_aapl_daily.parquet", index=False)
print(len(df), "rows", df["datetime"].min().date(), "to", df["datetime"].max().date())Needs a personal API key; not run.
Limits
- Basic: eight API credits per minute and 800 credits per day.
- Credits are weighted by endpoint and symbol count.
Quirks
- Sort values by datetime before time-series work.
- An API error is a JSON object with status=error, code and message.
- The free plan is not for display or production.
Terms and attribution
- Basic data may be used internally only for testing, evaluation or development.
- It may not be displayed, shared externally or used in production.
- Free-tier data may not be used commercially.
Sources
- https://twelvedata.com/pricing: “8 (800 a day)”
- https://twelvedata.com/pricing: “Data may be used internally for testing, evaluation, or development purposes only.”
- https://twelvedata.com/terms: “Use Free Tier data for commercial purposes”
Information and education only. Not financial, investment, legal or tax advice. Listings can be inaccurate, incomplete or out of date and are provided "as is". Free tiers, limits and licenses belong to each provider and can change, so check the provider's own terms before you rely on them. Terms & Disclaimer