Most currency APIs want your email, your credit card, and a monthly commitment before you can test a single rate. ExchangeRate-API has a free open endpoint that requires none of that.
One URL. No key. 166 currencies. Updated daily.
https://open.er-api.com/v6/latest/USD
That's it. Call it right now from your terminal:
curl https://open.er-api.com/v6/latest/USD
You'll get back:
{
"result": "success",
"base_code": "USD",
"time_last_update_utc": "Thu, 26 Mar 2026 00:02:31 +0000",
"time_next_update_utc": "Fri, 27 Mar 2026 00:02:31 +0000",
"rates": {
"EUR": 0.863827,
"GBP": 0.747511,
"JPY": 159.204596,
"CAD": 1.380053,
"AUD": 1.438717,
"CHF": 0.791328,
"CNY": 7.257342,
"INR": 84.123456
}
}
166 currencies in one request. No auth headers. No rate limit errors to handle.
Change the base currency
Swap USD for any supported currency code:
curl https://open.er-api.com/v6/latest/EUR
curl https://open.er-api.com/v6/latest/GBP
curl https://open.er-api.com/v6/latest/JPY
The response always gives you rates relative to your chosen base.
Python: currency converter in 15 lines
import requests
def convert(amount: float, from_currency: str, to_currency: str) -> float:
url = f"https://open.er-api.com/v6/latest/{from_currency.upper()}"
response = requests.get(url)
response.raise_for_status()
data = response.json()
if data["result"] != "success":
raise ValueError(f"API error: {data}")
rate = data["rates"].get(to_currency.upper())
if not rate:
raise ValueError(f"Currency not found: {to_currency}")
return amount * rate
# Examples
print(f"$100 USD = €{convert(100, 'USD', 'EUR'):.2f} EUR")
print(f"£50 GBP = ${convert(50, 'GBP', 'USD'):.2f} USD")
print(f"¥10000 JPY = ${convert(10000, 'JPY', 'USD'):.2f} USD")
Output:
$100 USD = €86.38 EUR
£50 GBP = $66.93 USD
¥10000 JPY = $62.81 USD
JavaScript version
async function convertCurrency(amount, from, to) {
const response = await fetch(
`https://open.er-api.com/v6/latest/${from.toUpperCase()}`
);
const data = await response.json();
if (data.result !== 'success') {
throw new Error('API request failed');
}
const rate = data.rates[to.toUpperCase()];
if (!rate) throw new Error(`Unknown currency: ${to}`);
return (amount * rate).toFixed(2);
}
// Usage
convertCurrency(100, 'USD', 'EUR').then(result => {
console.log(`$100 USD = €${result} EUR`);
});
What the time_next_update_utc field tells you
The API updates rates once per day. The time_next_update_utc field shows exactly when the next update happens. Use it to avoid unnecessary calls:
import requests
from datetime import datetime, timezone
def get_rates_with_cache(base: str = "USD") -> dict:
url = f"https://open.er-api.com/v6/latest/{base}"
data = requests.get(url).json()
next_update = data["time_next_update_unix"]
now = datetime.now(timezone.utc).timestamp()
# Data is fresh — show when it updates next
minutes_until_refresh = int((next_update - now) / 60)
print(f"Rates current. Next update in ~{minutes_until_refresh} minutes")
return data["rates"]
rates = get_rates_with_cache("USD")
Cache the response and only re-fetch after time_next_update_unix. You'll cut your API calls to 1/day.
Build a multi-currency price display
import requests
def price_in_currencies(usd_price: float, currencies: list) -> dict:
data = requests.get("https://open.er-api.com/v6/latest/USD").json()
rates = data["rates"]
return {
currency: round(usd_price * rates[currency], 2)
for currency in currencies
if currency in rates
}
price = price_in_currencies(29.99, ["EUR", "GBP", "JPY", "CAD", "AUD", "INR"])
for currency, amount in price.items():
print(f" {currency}: {amount}")
Output:
EUR: 25.90
GBP: 22.43
JPY: 4773.84
CAD: 41.38
AUD: 43.13
INR: 2522.90
Free vs. paid
The open endpoint (open.er-api.com) is completely free with no registration. Limitations:
- Updates: Once per day (sufficient for most apps)
- Historical data: Not available (paid only)
- Rate limits: No documented limit, but cache your responses anyway
- HTTPS: Yes
- CORS: Yes (usable from browser)
The paid API (v6.exchangerate-api.com) adds historical data, minute-level updates, and higher reliability SLAs. Starting at $9.99/month.
For a portfolio tracker, e-commerce price display, or internal tool — the free endpoint handles it fine.
What it doesn't do
No historical exchange rates on the free tier. If you need "what was EUR/USD on January 15, 2023?" — that's a paid feature. Free alternatives for historical data: Frankfurter API (ECB rates, historical, completely free).
Need live currency data on autopilot? My Exchange Rate Scraper on Apify tracks 170+ currencies — runs on a schedule, no code needed. Email spinov001@gmail.com for custom pipelines.
More free API articles:
Top comments (0)