BOC (BOC_OVERNIGHT) Historical Data API: Timeseries, Charts & Downloads

BOC (BOC_OVERNIGHT) Historical Data API: Timeseries, Charts & Downloads

You need reliable, machine-readable Bank of Canada Overnight Rate history to backtest funding costs, price variable-rate loans, and build charts—without hand-scraping PDFs. By the end of this guide you will query BOC_OVERNIGHT across multi-year windows, retrieve point-in-time values, generate OHLC candlesticks for charting, compute spreads and loan payments from the returned value, and export clean datasets for downstream analytics.

About BOC_OVERNIGHT: units, timing, and interpretation

Symbol: BOC_OVERNIGHT — the Bank of Canada Overnight Rate. The rate is expressed as a percentage (e.g., 2.25 denotes 2.25%). It is a central bank benchmark associated with CAD and, as documented here, treated as a monthly series in the Interest Rates API.

Illustration: BOC (BOC_OVERNIGHT) Historical Data API: Timeseries, Charts & Downloads

Key points when reading values:

  • Units: percent per annum (no basis points scaling; 2.25 means 2.25%).
  • Effective date: returned as an ISO Y-m-d string in the response. For monthly symbols, the API associates the month’s value with the last day in that period that has data.
  • Currency metadata: responses include a currencies object keyed by symbol for clarity; it describes the currency associated with the rate.

If your workflow assumes business-day daily sampling, be mindful that BOC_OVERNIGHT is monthly in this API; you will want to forward- or back-fill for daily modeling, or simply operate in monthly space.

Try Interest Rates API and Explore Interest Rates API features to see how the endpoints line up with your data pipeline. When you are ready, Get started with Interest Rates API and request your API key.

Quick check: latest BOC_OVERNIGHT value

Start with a sanity check to confirm connectivity and verify the current effective monthly print for BOC_OVERNIGHT. Use GET and authenticate via the api_key query parameter.

Official cURL example (copy verbatim)

curl -s "https://interestratesapi.com/api/v1/latest?api_key=YOUR_API_KEY&symbols=BOC_OVERNIGHT"

Official JSON response (copy verbatim)

{
    "success": true,
    "date": "2026-09-30",
    "base": "CAD",
    "rates": {
        "BOC_OVERNIGHT": 2.25
    },
    "dates": {
        "BOC_OVERNIGHT": "2026-09-30"
    },
    "currencies": {
        "BOC_OVERNIGHT": "CAD"
    },
    "base_filter_note": null
}

How to read it:

  • rates.BOC_OVERNIGHT is the percentage value (2.25% in this example).
  • date is the response’s reference date; dates.BOC_OVERNIGHT is the effective date for the symbol.
  • currencies.BOC_OVERNIGHT tells you the underlying currency context (CAD).

Historical time windows with /timeseries

For modeling and charting, use /timeseries to fetch a continuous sequence. You provide start, end, and symbols. For monthly symbols like BOC_OVERNIGHT, each returned key in the series maps to the effective date used for that month (typically the last data day of the month).

cURL

Python (requests)

import requests

url = "https://interestratesapi.com/api/v1/timeseries"
params = {
"start": "2025-10-13",
"end": "2026-10-13",
"symbols": "BOC_OVERNIGHT",
"api_key": "YOUR_API_KEY"
}
resp = requests.get(url, params=params)
ts = resp.json()

# Access the series for BOC_OVERNIGHT
series = ts["rates"]["BOC_OVERNIGHT"] # dict: date -> value (%)
# Example: iterate and print date, value
for d, v in series.items():
print(d, v)

# Frequency hint (for this symbol, monthly)
freq = ts.get("frequencies", {}).get("BOC_OVERNIGHT")
print("frequency:", freq)

# Currency context
cur = ts.get("currencies", {}).get("BOC_OVERNIGHT")
print("currency:", cur)

JavaScript (fetch)

const url = "https://interestratesapi.com/api/v1/timeseries?start=2025-10-13&end=2026-10-13&symbols=BOC_OVERNIGHT&api_key=YOUR_API_KEY";

const res = await fetch(url);
const ts = await res.json();

const series = ts.rates.BOC_OVERNIGHT; // { "YYYY-MM-DD": value, ... }
for (const [date, value] of Object.entries(series)) {
console.log(date, value);
}

