Docs /

Historical exchange rates

Use the date endpoint for one snapshot or /v1/range for a daily series. Published coverage starts on 1999-01-04.

Get one date

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

bash · one historical snapshot
curl "https://api.exchangerate.dev/v1/2024-01-15/EUR?symbols=USD,GBP"

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.

Get a date range

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

bash · 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"
  • 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; missing weekends are not inserted.
bash · 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"

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 · 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"   --output usd-rates-2024.csv

Keep provenance with the numbers

Each row includes source, is_forward_filled, and derived_symbols. Store those fields with the rates. They explain where an observation came from and whether a cross was calculated from other pairs.

Backtests need a time split
A clean API response does not prevent look-ahead bias. Split training and test data by date, and do not let a future value leak into an earlier feature. The backfill guide shows the safe pattern.

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