Official Central Bank Exchange Rates
On this page, we’ll dive into the official exchange rates endpoints you can use to retrieve the exchange rates central banks like the ECB, the Federal Reserve or the Bank of England officially publish, including their full history.
Official rates are what accounting, invoicing, tax and customs rules usually refer to. Unlike /latest and /historical, which aggregate market data, these endpoints return each central bank’s own publication: one set of rates per business day, never blended, smoothed or filled in.
Which source should I use?
Many tax authorities prescribe a specific central bank rate, for example the ECB reference rates in the euro area, the NBP rates in Poland or the CNB rates in the Czech Republic. Check which bank, which rate and which day your rules require, then request exactly that source and date.
Sources
35 central banks and official fixing authorities on six continents. Each bank links to its public rate page with today’s rates, charts and yearly averages. More banks are added as they publish machine-readable rates.
Europe
source | Central bank | Against | Rate | Since |
|---|---|---|---|---|
ecb | European Central Bank | EUR | Reference rates | 1999 |
boe | Bank of England | GBP | Spot rates at 16:00 London time | 1975 |
cnb | Czech National Bank | CZK | Exchange rate fixing | 1991 |
nbp | National Bank of Poland | PLN | Average rates (table A) | 2002 |
norges | Norges Bank | NOK | Daily exchange rates | 1980 |
riksbank | Sveriges Riksbank | SEK | Daily middle rates | 1993 |
nationalbanken | Danmarks Nationalbank | DKK | Daily exchange rates | 1977 |
mnb | Magyar Nemzeti Bank | HUF | Official exchange rates | 1949 |
bnr | National Bank of Romania | RON | Reference rates | 2005 |
nbu | National Bank of Ukraine | UAH | Official rates, incl. precious metals | 1996 |
tcmb | Central Bank of the Republic of Türkiye | TRY | Indicative forex buying rates | 2005 |
nbm | National Bank of Moldova | MDL | Official exchange rates | 1995 |
nbrm | National Bank of the Republic of North Macedonia | MKD | Middle rates | 1997 |
cbbh | Central Bank of Bosnia and Herzegovina | BAM | Middle rates | 2003 |
cbr | Bank of Russia | RUB | Official exchange rates | 1998 |
Asia and the Middle East
source | Central bank | Against | Rate | Since |
|---|---|---|---|---|
nbg | National Bank of Georgia | GEL | Official exchange rates | 1995 |
cba | Central Bank of Armenia | AMD | Official exchange rates | 2000 |
cbar | Central Bank of the Republic of Azerbaijan | AZN | Official rates, incl. precious metals | 2006 |
nbk | National Bank of Kazakhstan | KZT | Official market rates | 1999 |
cbu | Central Bank of the Republic of Uzbekistan | UZS | Official exchange rates | 2000 |
nbt | National Bank of Tajikistan | TJS | Official exchange rates | 2000 |
boi | Bank of Israel | ILS | Representative rates | 1985 |
pboc | People's Bank of China | CNY | RMB central parity (CFETS) | 2006 |
bnm | Bank Negara Malaysia | MYR | 12:00 middle rates | 2005 |
bi | Bank Indonesia | IDR | Transaction rates (buying) | 2001 |
nrb | Nepal Rastra Bank | NPR | Buying rates | 2000 |
Oceania
source | Central bank | Against | Rate | Since |
|---|---|---|---|---|
rba | Reserve Bank of Australia | AUD | Indicative rates at 16:00 Sydney time | 2023 |
Americas
source | Central bank | Against | Rate | Since |
|---|---|---|---|---|
fed | Federal Reserve | USD | H.10 noon buying rates, released weekly | 1971 |
boc | Bank of Canada | CAD | Daily average rates | 2017 |
bcb | Banco Central do Brasil | BRL | PTAX closing rates (selling) | 1994 |
bcra | Banco Central de la República Argentina | ARS | Official rates (A 3500 for USD) | 2002 |
bcrp | Banco Central de Reserva del Perú | PEN | Interbank rate, USD only | 1997 |
sfc | Superintendencia Financiera de Colombia | COP | TRM, USD only | 1991 |
Africa
source | Central bank | Against | Rate | Since |
|---|---|---|---|---|
cbn | Central Bank of Nigeria | NGN | Central rates | 2001 |
sarb | South African Reserve Bank | ZAR | Rand rates for USD, GBP, EUR, JPY | 2000 |
The currencies each bank publishes, its publication schedule and the exact first and last date of its history are available from /v3/official/sources. Rates are imported within the hour after a bank publishes them.
How the values work
- Normalised quotation. Banks quote in different directions and units (the CNB publishes CZK per 100 JPY, the Fed publishes USD per EUR but JPY per USD). Every value is normalised to units of currency per 1 unit of
base_currency, like the rest of the API. Apart from that the values are exactly as published. - Official against the bank’s currency. By default
base_currencyis the bank’s own currency (EUR forecb, PLN fornbp, ...) and every value is official. With any otherbase_currencythe values are cross rates calculated from the official ones, andmeta.cross_ratesistrue. The bank’s own currency is included in that case, sosource=nbp&base_currency=USD¤cies=PLNreturns the official PLN rate for 1 USD. - Business days only. Banks do not publish on weekends and holidays. When you request such a
date, you get the bank’s newest publication from up to 14 days before it;meta.datetells you which day the rates are for. The NBU sets a rate for every calendar day, a day in advance. - Publication references. Where a bank numbers its publications,
meta.referencecarries the number, e.g. the NBP table number (188/A/NBP/2026) or the TCMB bulletin number, so you can cite it on invoices and filings. - Buying rates. A few banks (TCMB, Bank Indonesia, Nepal Rastra Bank) publish buying and selling rates but no middle rate. Their buying rate is served, as the rate type says; nothing is averaged.
- Precision. Some banks publish weak currencies with few significant digits (the Riksbank publishes 1 IDR as
0.00055SEK). Those values are served as published, so cross rates derived from them are only as precise as the bank’s figure. Quotations with a single significant digit are too coarse to convert with and are left out.
Official Exchange Rates
This endpoint returns the official exchange rates a central bank published for a date, or its newest publication when no date is given.
Required attributes
- Name
source- Type
- string
- Description
The central bank to get the official rates from, e.g.
ecb,fedornbp. Every supported code is listed under Sources
Optional attributes
- Name
date- Type
- string
- Description
Date to get the official rates for (format: 2026-09-28) By default the bank’s newest publication is returned
- Name
base_currency- Type
- string
- Description
The currency all values are relative to By default the bank’s own currency, which gives the official values as published
- Name
currencies- Type
- string
- Description
A list of comma-separated currency codes which you want to get (USD,GBP) By default all currencies of the publication will be shown
- Name
compare- Type
- string
- Description
marketadds the market rate of the publication day next to every official rate, see official vs. market
- Name
format- Type
- string
- Description
json(default),csvorxlsx(the same table as an Excel download)
Response Structure
The meta key describes the publication: the source code and the bank’s source_name, the date the rates are for, the requested_date you asked for (null without one), the base_currency of the values, the bank’s own source_base_currency, whether the values are cross_rates, the bank’s reference for the publication and last_updated_at, when currencyapi last imported it. The data key holds the rates like the /latest endpoint. With compare=market, every rate also carries market and difference_pct, and meta.market_last_updated_at says when the market rate is from.
Request
curl -G https://api.currencyapi.com/v3/official \
-d source=nbp \
-d date=2026-09-28 \
-d base_currency=USD \
-d currencies=PLN \
-H "apikey: YOUR-API-KEY"
Response
{
"meta": {
"source": "nbp",
"source_name": "National Bank of Poland",
"date": "2026-09-28",
"requested_date": "2026-09-28",
"base_currency": "USD",
"source_base_currency": "PLN",
"cross_rates": true,
"reference": "188/A/NBP/2026",
"last_updated_at": "2026-09-28T10:07:12Z"
},
"data": {
"PLN": {
"code": "PLN",
"value": 3.8478
}
}
}
Official Exchange Rates for a Date Range
This endpoint returns every publication of a central bank between two dates, oldest first, for example to build a monthly average or to fill a ledger. Only the bank’s publication days are included.
Like /range it requires a plan that includes the range endpoint, and plans limited to one currency per range request need exactly one code in currencies.
Required attributes
- Name
source- Type
- string
- Description
The central bank to get the official rates from
- Name
date_from- Type
- string
- Description
First date of the range (format: 2026-09-01)
- Name
date_to- Type
- string
- Description
Last date of the range (format: 2026-09-30), at most 366 days after
date_from
Optional attributes
- Name
base_currency- Type
- string
- Description
The currency all values are relative to By default the bank’s own currency
- Name
currencies- Type
- string
- Description
A list of comma-separated currency codes which you want to get (USD,GBP) By default all currencies of each publication will be shown
- Name
accuracy- Type
- string
- Description
day(default) for every publication,weekfor only the last publication of each week (Monday to Sunday) ormonthfor only the last publication of each month, see month-end rates
- Name
compare- Type
- string
- Description
marketadds the market rate of each publication day next to every official rate, see official vs. market Not together withdatev,erpnextorodoo
- Name
format- Type
- string
- Description
json(default),csv,xlsx(the same table as an Excel download), or a file to import into accounting software:datev,erpnextorodoo, see accounting imports
Response Structure
The data key holds one entry per publication with its date, the bank’s reference and the currencies. With compare=market, every rate also carries market and difference_pct, and every entry its market_last_updated_at.
Month-end and week-end rates
Accounting revalues open items and balances at the rate of the period’s last day. With accuracy=month the range keeps only the last publication of each month, with accuracy=week the last one of each week (Monday to Sunday). It works with every format, including the accounting imports. When date_to falls inside a week or month, the last entry is that period’s last publication up to date_to.
Month-end rates
curl -G https://api.currencyapi.com/v3/official/range \
-d source=ecb \
-d date_from=2026-08-01 \
-d date_to=2026-09-29 \
-d currencies=USD \
-d accuracy=month \
-d format=csv \
-H "apikey: YOUR-API-KEY"
Response (text/csv)
date,source,base_currency,currency,value,reference
2026-08-31,ecb,EUR,USD,1.17,
2026-09-28,ecb,EUR,USD,1.1378,
Request
curl -G https://api.currencyapi.com/v3/official/range \
-d source=ecb \
-d date_from=2026-09-01 \
-d date_to=2026-09-30 \
-d currencies=USD \
-H "apikey: YOUR-API-KEY"
Response
{
"meta": {
"source": "ecb",
"source_name": "European Central Bank",
"base_currency": "EUR",
"source_base_currency": "EUR",
"cross_rates": false
},
"data": [
{
"date": "2026-09-25",
"reference": null,
"currencies": {
"USD": {
"code": "USD",
"value": 1.1403
}
}
},
{
"date": "2026-09-28",
"reference": null,
"currencies": {
"USD": {
"code": "USD",
"value": 1.1378
}
}
}
]
}
List Central Bank Sources
This endpoint lists every central bank you can use as source, with the currency it publishes against, the kind of rate, when it publishes, a link to the bank’s own page, the first and last date of the stored history and the currencies of its newest publication.
Request
curl -G https://api.currencyapi.com/v3/official/sources \
-H "apikey: YOUR-API-KEY"
Response
{
"data": {
"ecb": {
"code": "ecb",
"name": "European Central Bank",
"country": "EU",
"region": "europe",
"base_currency": "EUR",
"rate_type": "Euro foreign exchange reference rates",
"schedule": "Every TARGET2 business day at around 16:00 CET",
"website": "https://www.ecb.europa.eu/stats/policy_and_exchange_rates/euro_reference_exchange_rates/html/index.en.html",
"history": {
"from": "1999-01-04",
"to": "2026-09-28"
},
"currencies": ["AUD", "BRL", "CAD", "..."]
},
"...": "34 more central banks"
}
}
Finding a source for a currency
/v3/official/sources?currency=KZT lists every bank that publishes a rate for the tenge (and the National Bank of Kazakhstan, which publishes against it). Add region=asia (or europe, africa, north-america, south-america, oceania) to narrow it down. The endpoint is free: it never counts against your quota.
Comparing official rates
To see one currency pair as every central bank published it, for example EUR to USD at the ECB, the Federal Reserve and the Bank of England side by side, use /v3/official/compare.
CSV and caching
- CSV. Add
format=csvto/v3/officialor/v3/official/rangefor one row per currency and publication:date,source,base_currency,currency,value,reference. Values never use exponent notation, so Excel and Google Sheets read them as numbers. - Excel.
format=xlsxgives the same table as an Excel workbook, downloaded asofficial.xlsxorofficial-range.xlsx, see Excel downloads. - Conditional requests. Every response carries an
ETag. Send it back asIf-None-Matchand an unchanged response comes back as304 Not Modifiedwithout a body.Cache-Controltells you how long a response stays current: 5 minutes for recent publications, a day for settled ones.
Official vs. market rates
Add compare=market to /v3/official or /v3/official/range to see how far each official rate is from the market. Every rate then carries two more fields:
market: the market rate for the publication day, in the same units asvalue. It is that day’s close from/v3/historical; for a publication dated today it is the latest market rate at your plan’s update interval, like/v3/latest.difference_pct: (official / market − 1) × 100, rounded to 4 decimals. Positive when the official rate is above the market.
Both are null where the market has no rate for the currency or the base currency. meta.market_last_updated_at (on /v3/official/range: each entry’s market_last_updated_at) says when the market rate is from. The official value stays exactly as published, and the request costs the same. With format=csv or xlsx the table gains the columns market,difference_pct. The accounting imports carry the official rates only, so compare with format=datev, erpnext or odoo returns a 422.
ECB rates next to the market
curl -G https://api.currencyapi.com/v3/official \
-d source=ecb \
-d date=2026-09-25 \
-d currencies=USD \
-d compare=market \
-H "apikey: YOUR-API-KEY"
Response
{
"meta": {
"source": "ecb",
"source_name": "European Central Bank",
"date": "2026-09-25",
"requested_date": "2026-09-25",
"base_currency": "EUR",
"source_base_currency": "EUR",
"cross_rates": false,
"reference": null,
"last_updated_at": "2026-09-25T14:16:03Z",
"market_last_updated_at": "2026-09-25T23:59:59Z"
},
"data": {
"USD": {
"code": "USD",
"value": 1.1403,
"market": 1.1402508552,
"difference_pct": 0.0043
}
}
}
The same with format=csv
date,source,base_currency,currency,value,reference,market,difference_pct
2026-09-25,ecb,EUR,USD,1.1403,,1.140250855,0.0043
Importing into accounting software
/v3/official/range also returns the rates as a file your accounting software imports as its exchange rate table: add format=datev, format=erpnext or format=odoo. The file comes as a download named {source}-{format}-{date_from}-{date_to}.csv, e.g. ecb-datev-2026-09-01-2026-09-30.csv, and costs one request like any range request. Combine it with accuracy=month to import only month-end rates.
DATEV
For the Kurstabelle of DATEV Kanzlei-Rechnungswesen and DATEV Rechnungswesen (import described in DATEV Dok.-Nr. 1015760). DATEV keeps rates against the euro, so the rates must be against EUR: use a bank that publishes against EUR such as ecb, or set base_currency=EUR. Any other base currency returns a 422.
Download the ECB rates for DATEV
curl -G https://api.currencyapi.com/v3/official/range \
-d source=ecb \
-d date_from=2026-09-25 \
-d date_to=2026-09-28 \
-d currencies=USD,GBP \
-d format=datev \
-H "apikey: YOUR-API-KEY" \
-o ecb-datev-2026-09-25-2026-09-28.csv
File (windows-1252, CRLF, no header)
EUR;GBP;25.09.2026;25.09.2026;0,860450;European Central Bank;5
EUR;GBP;28.09.2026;28.09.2026;0,857850;European Central Bank;5
EUR;USD;25.09.2026;25.09.2026;1,140300;European Central Bank;5
EUR;USD;28.09.2026;28.09.2026;1,137800;European Central Bank;5
Each line is one rate: Währung 1;Währung 2;Datum von;Datum bis;Kurs;Notiz;Kurstyp. The Kurs is the units of Währung 2 for 1 EUR with 6 decimals and a decimal comma, valid for the one day in Datum von and Datum bis; the Notiz is the name of the bank and the Kurstyp is 5 (Freier Kurs).
- Download the file as above.
- In DATEV Kanzlei-Rechnungswesen or DATEV Rechnungswesen, open the Kurstabelle and choose Importieren.
- The first time, create an ASCII import format with the fields in this order: Währung 1, Währung 2, Datum von, Datum bis, Kurs, Notiz, Kurstyp. Set the field separator to
;and no text delimiter. The file has no header line. - Select the downloaded file with that import format and start the import. The rates appear in the Kurstabelle as Freier Kurs.
ERPNext
For the Currency Exchange records of ERPNext. Set base_currency to your company’s currency; every row then converts one foreign currency into it.
Download the ECB rates for ERPNext
curl -G https://api.currencyapi.com/v3/official/range \
-d source=ecb \
-d date_from=2026-09-25 \
-d date_to=2026-09-28 \
-d currencies=USD \
-d format=erpnext \
-H "apikey: YOUR-API-KEY" \
-o ecb-erpnext-2026-09-25-2026-09-28.csv
File
Date,From Currency,To Currency,Exchange Rate,For Buying,For Selling
2026-09-25,USD,EUR,0.876962203,1,1
2026-09-28,USD,EUR,0.878889084,1,1
From Currency is the foreign currency, To Currency the base currency, and Exchange Rate the units of the base currency for 1 unit of the foreign currency (9 decimals), valid for buying and selling.
- Download the file as above.
- In ERPNext, create a new Data Import: Document Type Currency Exchange, Import Type Insert New Records, and save it.
- Attach the downloaded file as the Import File. ERPNext maps the columns by their names; check the preview.
- Click Start Import. The rates appear in the Currency Exchange list.
Odoo
For the rates of one currency in Odoo, which imports the rates of each currency separately. Request exactly one currency (more return a 422) and set base_currency to your company’s currency.
Download the ECB USD rates for Odoo
curl -G https://api.currencyapi.com/v3/official/range \
-d source=ecb \
-d date_from=2026-09-25 \
-d date_to=2026-09-28 \
-d currencies=USD \
-d format=odoo \
-H "apikey: YOUR-API-KEY" \
-o ecb-odoo-2026-09-25-2026-09-28.csv
File
name,company_rate
2026-09-28,1.1378
2026-09-25,1.1403
name is the date and company_rate the units of the currency for 1 unit of the base currency (Odoo’s "Unit per" rate), newest first as Odoo lists them.
- Download the file as above.
- In Odoo, go to Accounting → Configuration → Currencies and open the currency (activate it first if needed).
- Open its list of rates and choose Import records from the actions menu.
- Upload the downloaded file, check that
nameandcompany_rateare mapped to the date and the company rate, then click Import.
Errors
Every error response carries a stable, machine-readable error.code next to the human-readable message, actions with links to the next step, and an info link to this page.
| Status | error.code | When |
|---|---|---|
403 | plan_upgrade_required | /v3/official/range on a plan without the range endpoint, or with more than one currency on a plan limited to one |
404 | no_rates_published | The bank published nothing on the requested date or in the 14 days before it (e.g. a date before its history starts), or nothing in the requested range |
422 | currency_not_published | base_currency is not a currency the bank published on that date |
422 | invalid_parameters | A parameter is invalid, e.g. compare together with an accounting import format; errors lists the messages per parameter |
404 response
{
"message": "European Central Bank published no official rates on 1998-06-01 or in the 14 days before it.",
"error": {
"code": "no_rates_published",
"message": "European Central Bank published no official rates on 1998-06-01 or in the 14 days before it."
},
"actions": {
"sources": "https://api.currencyapi.com/v3/official/sources",
"docs": "https://currencyapi.com/docs/openapi.yaml"
},
"info": "For more information, see documentation: https://currencyapi.com/docs/official"
}
See Request Status Codes for the errors every endpoint shares.