14.6 million official exchange rates from 107 central banks and tax authorities, now on Hugging Face

Reviewed by Madhushan, Fintech Developer — September 2026
Financial data on a screen

If you have ever needed "the ECB rate on the invoice date" for a tax return, a customs form, a transfer-pricing file or an audit, you know the problem. The number exists. It is public. And it is scattered across a hundred central-bank websites, each with its own PDF, XML feed, Excel download or HTML table, each with its own idea of which way round a rate should be quoted.

We spent most of this year collecting those tables into one pipeline. As of this week the full history is a public dataset on Hugging Face:

huggingface.co/datasets/AllRates/central-bank-exchange-rates

Rows14,612,276
Institutions103 central banks + 4 tax authorities
Earliest date1914 (Swiss National Bank)
Currencies215 base, 202 quote
RefreshDaily, from the GitHub source repository
LicenseCC BY 4.0
Size515 MB CSV, auto-converted to Parquet

Why "official" rates and not market rates

Most exchange-rate datasets are market data: a mid-market snapshot from some aggregator at some time of day. That is the right thing for a price display. It is the wrong thing for anything a regulator will look at.

Tax offices, customs agencies and accounting standards usually name a publisher. HMRC publishes monthly rates for UK VAT and customs. The ECB reference rate is the default for euro-area statutory reporting. The Reserve Bank of India reference rate is the benchmark for statutory rupee conversions. The Reserve Bank of Australia, Bank of Canada, Banco Central do Brasil and dozens of others publish a daily fixing that is the rate for that jurisdiction, regardless of what the interbank market did five minutes later.

Those numbers are not derivable from market data. They have to be collected from the source, on the source's schedule, in the source's convention. That is what this dataset is. (If you want the same rates as an API rather than a download, that is the central bank rates API.)

What is in it

One CSV per institution under rates/, five columns, identical everywhere:

ColumnTypeMeaning
datestringISO 8601 publication date. Weekends and the publisher's holidays are simply absent.
basestringThe currency being priced (ISO 4217).
quotestringThe currency it is priced in.
typestringThe publisher's own label: reference, middle, buy, sell, spot, indicative, monthly, monthly_average, quarterly, close, and a few more.
valuefloatHow many quote one base buys.

A few rows from rates/ecb.csv:

date,base,quote,type,value
2025-01-02,EUR,AUD,reference,1.6618
2025-01-02,EUR,BGN,reference,1.9558
2025-01-02,EUR,BRL,reference,6.42

Alongside the history there is latest/<code>.json with each institution's most recent table, and sources.json with the institution's name, country, home currency, kind (central bank or tax authority) and the URL of the page we collect from.

Coverage by depth, to give you a sense of what "back to 1914" actually means:

InstitutionCodeFirst year in dataset
Swiss National Banksnb1914
Bank of Koreabok1964
Bank of Israelboi1975
Hong Kong Monetary Authorityhkma1981
Bank of Japanboj1998
European Central Bankecb1999
Reserve Bank of Indiarbi2003
People's Bank of Chinapboc2006

Most institutions only publish a few years of history on their own sites. Where a bank offered more, we took all of it.

Loading it

With the datasets library, the whole thing as one table:

from datasets import load_dataset

ds = load_dataset("AllRates/central-bank-exchange-rates", "rates")

With pandas, one institution at a time. This is usually what you want, because 14.6 million rows is a lot of memory for a question about one bank:

import pandas as pd

ecb = pd.read_csv(
    "hf://datasets/AllRates/central-bank-exchange-rates/rates/ecb.csv",
    parse_dates=["date"],
)
usd = ecb[(ecb.base == "EUR") & (ecb.quote == "USD")].set_index("date")["value"]
print(usd.resample("YE").mean().tail())

With Polars, lazily, if you want to scan several banks without loading all of them:

import polars as pl

df = (
    pl.scan_csv("hf://datasets/AllRates/central-bank-exchange-rates/rates/*.csv")
      .filter((pl.col("base") == "USD") & (pl.col("quote") == "INR"))
      .collect()
)

With DuckDB, straight off the Hub, no download step:

INSTALL httpfs; LOAD httpfs;

SELECT date, value
FROM 'hf://datasets/AllRates/central-bank-exchange-rates/rates/rbi.csv'
WHERE base = 'USD' AND quote = 'INR' AND type = 'reference'
ORDER BY date DESC
LIMIT 5;

Three things you can do with it that you could not do before

Compare what different central banks say the same pair is worth. The ECB publishes EUR→USD. The Fed publishes USD→EUR. The Bank of Canada publishes both against CAD. On any given day these disagree by a few basis points because they fix at different times. That spread is itself interesting, and until now you had to scrape three sites to see it.

Reconstruct a filing exactly. Pick the publisher your jurisdiction names, filter to type == "reference" (or whatever that publisher calls its headline rate), take the row for the invoice date. If the date is missing, the publisher did not publish that day, and your local rule will say whether to use the previous or next business day.

Train on a century of official fixings. The SNB series runs from 1914. The Bank of Korea from 1964. If you are building anything that needs long, clean, non-market FX series, this is a larger and more consistent corpus than we could find anywhere else in the open.

Conventions and caveats

We made a few decisions that you should know about before relying on the data.

How it stays current

The dataset is a mirror of a GitHub repository, AllRates-Today/central-bank-exchange-rates, which is itself fed by the collection pipeline behind AllRatesToday. A scheduled Action runs four times a day, pulls each institution's latest table from a keyless open endpoint, commits only when something changed, and then pushes the consolidated per-institution CSVs to Hugging Face. So the Hub copy is never more than a few hours behind the source sites.

If you want the same data as small JSON files on a CDN instead of a 500 MB dataset, the GitHub repo serves data/latest.json and per-bank latest.json over jsDelivr with no key. If you want it as an API with a query language, the same rates are behind https://allratestoday.com/api/open/central-bank/<code>, also keyless, and the download page gives you any single table as CSV, Excel or JSON.

License

CC BY 4.0. Use it commercially, redistribute it, train on it. The one condition is visible credit to AllRatesToday with a link to allratestoday.com.

If you build something with it, open an issue on the GitHub repo or leave a note in the dataset's Community tab. Missing an institution you need? The repo README lists how new sources get added, and we are actively expanding coverage.

Official rates, as an API

The same 107 institutions, queryable by date, pair and publisher. Free tier, no credit card.

Explore the central bank rates API

Related Articles