console.log("frequency:", ts.frequencies?.BOC_OVERNIGHT);
console.log("currency:", ts.currencies?.BOC_OVERNIGHT);

PHP

<?php
$url = "https://interestratesapi.com/api/v1/timeseries?start=2025-10-13&end=2026-10-13&symbols=BOC_OVERNIGHT&api_key=YOUR_API_KEY";
$resp = file_get_contents($url);
$data = json_decode($resp, true);

$series = $data["rates"]["BOC_OVERNIGHT"]; // associative array date => value
foreach ($series as $date => $value) {
echo $date . " " . $value . PHP_EOL;
}

$freq = $data["frequencies"]["BOC_OVERNIGHT"] ?? null;
$cur = $data["currencies"]["BOC_OVERNIGHT"] ?? null;
echo "frequency: " . $freq . PHP_EOL;
echo "currency: " . $cur . PHP_EOL;
?>

Example JSON shape (from docs)

Notes for interpreting the series:

  • The API returns a dictionary of date → value (%). For monthly symbols, expect one date per month (the last day with data in that month). When aligning to business-day indices, forward-fill if needed.
  • The frequencies and currencies objects provide metadata per symbol. Use them to branch logic (e.g., monthly resampling vs. daily).
  • If your range includes weekends or holidays, the API includes only dates with published values; you may not see every calendar day.

If you plan to chart or compute rolling averages, normalize the index to month-end and confirm the frequency you expect for BOC_OVERNIGHT in your workflow.

Browse the full product surface at Explore Interest Rates API features and request an API key via Get started with Interest Rates API.

Point-in-time lookups with /historical

Fetch the BOC_OVERNIGHT rate on a single date. For monthly symbols, if the requested day has no direct print (e.g., a mid-month date), the API returns the month’s effective value using the last day with data in that month.

cURL

Python (requests)

import requests

resp = requests.get(
"https://interestratesapi.com/api/v1/historical",
params={"date": "2025-06-15", "symbols": "BOC_OVERNIGHT", "api_key": "YOUR_API_KEY"}
)
data = resp.json()
value = data["rates"]["BOC_OVERNIGHT"] # percentage
effective_date = data.get("date") # request date
symbol_currency = data["currencies"]["BOC_OVERNIGHT"]

JavaScript (fetch)

const res = await fetch(
"https://interestratesapi.com/api/v1/historical?date=2025-06-15&symbols=BOC_OVERNIGHT&api_key=YOUR_API_KEY"
);
const data = await res.json();
const value = data.rates.BOC_OVERNIGHT;
const currency = data.currencies.BOC_OVERNIGHT;

PHP

<?php
$url = "https://interestratesapi.com/api/v1/historical?date=2025-06-15&symbols=BOC_OVERNIGHT&api_key=YOUR_API_KEY";
$resp = file_get_contents($url);
$data = json_decode($resp, true);
echo $data["rates"]["BOC_OVERNIGHT"];
?>

Sample JSON (from docs)

Edge cases:

  • Weekends/holidays: a monthly symbol resolves to the month’s effective print; do not expect distinct weekend values.
  • Out-of-range dates: the API returns a 404 if the date precedes available history; check the error message for available ranges.

Fluctuation stats over a window

Compute absolute and percentage changes, plus high/low for BOC_OVERNIGHT in a date range. This is useful for describing regime shifts or for UI summaries above a chart.

cURL

Python (requests)

import requests

resp = requests.get(
"https://interestratesapi.com/api/v1/fluctuation",
params={"start": "2025-10-13", "end": "2026-10-13", "symbols": "BOC_OVERNIGHT", "api_key": "YOUR_API_KEY"}
)
fx = resp.json()["rates"]["BOC_OVERNIGHT"]
print(fx["start_date"], fx["start_value"], fx["end_value"], fx["change"], fx["change_pct"], fx["high"], fx["low"])

JavaScript (fetch)

const res = await fetch(
"https://interestratesapi.com/api/v1/fluctuation?start=2025-10-13&end=2026-10-13&symbols=BOC_OVERNIGHT&api_key=YOUR_API_KEY"
);
const fx = (await res.json()).rates.BOC_OVERNIGHT;
console.log(fx);

PHP

