Ethereum Price API: The Complete Guide for Crypto Traders
Master the Ethereum price API: fetch real-time ETH/USD rates, gas fees, and historical data using free APIs like CoinGecko. Includes Python code examples.
Master the Ethereum price API: fetch real-time ETH/USD rates, gas fees, and historical data using free APIs like CoinGecko. Includes Python code examples.
If you're serious about trading ETH on Binance, Coinbase, or any other exchange, you already know that being even a few seconds late to a price move can cost you real money. That's why traders who build their own tools — alerts, bots, dashboards — reach for the Ethereum price API as their first building block. It's the raw feed that everything else runs on. This guide walks you through the best options available right now, how to actually use them in code, and how to avoid the common mistakes that trip up most beginners.
An Ethereum price API is a web service that returns current (and sometimes historical) ETH price data in a machine-readable format — almost always JSON. You send an HTTP request to an endpoint, and you get back a structured response with the current price, market cap, volume, and whatever else the provider decides to include. The get ethereum price api pattern is straightforward: hit a URL, parse the JSON, use the number. But beneath that simplicity there's real nuance — rate limits, data freshness, supported currency pairs, and authentication requirements that vary widely between providers.
For most traders, the primary use case is clear: they want to know what 1 ETH is worth in USD right now. But as strategies get more sophisticated, you'll also need the ethereum gas price api to estimate transaction costs, the ethereum historical price api to backtest strategies, and potentially multiple data sources to cross-reference prices across Bybit, OKX, and other venues. Understanding the full landscape matters before you write a single line of code.
The free ethereum price api market is more mature than most people realize. You don't need to pay anything to get solid, reliable ETH price data — at least at moderate request volumes. Here are the main providers worth knowing about, along with what actually differentiates them in practice.
| Provider | Free Tier | Rate Limit | Auth Required | Historical Data |
|---|---|---|---|---|
| CoinGecko | Yes | 30 req/min | No (Demo key optional) | Yes, up to 365 days |
| CoinMarketCap | Yes | 333 req/day | Yes (API key) | Limited on free plan |
| Binance API | Yes | 1200 req/min | No (public endpoints) | Yes (OHLCV klines) |
| Etherscan | Yes | 5 req/sec | Yes (free key) | On-chain data only |
| Kraken API | Yes | Generous | No (public endpoints) | Yes (OHLCV) |
| Gate.io API | Yes | 900 req/min | No (public endpoints) | Yes (candlestick data) |
The coingecko ethereum price api is the go-to starting point for most developers. It's generous, well-documented, and doesn't require authentication for basic requests — you can call it right now without registering for anything. CoinMarketCap is more enterprise-focused but has a usable free tier if you register for an API key. For exchange-native price feeds, the Binance public API is arguably the best in the industry: fast, reliable, and essentially unrestricted on read-only market data endpoints. Gate.io also offers a solid public API if you want a second exchange-side source.
Always use at least two data sources for any production trading system. If CoinGecko experiences a delay or goes down, your bot shouldn't be flying blind. Cross-reference with an exchange API like Binance or Kraken as a fallback — the implementation cost is low, and the risk reduction is significant.
The simplest way to pull an ethereum api price feed into your application is via the CoinGecko public endpoint. No API key required, no signup, no configuration. Here's the most basic version to confirm the concept works:
import requests
def get_eth_price_usd() -> float:
url = "https://api.coingecko.com/api/v3/simple/price"
params = {
"ids": "ethereum",
"vs_currencies": "usd"
}
response = requests.get(url, params=params, timeout=10)
data = response.json()
return data["ethereum"]["usd"]
price = get_eth_price_usd()
print(f"ETH/USD: ${price:,.2f}")
That works in development, but it's going to fail silently in production. No error handling, no timeout recovery, no retry logic. Rate limiting alone will break it within minutes of sustained use. Here's the version you actually want to deploy — it handles the 429 rate limit response, timeouts, and unexpected errors, while also pulling additional market context like 24h change:
import requests
import time
from typing import Optional
COINGECKO_API = "https://api.coingecko.com/api/v3"
# Register a free demo key at coingecko.com for higher rate limits
API_KEY: Optional[str] = None # Set to "your_demo_api_key" if available
def get_ethereum_price(
currencies: list = ["usd", "btc"],
max_retries: int = 3
) -> Optional[dict]:
headers = {}
if API_KEY:
headers["x-cg-demo-api-key"] = API_KEY
for attempt in range(max_retries):
try:
response = requests.get(
f"{COINGECKO_API}/simple/price",
params={
"ids": "ethereum",
"vs_currencies": ",".join(currencies),
"include_24hr_change": "true",
"include_market_cap": "true",
"include_24hr_vol": "true"
},
headers=headers,
timeout=10
)
response.raise_for_status()
return response.json()["ethereum"]
except requests.exceptions.Timeout:
print(f"Timeout on attempt {attempt + 1}/{max_retries}")
time.sleep(2 ** attempt) # exponential backoff
except requests.exceptions.HTTPError as e:
if e.response.status_code == 429: # Rate limited
wait = 60 * (attempt + 1)
print(f"Rate limited. Waiting {wait}s before retry...")
time.sleep(wait)
else:
print(f"HTTP error: {e}")
return None
except Exception as e:
print(f"Unexpected error: {e}")
return None
return None
# Usage
data = get_ethereum_price()
if data:
print(f"ETH/USD: ${data['usd']:,.2f}")
print(f"ETH/BTC: {data['btc']:.6f}")
print(f"24h change: {data['usd_24h_change']:.2f}%")
print(f"24h volume: ${data['usd_24h_vol']:,.0f}")
print(f"Market cap: ${data['usd_market_cap']:,.0f}")
This is the production-ready version. The retry loop with exponential backoff keeps your application alive even when the API is having a rough moment. The 429 handling specifically is important — CoinGecko will rate-limit aggressively if you're on the free tier without a demo key, and crashing on every limit hit is what kills most naive implementations. Notice we're also extracting 24h change, volume, and market cap — free bonus data that can feed additional filters in your signal logic.
If you're trading DeFi protocols, bridging between chains, or executing on-chain transactions, gas prices are as important as ETH's spot price. A trade that looks profitable at first glance can become a loss if gas fees consume 30–40% of the margin — which happened constantly during the 2021 bull run when gas spiked above 500 gwei. Platforms like OKX and Bybit handle this automatically for their centralized order books, but the moment you step into on-chain execution, gas becomes your problem to manage. The ethereum gas price api lets you factor transaction costs into your decision-making before you commit.
Etherscan provides a dedicated gas oracle that returns current slow, standard, and fast gas prices in gwei. Here's how to use it alongside an ETH spot price feed to calculate the real USD cost of any transaction before execution:
import requests
ETHERSCAN_API_KEY = "your_etherscan_api_key" # Free at etherscan.io/apis
COINGECKO_API = "https://api.coingecko.com/api/v3"
def get_gas_prices_gwei() -> dict:
"""Fetch current gas prices from Etherscan gas oracle."""
params = {
"module": "gastracker",
"action": "gasoracle",
"apikey": ETHERSCAN_API_KEY
}
response = requests.get(
"https://api.etherscan.io/api",
params=params,
timeout=10
)
data = response.json()
if data["status"] != "1":
raise ValueError(f"Etherscan error: {data['message']}")
result = data["result"]
return {
"slow": int(result["SafeGasPrice"]),
"standard": int(result["ProposeGasPrice"]),
"fast": int(result["FastGasPrice"])
}
def get_eth_spot() -> float:
r = requests.get(
f"{COINGECKO_API}/simple/price",
params={"ids": "ethereum", "vs_currencies": "usd"},
timeout=10
)
return r.json()["ethereum"]["usd"]
def calculate_tx_cost_usd(gas_limit: int = 21000) -> None:
"""Print transaction cost breakdown at current gas prices."""
eth_price = get_eth_spot()
gas = get_gas_prices_gwei()
print(f"ETH price: ${eth_price:,.2f} | Gas limit: {gas_limit:}\n")
for speed, gwei in gas.items():
eth_cost = (gwei * 1e-9) * gas_limit # gwei -> ETH
usd_cost = eth_cost * eth_price
print(f" {speed:>8}: {gwei:>4} gwei = {eth_cost:.6f} ETH = ${usd_cost:.3f}")
# Simple ETH transfer = 21,000 gas
calculate_tx_cost_usd(gas_limit=21000)
# Uniswap swap ≈ 120,000–150,000 gas
calculate_tx_cost_usd(gas_limit=130000)
For complex DeFi interactions — swaps, liquidity adds, loan repayments — gas limits can reach 150,000 to 500,000 units, not 21,000. Always estimate gas before executing via eth_estimateGas (web3.py) or the Etherscan contract interaction estimator. Underestimating gas limit causes failed transactions where you still pay the fee.
Anyone building a trading strategy needs historical data to stress-test their assumptions before committing real capital. The ethereum historical price api on CoinGecko gives you up to 365 days of data on the free tier, with automatic granularity: hourly intervals for 2–90 day ranges, daily candles for anything longer. For tick-level or minute-by-minute data going back years, the Binance klines endpoint is the better choice — ETHUSDT historical data is available there going back to 2017.
Platforms like VoiceOfChain combine historical price data with on-chain signals and sentiment feeds to generate real-time trading alerts. The same approach applies to individual traders: once you have a historical pipeline, you can validate any signal against past market conditions before trusting it with live capital. Here's how to pull ETH historical prices into a pandas DataFrame ready for analysis:
import requests
import pandas as pd
from datetime import datetime
def get_eth_historical(
days: int = 90,
currency: str = "usd"
) -> pd.DataFrame:
"""
Fetch ETH historical prices from CoinGecko.
Granularity auto-selected: hourly (2-90 days), daily (90+ days).
"""
url = "https://api.coingecko.com/api/v3/coins/ethereum/market_chart"
response = requests.get(
url,
params={"vs_currency": currency, "days": days},
timeout=20
)
response.raise_for_status()
raw = response.json()
df = pd.DataFrame(raw["prices"], columns=["ts_ms", "price"])
df["volume"] = [v[1] for v in raw["total_volumes"]]
df["market_cap"] = [m[1] for m in raw["market_caps"]]
df["datetime"] = pd.to_datetime(df["ts_ms"], unit="ms", utc=True)
df = df.drop(columns=["ts_ms"]).set_index("datetime")
df.index = df.index.tz_convert("US/Eastern") # localize to your TZ
return df
# Pull 90 days of hourly data
df = get_eth_historical(days=90)
print(df.tail(3).to_string())
print(f"\nPeriod: {df.index[0].date()} → {df.index[-1].date()}")
print(f"Candles: {len(df):}")
print(f"Min price: ${df['price'].min():,.2f}")
print(f"Max price: ${df['price'].max():,.2f}")
print(f"Avg price: ${df['price'].mean():,.2f}")
# Simple moving average crossover signal
df["sma20"] = df["price"].rolling(20).mean()
df["sma50"] = df["price"].rolling(50).mean()
df["signal"] = (df["sma20"] > df["sma50"]).astype(int)
bullish_periods = df["signal"].sum() / len(df) * 100
print(f"\nBullish (SMA20 > SMA50): {bullish_periods:.1f}% of the period")
With this data in a pandas DataFrame, you can run moving average crossovers, RSI calculations, Bollinger Bands, or any indicator using libraries like pandas-ta or ta-lib — no data subscription needed. The datetime index with timezone awareness is critical for strategies that factor in market session timing. CoinGecko's composite price aggregates across major venues including Binance, Coinbase, Bybit, OKX, Bitget, KuCoin, and Gate.io, giving you a clean representative price rather than one exchange's idiosyncratic feed.
One practical note for backtesting accuracy: if your live execution will happen on a specific exchange, consider pulling historical data from that exchange's native API. KuCoin's klines endpoint, for example, will give you prices as they actually appeared on KuCoin — which may differ from the aggregate by 0.1–0.5%. That's a small difference in isolation, but it compounds across hundreds of backtest trades and can produce optimistic P&L projections that don't survive contact with live markets.
Building on an Ethereum price API is one of the highest-leverage moves a technically inclined trader can make. Once you have a reliable price feed, you can layer in gas cost tracking, historical backtesting, cross-exchange price comparison, and automated alerting — all without paying for premium data subscriptions. Start with CoinGecko for aggregated pricing and add exchange-specific feeds from Binance or Coinbase as you need higher granularity or lower latency. Pair that with Etherscan's gas oracle and you have a foundation solid enough for any ETH-focused strategy. Platforms like VoiceOfChain build on exactly these kinds of data pipelines to surface real-time trading signals — the same infrastructure is available to individual traders, one API call at a time.