Menu

Historical Exchange Rate API

Plus and Pro offer daily history from 1999-01-04. Free covers 30 days, Basic one year. Export JSON, CSV, or Parquet.

Look up one historical date

Put the date and base currency in the path. The symbols filter is optional; without it, the response includes every supported quote currency.

If you are checking a rate before writing an integration, start with the historical exchange-rate lookup tool. It shows the result first and gives you the matching API request.

bash · Plus or Pro · one historical snapshot
curl "https://api.exchangerate.dev/v1/2024-01-15/EUR?symbols=USD,GBP" \  -H "Authorization: Bearer YOUR_API_KEY"

If the requested date is a weekend or market holiday, the endpoint carries forward the most recent published fix and sets is_forward_filled to true. It never invents a rate.

Pull a date range

The range endpoint needs symbols, start_date, and end_date. The base defaults to USD.

bash · Plus or Pro · daily EUR and GBP rates
curl "https://api.exchangerate.dev/v1/range?base=USD&symbols=EUR,GBP&start_date=2024-01-01&end_date=2024-06-30" \  -H "Authorization: Bearer YOUR_API_KEY"
  • JSON returns up to 366 business-day rows at a time.
  • When has_more is true, pass next_cursor back as the next request's cursor.
  • A single request can span up to 1,830 days, roughly five years.
  • Range rows are published business-day observations; weekends and other non-publication dates are not inserted.
bash · Plus or Pro · follow the cursor
curl "https://api.exchangerate.dev/v1/range?base=USD&symbols=EUR,GBP&start_date=2021-01-01&end_date=2025-12-31&cursor=2022-06-01" \  -H "Authorization: Bearer YOUR_API_KEY"

Pull intraday observations

For a recorded response and plan overview, start with the intraday exchange rate API guide.

Pro includes 1-minute through 4-hour observations via /v1/timeseries. Plus includes 1h and 4h for 30 days. Use the 1d interval of /v1/timeseries when you want the same daily reference history served by the existing daily endpoints.

bash · Pro · aligned 15-minute cross
curl "https://api.exchangerate.dev/v1/timeseries?base=EUR&symbols=JPY&interval=15m&from=2026-09-14T12:00:00Z&to=2026-09-14T13:00:00Z" \  -H "Authorization: Bearer YOUR_KEY"

Market collection began on 2026-09-14; this example uses a populated window from that day. The retention periods below describe how long collected rows are kept, not how far back every pair is already populated. The current open bucket can change.

  • 1m observations are retained for 30 days.
  • 5m, 15m, 1h, and 4h are retained without a scheduled expiry.
  • 1d remains the existing daily reference series.
  • Intraday gaps remain gaps; weekends and market closures do not create synthetic rows.
  • Derived crosses require real closing ticks on both USD legs within the same interval bucket and no more than five seconds apart. These are approximate rate observations, not simultaneous quotes or cross OHLC.
  • effective_at gives the older contributing source timestamp, preserving fractional seconds. Candle backfills have null observation times and cannot establish cross observations.
  • Supported windows with no observations return HTTP 200 with data: [], has_more: false and next_cursor: null. An unknown interval returns HTTP 400 unsupported_interval.
  • Coverage depends on the pair and interval. Requests containing unsupported pairs are rejected in full with unsupported_pair_interval and a rejected pair list. See the pair and interval coverage table.

For ongoing live updates after a historical query, see the WebSocket integration guide. WebSocket coverage is narrower than the daily reference catalog and requires an API key.

Download CSV or Parquet

Add format=csv or format=parquet. Exports return the full requested window as one file, so they do not use the JSON cursor.

bash · Plus or Pro · save a CSV
curl -L "https://api.exchangerate.dev/v1/range?base=USD&symbols=EUR,GBP&start_date=2024-01-01&end_date=2024-12-31&format=csv" \  -H "Authorization: Bearer YOUR_API_KEY" \  --output usd-rates-2024.csv

Weekends and missing observations

A one-date request for a weekend or market holiday returns the most recently published fix with is_forward_filled set to true. A range does not manufacture rows for those dates; it contains published business-day observations only. Treat a forward-filled value as the prior observation, not a new market event.

Provenance and derived rates

Daily range rows include source, is_forward_filled, and derived_symbols. Time-series rows include timestamp, source_type, market_session, and derived_symbols. Store those fields with the rates.

Avoid look-ahead bias in backtests

For a worked Python example, read Historical FX time series in Python.

Limits and pricing

The date and range endpoints use the same request quota as the rest of the API. A CSV or Parquet range export counts as one call. Free and keyless cover 30 days, Basic one year, and Plus and Pro full daily history from 1999 where available. See pricing for current quotas and plan limits.