DocsDocs

Request the latest exchange rates

GET /v1/latest: copy the request and see a full response and errors

20 Oct 2026 · 2 min read

GET /v1/latest/USD returns the latest rates from USD to every other currency. Use symbols to select specific currencies. Without a key, you can make 10 requests a minute per IP. A free key includes 5,000 requests a month. Free and keyless rates are delayed by 15 minutes.

Make a request

Set the base currency in the path or with ?base=. Store your key on your server.

Shell
curl "https://api.exchangerate.dev/v1/latest/USD?symbols=EUR,GBP,JPY" \  -H "Authorization: Bearer $EXCHANGERATE_API_KEY"
JavaScript
const res = await fetch("https://api.exchangerate.dev/v1/latest/USD?symbols=EUR,GBP,JPY", {  headers: { Authorization: `Bearer ${process.env.EXCHANGERATE_API_KEY}` },})const data = await res.json()if (data.result !== "success") throw new Error(data.code)
Python
import os, requestsres = requests.get(    "https://api.exchangerate.dev/v1/latest/USD?symbols=EUR,GBP,JPY",    headers={"Authorization": f"Bearer {os.environ['EXCHANGERATE_API_KEY']}"},    timeout=10,)data = res.json()if data["result"] != "success":    raise RuntimeError(data["code"])

Parameters

NameLocationRequiredDescription
basepath, or ?base=No (USD)Currency used as the base for rates
symbolsqueryNo (every other currency)Currencies to include, separated by commas

Read the response

This example was captured without a key on 19 Oct 2026. Rates and timestamps will differ in your response.

Response example (19 Oct 2026)
{  "result": "success",  "base": "USD",  "source": "live",  "sources": {    "EUR": "live",    "GBP": "live",    "JPY": "live"  },  "market_session": "open",  "timestamp": "2026-10-19T12:44:20Z",  "data_updated_at": "2026-10-19T12:28:59Z",  "effective_at": {    "EUR": "2026-10-19T12:28:59Z",    "GBP": "2026-10-19T12:28:59Z",    "JPY": "2026-10-19T12:28:59Z"  },  "rates": {    "EUR": 0.89124,    "GBP": 0.75048,    "JPY": 158.274  },  "stale": {    "EUR": false,    "GBP": false,    "JPY": false  },  "derived_symbols": [],  "notice": "Indicative rates, not for settlement."}
FieldDescription
resultsuccess or error
source, sourcesRate source: live, ecb_daily or market_daily; source reports the least fresh
market_sessionopen, weekend or interbank_closed
timestampTime the response was served (UTC)
data_updated_atTime of the oldest observation returned (UTC)
effective_atObservation time for each currency
ratesUnits of each currency per 1 unit of the base
staleTrue if a rate is outside its source's freshness window
derived_symbolsCurrencies with rates calculated through another currency
noticeReminder that rates are indicative and aren't for settlement

Errors

StatuscodeWhen
400unsupported_baseUnsupported base currency
429ip_rate_limitedKeyless requests exceed 100 in an hour per IP
429quota_exceededPlan's monthly request limit exceeded
Error response
{  "result": "error",  "code": "unsupported_base",  "message": "unsupported base: XYZ"}

Request limits

Free includes 5,000 requests a month and 10 a minute, with rates delayed by 15 minutes. Paid plans provide live rates. See free plan limits for details on every plan.

Questions

Does /v1/latest require an API key?

No. Keyless limits are 10 requests a minute and 100 requests an hour per IP. A free key gives you a separate quota of 5,000 requests a month.

How can I request specific currencies?

Use symbols, for example ?symbols=EUR,GBP,JPY. Leave it out to receive every other currency.

Does this endpoint return live rates?

Paid plans receive live rates. Free and keyless rates have a 15-minute delay, shown by X-Price-Delay-Seconds: 900 in the response.

Keep reading

Use your own quota for /v1/latest

Add a free key to count this request against your own quota instead of the shared per-IP limit.

Get a free key