Comparing the nine country codes used here requires nine policy-rate requests, each charged as one metered unit. To compare policy rates across countries, keep the instrument, currency and source date alongside each value.
Do it with the API
Policy rates are live on every plan, including Free. Each request returns one country's latest source observation at or before today UTC. The comparison uses USA, CAN, AUS, SWE, NOR, BRA, CZE, MYS and DEU. DEU represents the ECB deposit facility rate.
- Set your API key Set the
NARWHAL_API_KEYenvironment variable in your shell withexport NARWHAL_API_KEY="your_api_key". Install the Python dependencies withpython -m pip install requests pandas. The script reads the key from the environment and sends it in the Authorization header. - Request each country's latest rate Use one
requests.Sessionand loop over the uppercase country codes. Call/v1/economics/{country}/central-bank/policy-rateonce for each code. Keep the response fields together so each rate retains its currency, instrument and date. - Calculate one comparison value For a point response, read
rate. For a range response, calculate(lower_bound + upper_bound) / 2with decimal arithmetic. This midpoint is your own calculation: Narwhal API returns the published bounds and never computes a midpoint. Values are decimal strings in percent per annum. - Build and sort the table Create a pandas DataFrame with
country,currency,instrument,rateanddate. Take the date fromeffective_onorobserved_on; each response has exactly one. Sort by the calculated rate. Keeping Decimal values preserves the precision of the supplied strings. - Run the complete script Save this as
compare_rates.pyand runpython compare_rates.pyafter public access opens. It prints rates from lowest to highest. HTTP errors stop the script throughraise_for_status(), so an unavailable country does not silently disappear from the comparison.import os from decimal import Decimal import pandas as pd import requests api_key = os.environ["NARWHAL_API_KEY"] base_url = "https://api.narwhalapi.com" countries = ["USA", "CAN", "AUS", "SWE", "NOR", "BRA", "CZE", "MYS", "DEU"] rows = [] with requests.Session() as session: session.headers.update({"Authorization": f"Bearer {api_key}"}) for country in countries: response = session.get( f"{base_url}/v1/economics/{country}/central-bank/policy-rate", timeout=10, ) response.raise_for_status() observation = response.json() if observation["rate_type"] == "point": rate = Decimal(observation["rate"]) elif observation["rate_type"] == "range": rate = ( Decimal(observation["lower_bound"]) + Decimal(observation["upper_bound"]) ) / Decimal("2") else: raise ValueError(f"Unexpected rate_type for {country}") date = ( observation["effective_on"] if "effective_on" in observation else observation["observed_on"] ) rows.append({ "country": observation["country"], "currency": observation["currency"], "instrument": observation["instrument"], "rate": rate, "date": date, }) comparison = pd.DataFrame( rows, columns=["country", "currency", "instrument", "rate", "date"], ).sort_values("rate") print(comparison.to_string(index=False))
What does each country’s rate measure?
These rates are comparable only loosely. An overnight target, a repo rate and a deposit rate describe different instruments. Each also belongs to a currency with its own inflation rate. A numerical ranking alone does not establish which country has tighter monetary policy.
| Country code | Currency | Policy-rate instrument |
|---|---|---|
| USA | USD | Federal funds target range; early history has a point target |
| CAN | CAD | Overnight rate target |
| AUS | AUD | Cash rate target; early history includes target ranges |
| SWE | SEK | Policy rate, called the repo rate until 8 June 2022 |
| NOR | NOK | Sight deposit rate |
| BRA | BRL | Selic target |
| CZE | CZK | Two-week repo rate |
| MYS | MYR | Overnight policy rate |
| DEU | EUR | ECB deposit facility rate |
The saved US example has a federal funds target range of 3.50 to 3.75 percent, effective 11 December 2025. Its calculated midpoint is (3.50 + 3.75) / 2 = 3.625 percent. That figure is a comparison value derived from the example, not a published point target or a claim about today's rate.
Preserve the original bounds if you retain the comparison. A single midpoint removes the width of the target range from the printed table. For Brazil, use the Selic target returned for BRA.
The source notices for these observations are:
- Source: Board of Governors of the Federal Reserve System
- Source: Bank of Canada. This information is available free of charge on the Bank of Canada website: https://www.bankofcanada.ca. Narwhal normalised the format.
- Source: Reserve Bank of Australia 2026. This information is available free of charge on the RBA website: https://www.rba.gov.au. No endorsement is implied.
- Source: Sveriges Riksbank, with the date of the data.
- Source: Norges Bank
- Source: Banco Central do Brasil (SGS 432), Open Data Commons Open Database License (ODbL).
- Source: the CNB
- Source: Bank Negara Malaysia. Data and information are subject to Terms of Use for BNM Datasets. https://www.bnm.gov.my/terms-of-use-bnm-datasets
- Source: European Central Bank (ECB). This information is available free of charge on the ECB website: https://www.ecb.europa.eu. Narwhal's modifications are to the format only.
How to compare real rates
A simple approximate real rate subtracts inflation from the nominal policy rate: real rate ≈ policy rate − inflation. Use percentages on both sides of the subtraction. For a target range, identify the nominal input as your calculated midpoint.
For countries that have an inflation route, request /v1/economics/{country}/inflation and read year_over_year. This includes USA, CAN, AUS and DEU. A 404 means no data; leave that country's real-rate result absent rather than substituting zero inflation.
Keep the inflation period beside the policy-rate date, since the observations can refer to different times. The real interest rate calculation explains the subtraction. Inflation adjustment still leaves differences between the underlying policy instruments.
Why is the euro area one row?
Any supported euro member code returns the same ECB deposit facility rate. Using DEU once avoids repeating the same instrument across the comparison. For historical requests, coverage starts at each member's euro adoption date, so the available history can differ between member codes.
Why does the date differ between countries?
effective_on is the date the rate took effect. observed_on is the date the source recorded the value. Sources also publish different observation patterns, so latest responses need not share a date. Future effective dates never replace the current rate early.
For a historical comparison, add the same date=YYYY-MM-DD to every request. Each returns the latest source observation at or before that date. Days without source observations are not invented, so retain each returned date.
Published .
Next steps
- Central-bank interest rates API
- How-toTrack central-bank rate changes
- How-toCalculate the real interest rate
- API referencePolicy-rate API reference
Create a free key and call the API from your own code. Get a free API key