<?php
$url = "https://interestratesapi.com/api/v1/fluctuation?start=2025-10-13&end=2026-10-13&symbols=BOC_OVERNIGHT&api_key=YOUR_API_KEY";
$data = json_decode(file_get_contents($url), true);
print_r($data["rates"]["BOC_OVERNIGHT"]);
?>

Sample JSON (from docs)

Fields:

  • start_value and end_value are percentages at the first and last data points in the range.
  • change and change_pct summarize the shift; high and low capture the window extremes.

OHLC for candlestick charts

The /ohlc endpoint computes open-high-low-close bars from daily data. For BOC_OVERNIGHT as a monthly series, a monthly period will generally show the open as the first available value in the month and close as the last available value in the month, with data_points indicating count of underlying observations.

cURL

Python (requests)

import requests

resp = requests.get(
"https://interestratesapi.com/api/v1/ohlc",
params={"symbols": "BOC_OVERNIGHT", "period": "monthly", "start": "2025-10-13", "end": "2026-10-13", "api_key": "YOUR_API_KEY"}
)
ohlc = resp.json()["rates"]["BOC_OVERNIGHT"]
for bar in ohlc:
print(bar["period"], bar["open"], bar["high"], bar["low"], bar["close"], bar["data_points"])

JavaScript (fetch)

const res = await fetch(
"https://interestratesapi.com/api/v1/ohlc?symbols=BOC_OVERNIGHT&period=monthly&start=2025-10-13&end=2026-10-13&api_key=YOUR_API_KEY"
);
const ohlc = (await res.json()).rates.BOC_OVERNIGHT;
console.log(ohlc);

PHP

<?php
$url = "https://interestratesapi.com/api/v1/ohlc?symbols=BOC_OVERNIGHT&period=monthly&start=2025-10-13&end=2026-10-13&api_key=YOUR_API_KEY";
$data = json_decode(file_get_contents($url), true);
print_r($data["rates"]["BOC_OVERNIGHT"]);
?>

Sample JSON (from docs)

Charting with Chart.js (candles)

Transform the OHLC array into {x, o, h, l, c} objects for a candlestick plugin or into separate arrays for your plotting library. Example with Chart.js Financial Chart:

<canvas id="bocChart"></canvas>
<script type="module">
// Assumes you included Chart.js and the financial chart plugin
const url = "https://interestratesapi.com/api/v1/ohlc?symbols=BOC_OVERNIGHT&period=monthly&start=2025-10-13&end=2026-10-13&api_key=YOUR_API_KEY";
const res = await fetch(url);
const data = await res.json();
const bars = data.rates.BOC_OVERNIGHT.map(b => ({
x: b.period + "-01", // render at start of month
o: b.open,
h: b.high,
l: b.low,
c: b.close
}));

new Chart(
document.getElementById('bocChart'),
{
type: 'candlestick',
data: { datasets: [{ label: 'BOC_OVERNIGHT', data: bars }] },
options: {
parsing: false,
scales: {
x: { type: 'time', time: { unit: 'month' } },
y: { ticks: { callback: v => v + "%" } }
}
}
}
);
</script>

Tip: data_points tells you how many source observations contributed to each bar—useful for data quality flags.

Compute spreads and loan payments

Two common operations with policy rates are (a) computing a rate spread relative to another benchmark and (b) estimating a loan payment using the rate. Use /convert to quickly compare interest costs against another symbol’s latest value. For custom calculations, fetch /latest and apply your own formulas.

API-based comparison via /convert

Fields:

  • from and to each carry the latest rate and implied simple total_interest over term_months.
  • difference.rate_spread equals from.rate − to.rate in percentage points.

Your own spread and payment math

From /latest, you can compute:

  • Rate spread: spread_pp = rate_a − rate_b.
  • Monthly payment (amortizing): P = r_m × A / (1 − (1 + r_m)^(-n)), where r_m = rate% / 100 / 12, A = principal, n = months. Use the API rate as the APR proxy for illustrative calculations.
  • Simple interest estimate (non-amortizing): interest = A × (rate%/100) × (n/12).

Do not hardcode numbers; always read rates from the API response to keep your model aligned to the latest publication. For production, persist your retrieved rates and recompute spreads/payments upon refresh.

Python data pipeline: fetch → pandas → CSV/Parquet

