Bank of Canada
Bank of Canada Valet API — Canada's policy rate, CAD exchange rates and yields as a simple JSON/CSV API
For Canadian monetary and financial series from the source — the target for the overnight rate, USD/CAD and other exchange rates, benchmark bond yields, the Bank's own commodity price index — with an API that is a model of simplicity.
Reach for it when…
For Canadian monetary and financial series from the source — the target for the overnight rate, USD/CAD and other exchange rates, benchmark bond yields, the Bank's own commodity price index — with an API that is a model of simplicity.
Not for: Canadian CPI, GDP and jobs (Statistics Canada), TSX prices, anything intraday.
Units, revisions, traps
Units. Rates in percent; exchange rates in Canadian dollars per unit of foreign currency (FXUSDCAD = CAD per USD).
Revisions. Not revised.
- Series names are mnemonic (FXUSDCAD, V39079 for the overnight target) — look them up in the Valet series list.
- The 'recent' parameter counts observations, not days.
- Exchange rates are noon-free since 2017: one daily average rate at 16:30 ET.
Classic mistake: Reading FXUSDCAD as US dollars per Canadian dollar.
Three recipes
Each recipe: Python · Excel · Sheets, with how to read the result. Python recipes run under pandas; recipe 1 is re-run by the weekly check where the source allows it.
How to use it in your own work
Copy the snippet, change the series id, read the result the way the footer says. Replace YOUR_…_KEY with your own key where one is needed.
Recipe 1USD/CAD, daily
import requests, pandas as pd
u = "https://www.bankofcanada.ca/valet/observations/FXUSDCAD/json?recent=60"
j = requests.get(u, timeout=30).json()
df = pd.DataFrame([(o["d"], float(o["FXUSDCAD"]["v"])) for o in j["observations"]], columns=["date", "cad_per_usd"])
print(df.set_index(pd.to_datetime(df.date))["cad_per_usd"].tail())- Data → From Web → https://www.bankofcanada.ca/valet/observations/FXUSDCAD/csv?recent=60 → skip the metadata rows.
=IMPORTDATA("https://www.bankofcanada.ca/valet/observations/FXUSDCAD/csv?recent=60")Recipe 2The policy rate
import requests, pandas as pd
u = "https://www.bankofcanada.ca/valet/observations/V39079/json?start_date=2020-01-01"
j = requests.get(u, timeout=30).json()
df = pd.DataFrame([(o["d"], float(o["V39079"]["v"])) for o in j["observations"]], columns=["date", "target"])
print(df.drop_duplicates("target").tail(8))- From Web with the CSV form of the URL.
=IMPORTDATA with the CSV form.Recipe 3Benchmark bond yields
import requests, pandas as pd
u = "https://www.bankofcanada.ca/valet/observations/group/bond_yields_benchmark/json?recent=10"
j = requests.get(u, timeout=30).json()
print(pd.DataFrame(j["observations"]).tail(3).T)- From Web with the CSV form.
=IMPORTDATA with the CSV form.Series → question map
The ids we use from Bank of Canada Valet API, each with the question it answers. The catalog's compare view reads the concept tags behind these rows.
| Series | Answers | Region | Concept |
|---|---|---|---|
| FXUSDCAD | Canadian dollars per US dollar | Canada | fx_usd |
| V39079 | What is the Bank of Canada's policy rate? | Canada | policy_rate |
| BD.CDN.10YR.DQ.YLD | Where is the 10-year Canada yield? | Canada | yield_10y |
| BD.CDN.2YR.DQ.YLD | Where is the 2-year Canada yield? | Canada | yield_2y |
Compare with
Same question, different source: FRED, RBA statistical tables, EIA API. The compare view lines up coverage, frequency, history and access side by side and lists what the combination makes possible.
Open compare: Bank of Canada Valet API · FRED · RBA statistical tables →
Questions readers ask
Is Valet free?
Yes, no key; JSON, CSV and XML.
Where are the series names?
bankofcanada.ca/valet/lists/series, or the 'group' endpoints that bundle related series.
Where is Canadian CPI?
Statistics Canada (statcan.gc.ca) and its Web Data Service; FRED mirrors the headline.
From the paper
Educational only — we explain, we never advise · snippet licence: public domain · corrections to [email protected], fixed within a day and logged in the changelog.