The snippet below ingests BOC_OVERNIGHT via /timeseries into a tidy monthly DataFrame and exports both CSV and Parquet. It handles missing dates by reindexing to month-end and forward-filling (appropriate for a stepwise policy rate). Adjust fill behavior to your risk policy.

End-to-end Python example

import requests
import pandas as pd

API = "https://interestratesapi.com/api/v1/timeseries"
params = dict(
start="2015-01-01",
end="2026-12-31",
symbols="BOC_OVERNIGHT",
api_key="YOUR_API_KEY"
)

r = requests.get(API, params=params)
j = r.json()

# Extract to DataFrame
series = j["rates"]["BOC_OVERNIGHT"] # dict of date -> value (%)
df = pd.DataFrame(
[(pd.to_datetime(d), v) for d, v in series.items()],
columns=["date", "value_pct"]
).sort_values("date").set_index("date")

# Resample to month-end index (if needed) and forward-fill
df_m = df.resample("M").last().ffill()

# Export
df_m.to_csv("boc_overnight_monthly.csv", float_format="%.4f")
df_m.to_parquet("boc_overnight_monthly.parquet", index=True)

print("rows:", len(df_m), "start:", df_m.index.min().date(), "end:", df_m.index.max().date())

Production tips:

  • Cache raw JSON responses and store the normalized DataFrame with a version tag (e.g., yyyymmdd) to make model runs reproducible.
  • If you join with daily market data, forward-fill monthly policy rates to daily indices but annotate them as monthly to prevent misinterpretation.
  • Schedule refreshes based on the benchmark’s publication cadence (see below).

Operational details: publication, business days, caching

  • Publication cadence: In this API, BOC_OVERNIGHT is modeled as a monthly series. The effective date you should track is the one returned under dates for the symbol.
  • Business-day behavior: Monthly series do not emit a distinct value for each business day. If you require daily sampling, forward-fill the monthly print across the month’s business days in your warehouse.
  • Caching: Upstream rates change only on official publications. Cache GET responses for your dashboard refresh interval (e.g., hourly or daily) and invalidate after new prints land.
  • Time zones: Dates are ISO Y-m-d; treat them as naively aligned to the market day. If your application is timezone-sensitive, convert at presentation time only.
  • Rate limit headers: Watch X-RateLimit-Limit, X-RateLimit-Remaining, and X-RateLimit-Reset. Back off or queue when 429 is returned (Retry-After present).

Explore endpoints and try concrete requests at Try Interest Rates API. When you are ready to integrate, use Register to obtain your API key.

Discoverability: /symbols for catalog lookup

Use /symbols to programmatically discover available central bank or interbank series. You can filter by category and currency. Example:

cURL

Python (requests)

import requests
s = requests.get(
"https://interestratesapi.com/api/v1/symbols",
params={"category": "central_bank", "base": "CAD", "api_key": "YOUR_API_KEY"}
).json()
print("count:", s.get("count"))
for sym in s.get("symbols", []):
print(sym["symbol"], sym["name"], sym["frequency"])

JavaScript (fetch)

const res = await fetch("https://interestratesapi.com/api/v1/symbols?category=central_bank&base=CAD&api_key=YOUR_API_KEY");
const listing = await res.json();
console.log(listing.count, listing.symbols?.map(s => s.symbol));

PHP

<?php
$url = "https://interestratesapi.com/api/v1/symbols?category=central_bank&base=CAD&api_key=YOUR_API_KEY";
$data = json_decode(file_get_contents($url), true);
echo $data["count"] ?? 0;
?>

Sample JSON (from docs)

The shape shows what fields to expect; your filtered call will return entries relevant to CAD and BOC_OVERNIGHT.

Error handling and resilience

Anticipate and surface meaningful errors to users and jobs:

  • 401: Missing or invalid api_key. Verify you are passing ?api_key=YOUR_API_KEY on every GET.
  • 403: Account lacks an active plan.
  • 404: No symbols matched, or no data in the requested range (may include details with available ranges).
  • 422: Validation error (e.g., wrong date format; ensure Y-m-d).
  • 429: Quota exhausted. Inspect Retry-After, X-RateLimit-* headers; implement exponential backoff and request budgeting.

For batch pipelines, log full request URLs (scrub api_key), HTTP status codes, and response bodies. On 404 for a point-in-time date, your handler can try the last business day of the month for a monthly series or adjust to the nearest available month-end.

How to compute monthly payments and spreads from BOC_OVERNIGHT

Here is a minimal, reproducible example using the official latest endpoint values at runtime:

Python snippet

import requests
import math

resp = requests.get(
"https://interestratesapi.com/api/v1/latest",
params={"symbols": "BOC_OVERNIGHT", "api_key": "YOUR_API_KEY"}
).json()

r_annual = resp["rates"]["BOC_OVERNIGHT"] / 100.0
r_month = r_annual / 12.0

principal = 250000.0
months = 300

payment = (r_month * principal) / (1.0 - (1.0 + r_month) ** (-months)) if r_month > 0 else principal / months
print("monthly_payment", round(payment, 2))

# Compare to another rate (ECB_MRO) by fetching both
resp2 = requests.get(
"https://interestratesapi.com/api/v1/latest",
params={"symbols": "BOC_OVERNIGHT,ECB_MRO", "api_key": "YOUR_API_KEY"}
).json()

spread_pp = resp2["rates"]["BOC_OVERNIGHT"] - resp2["rates"]["ECB_MRO"]
print("spread_pp", spread_pp)

This avoids hardcoding numbers; actual results depend on the current API response at call time.

Practical time series pitfalls to avoid

  • Missing calendar days: Monthly policy rates will not emit values for each day. Always treat the index as monthly and reindex to month-end if needed.
  • Daily vs. monthly confusion: Check the frequencies metadata or your symbol catalog to confirm how to resample and chart correctly.
  • data_points in OHLC: A low count may indicate holidays or sparse observations; annotate your charts or dashboards accordingly.
  • Time-window boundaries: /timeseries honors inclusive start/end; ensure start ≤ end and watch for off-by-one errors when stitching adjacent requests.

Reference: Latest endpoint in all supported snippets

Below are consolidated samples for /latest with BOC_OVERNIGHT to copy into your app skeletons.

cURL

Python (requests)

import requests
response = requests.get(
'https://interestratesapi.com/api/v1/latest',
params=dict(symbols='BOC_OVERNIGHT', api_key='YOUR_API_KEY')
)
data = response.json()
print(data["rates"]["BOC_OVERNIGHT"], data["dates"]["BOC_OVERNIGHT"], data["currencies"]["BOC_OVERNIGHT"])

JavaScript (fetch)

const response = await fetch(
'https://interestratesapi.com/api/v1/latest?symbols=BOC_OVERNIGHT&api_key=YOUR_API_KEY'
);
const data = await response.json();
console.log(data.rates.BOC_OVERNIGHT, data.dates.BOC_OVERNIGHT, data.currencies.BOC_OVERNIGHT);

PHP

<?php
$url = 'https://interestratesapi.com/api/v1/latest?symbols=BOC_OVERNIGHT&api_key=YOUR_API_KEY';
$resp = file_get_contents($url);
$data = json_decode($resp, true);
echo $data['rates']['BOC_OVERNIGHT'] . ' ' . $data['dates']['BOC_OVERNIGHT'];
?>

FAQ

Q: What unit is BOC_OVERNIGHT returned in?
A: Percent per annum. The numeric value 2.25 means 2.25%.

Q: How do monthly symbols behave on weekends and holidays?
A: Monthly series do not produce separate weekend values. The effective date corresponds to the last day with data in the month. For daily modeling, forward-fill across business days.

Q: How should I interpret the dates object versus the top-level date?
A: The dates object maps each symbol to its effective date. The top-level date is the response’s reference date, which may be the request date or the service’s stamp for the batch.

Q: What’s the best way to chart BOC_OVERNIGHT?
A: Use /timeseries for monthly values and /ohlc for candlestick summaries. For line charts, plot effective dates on the x-axis and percentages on the y-axis. For daily canvases, forward-fill.

Q: How do I handle errors and rate limits?
A: Inspect HTTP status. On 429, read Retry-After and X-RateLimit-* headers and backoff. On 404s for date ranges, adjust to available windows or surface a “no data” message to the user.

Build your BOC_OVERNIGHT time series, charts, and exports now. Register for your key, review the endpoint catalog in MCP, and start shipping.

Ready to get started?

Get your API key and start validating bank data in minutes.

Get API Key