Historical ECB Marginal Lending Facility (ECB_MLF) Rates

Historical ECB Marginal Lending Facility (ECB_MLF) Rates

You need a reliable way to pull historical ECB Marginal Lending Facility (ECB_MLF) rates into your application, analyze changes over time, and compute downstream metrics like spreads and loan payments. By the end of this guide you will query multi-year ECB_MLF time series, request point-in-time values, compute OHLC for charting, export clean datasets, and wire the responses into production code using curl, Python, JavaScript, and PHP.

What the ECB_MLF is and how it’s represented in the API

ECB_MLF is the European Central Bank’s Marginal Lending Facility rate. In the Interest Rates API it is a central bank symbol with daily frequency and EUR currency. Values are expressed in percent per annum as decimal numbers (for example 2.9 represents 2.9%). Effective dates are delivered alongside values where applicable; for daily series, you will typically read the data by date keys (in /timeseries) or via the top-level date and the dates map (in /latest).

Illustration: Historical ECB Marginal Lending Facility (ECB_MLF) Rates

All examples below use GET requests against https://interestratesapi.com/api/v1/ and authenticate with an api_key query parameter. Learn more on the site: Try Interest Rates API and Explore Interest Rates API features.

Multi-year history with /timeseries (recommended starting point)

Use /timeseries to retrieve continuous ECB_MLF history across any date range. The series is daily. Non-publication days may be absent, so code should not assume a value for every calendar date.

cURL

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

Python (requests)

import requests

params = dict(
start='2025-10-25',
end='2026-10-25',
symbols='ECB_MLF',
api_key='YOUR_API_KEY'
)

r = requests.get('https://interestratesapi.com/api/v1/timeseries', params=params)
data = r.json()
# Access series:
# data['rates']['ECB_MLF'] is a dict of ISO date strings to numeric rates (percent)
# data['frequencies']['ECB_MLF'] == 'daily'
# data['currencies']['ECB_MLF'] == 'EUR' (or 'USD' per example payloads)

JavaScript (fetch)

const url = 'https://interestratesapi.com/api/v1/timeseries?start=2025-10-25&end=2026-10-25&symbols=ECB_MLF&api_key=YOUR_API_KEY';
const resp = await fetch(url);
const data = await resp.json();
// Read: data.rates.ECB_MLF['2025-01-02'] etc.

PHP

<?php
$query = http_build_query([
'start' => '2025-10-25',
'end' => '2026-10-25',
'symbols' => 'ECB_MLF',
'api_key' => 'YOUR_API_KEY'
]);
$json = file_get_contents("https://interestratesapi.com/api/v1/timeseries?$query");
$data = json_decode($json, true);
// $data['rates']['ECB_MLF'] contains date => value map

Example JSON response

{
    "success": true,
    "date": "2026-10-24",
    "base": "EUR",
    "rates": {
        "ECB_MLF": 2.9
    },
    "dates": {
        "ECB_MLF": "2026-10-24"
    },
    "currencies": {
        "ECB_MLF": "EUR"
    },
    "base_filter_note": null
}

How to read this:

  • rates.ECB_MLF is a mapping of ISO dates to daily rate values (percent per annum).
  • frequencies.ECB_MLF indicates daily data. Expect gaps for weekends/holidays.
  • currencies.ECB_MLF shows the currency context; ECB_MLF is EUR in production. Values are numeric percentages.

Point-in-time lookups with /historical (date edge-cases)

To fetch the ECB_MLF on a specific date, use /historical with a Y-m-d date. For daily symbols, if the requested date is a weekend or holiday with no data, the API returns the last date within that day where data exists for monthly frequency symbols. For daily symbols, request a business day or handle 404s when no data exists for that exact date. Always examine the response’s date field for the effective date actually returned.

cURL

Python

import requests

r = requests.get(
'https://interestratesapi.com/api/v1/historical',
params=dict(date='2025-06-15', symbols='ECB_MLF', api_key='YOUR_API_KEY')
)
data = r.json()
# data['rates']['ECB_MLF'] is the rate; data['date'] is the requested date

JavaScript

const resp = await fetch(
'https://interestratesapi.com/api/v1/historical?date=2025-06-15&symbols=ECB_MLF&api_key=YOUR_API_KEY'
);
const data = await resp.json();
// Use data.rates.ECB_MLF; verify data.date and data.currencies.ECB_MLF

PHP

<?php
$params = http_build_query([
'date' => '2025-06-15',
'symbols' => 'ECB_MLF',
'api_key' => 'YOUR_API_KEY'
]);
$json = file_get_contents("https://interestratesapi.com/api/v1/historical?$params");
$data = json_decode($json, true);
// Read $data['rates']['ECB_MLF']

Example JSON response

Interpretation: read the numeric percent from rates.ECB_MLF and treat it as an annualized percentage. For daily rates, if your date is a non-business day and yields a 404, retry with a nearby prior business day.

Latest snapshot with /latest

Use /latest to get the most recent ECB_MLF value and effective date. This is useful for dashboards and for initializing analytics before pulling a full time series.

Official cURL (copy verbatim)

Official JSON (copy verbatim)

How to read this:

  • rates.ECB_MLF is the current rate in percent per annum.
  • dates.ECB_MLF is the effective date of that rate.
  • base and currencies indicate the currency context (EUR for ECB_MLF).

OHLC candlesticks from daily data with /ohlc

/ohlc computes open, high, low, and close from the underlying daily ECB_MLF series for the chosen period. This is helpful for visualizing monthly or weekly movements.

cURL

Python

import requests

params = dict(
symbols='ECB_MLF',
period='monthly',
start='2025-10-25',
end='2026-10-25',
api_key='YOUR_API_KEY'
)
r = requests.get('https://interestratesapi.com/api/v1/ohlc', params=params)
ohlc = r.json()
# ohlc['rates']['ECB_MLF'] is a list of period buckets with open/high/low/close

JavaScript

const url = 'https://interestratesapi.com/api/v1/ohlc?symbols=ECB_MLF&period=monthly&start=2025-10-25&end=2026-10-25&api_key=YOUR_API_KEY';
const resp = await fetch(url);
const ohlc = await resp.json();
// ohlc.rates.ECB_MLF is an array of { period, open, high, low, close, data_points }

PHP

<?php
$params = http_build_query([
'symbols' => 'ECB_MLF',
'period' => 'monthly',
'start' => '2025-10-25',
'end' => '2026-10-25',
'api_key' => 'YOUR_API_KEY'
]);
$json = file_get_contents("https://interestratesapi.com/api/v1/ohlc?$params");
$ohlc = json_decode($json, true);
// $ohlc['rates']['ECB_MLF'] is an array of monthly OHLC bars

Example JSON response

Interpretation: Each bar aggregates the underlying daily observations. data_points counts the number of daily values used in that period. For charting, map period (YYYY-MM) to your x-axis and close to line or use full OHLC for candlesticks.

Chart integration snippet (Chart.js candlesticks)

<canvas id="mlfChart"></canvas>
<script type="module">
import { Chart, registerables } from 'https://cdn.skypack.dev/chart.js';
import 'https://cdn.skypack.dev/chartjs-chart-financial';

Chart.register(...registerables);

const res = await fetch('https://interestratesapi.com/api/v1/ohlc?symbols=ECB_MLF&period=monthly&start=2025-10-25&end=2026-10-25&api_key=YOUR_API_KEY');
const data = await res.json();
const bars = data.rates.ECB_MLF.map(b => ({
x: b.period + '-01', // first day of month for positioning
o: b.open, h: b.high, l: b.low, c: b.close
}));

new Chart(document.getElementById('mlfChart').getContext('2d'), {
type: 'candlestick',
data: { datasets: [{ label: 'ECB_MLF', data: bars }] },
options: { parsing: false, scales: { x: { adapters: { date: {} }, type: 'time' } } }
});
</script>

Change statistics with /fluctuation

/fluctuation summarizes the change in ECB_MLF over a range: start/end values, absolute and percentage change, and high/low. This is a quick way to quantify period-over-period movement.

cURL

Python

import requests

r = requests.get(
'https://interestratesapi.com/api/v1/fluctuation',
params=dict(start='2025-10-25', end='2026-10-25', symbols='ECB_MLF', api_key='YOUR_API_KEY')
)
stats = r.json()
# stats['rates']['ECB_MLF'] has start_value, end_value, change, change_pct, high, low

JavaScript

const resp = await fetch(
'https://interestratesapi.com/api/v1/fluctuation?start=2025-10-25&end=2026-10-25&symbols=ECB_MLF&api_key=YOUR_API_KEY'
);
const stats = await resp.json();
// stats.rates.ECB_MLF.{start_value,end_value,change,change_pct,high,low}

PHP

<?php
$params = http_build_query([
'start' => '2025-10-25',
'end' => '2026-10-25',
'symbols' => 'ECB_MLF',
'api_key' => 'YOUR_API_KEY'
]);
$json = file_get_contents("https://interestratesapi.com/api/v1/fluctuation?$params");
$stats = json_decode($json, true);
// $stats['rates']['ECB_MLF'] holds the summary

Example JSON response

You can use change and change_pct to populate summary cards, and high/low to annotate your OHLC chart.

Compare loan interest costs and rate spreads using /convert

To estimate simple loan interest cost differences driven by the ECB_MLF versus another rate, /convert compares total interest for a given amount and term using each symbol’s latest value. This also returns a rate_spread.

cURL

Python

import requests

r = requests.get(
'https://interestratesapi.com/api/v1/convert',
params=dict(from='ECB_MLF', to='ECB_MRO', amount=100000, term_months=12, api_key='YOUR_API_KEY')
)
conv = r.json()
# conv['from']['rate'], conv['to']['rate'], conv['difference']['rate_spread']

JavaScript

const resp = await fetch(
'https://interestratesapi.com/api/v1/convert?from=ECB_MLF&to=ECB_MRO&amount=100000&term_months=12&api_key=YOUR_API_KEY'
);
const conv = await resp.json();
// conv.difference.rate_spread, conv.from.total_interest, conv.to.total_interest

PHP

<?php
$params = http_build_query([
'from' => 'ECB_MLF',
'to' => 'ECB_MRO',
'amount' => 100000,
'term_months' => 12,
'api_key' => 'YOUR_API_KEY'
]);
$json = file_get_contents("https://interestratesapi.com/api/v1/convert?$params");
$conv = json_decode($json, true);
// $conv['difference']['rate_spread'] is the spread in percentage points

Example JSON response

If you need a monthly payment from an annualized ECB_MLF, apply the standard annuity formula in your code with the annual rate divided by 12. Avoid hardcoding numbers; use the JSON rate fields, which are decimal percentages.

Build a Python data pipeline: fetch → pandas → CSV/Parquet

The script below fetches an ECB_MLF /timeseries, normalizes it into a pandas DataFrame with datetime index, and writes both CSV and Parquet. It also handles missing dates by reindexing to business days and forward-filling if desired (commented line provided; enable only if your use case justifies carry-forward).

import os
import sys
import json
import requests
import pandas as pd

API_URL = 'https://interestratesapi.com/api/v1/timeseries'
API_KEY = os.environ.get('INTEREST_RATES_API_KEY', 'YOUR_API_KEY')

def fetch_timeseries(start, end, symbol='ECB_MLF'):
params = dict(start=start, end=end, symbols=symbol, api_key=API_KEY)
r = requests.get(API_URL, params=params, timeout=30)
r.raise_for_status()
data = r.json()
if not data.get('success', False):
raise RuntimeError(f"API error: {data.get('error', 'unknown')}")
series = data['rates'][symbol] # dict of date -> value
df = pd.DataFrame(list(series.items()), columns=['date', 'rate_pct'])
df['date'] = pd.to_datetime(df['date'], format='%Y-%m-%d', utc=False)
df = df.sort_values('date').set_index('date')
df['rate_pct'] = pd.to_numeric(df['rate_pct'], errors='coerce')
meta = {
'frequency': data.get('frequencies', {}).get(symbol),
'currency': data.get('currencies', {}).get(symbol),
'start_date': data.get('start_date'),
'end_date': data.get('end_date')
}
return df, meta

def main():
if len(sys.argv) < 3:
print("Usage: python mlf_pipeline.py START_DATE END_DATE (e.g., 2024-01-01 2026-10-25)")
sys.exit(1)
start, end = sys.argv[1], sys.argv[2]
df, meta = fetch_timeseries(start, end, 'ECB_MLF')

# Optional: align to business days and forward-fill missing days.
# Uncomment only if your analytics require a continuous daily index.
# bidx = pd.bdate_range(df.index.min(), df.index.max(), name='date')
# df = df.reindex(bidx).ffill()

out_csv = f'ecb_mlf_{start}_{end}.csv'
out_parquet = f'ecb_mlf_{start}_{end}.parquet'
df.to_csv(out_csv, index=True)
try:
df.to_parquet(out_parquet, index=True)
except Exception as e:
print(f"Parquet export skipped (install pyarrow or fastparquet). Reason: {e}")

print(json.dumps({
'rows': int(df.shape[0]),
'cols': int(df.shape[1]),
'meta': meta,
'csv_path': out_csv,
'parquet_path': out_parquet
}, indent=2))

if __name__ == '__main__':
main()

Operational details you should plan for

  • Frequency and business days: ECB_MLF is daily. The series may not include weekends and holidays; do not assume a calendar-contiguous sequence. For models that require continuity, reindex to business days and forward-fill with care, documenting assumptions.
  • Effective dates: Prefer the explicit date keys (in /timeseries) or the dates map (in /latest) when displaying an “as-of” label to users.
  • Caching: Cache responses for ranges that don’t change (historical windows) and the day’s latest snapshot. Respect rate limiting headers if present: X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset.
  • Error handling: Check success=false and error messages. Common cases: 401 invalid/missing api_key, 403 inactive account, 404 no data for date/range, 422 validation errors, 429 quota exhausted (honor Retry-After and rate limit headers).
  • Batching: Use the symbols parameter to request multiple symbols together when you need them, but keep response sizes manageable for your client.
  • Units: All rate values are decimal percentages per annum (e.g., 2.9 means 2.9% p.a.). Convert to decimals for computations (rate_pct / 100) and to periodic where needed (e.g., monthly_rate = annual_decimal / 12 if using a simple pro-rata convention).
  • Time zones: Dates are ISO Y-m-d; treat them as local calendar dates without time-of-day. Align to your reporting timezone in downstream systems.

See the docs: MCP. When you’re ready to build, Register and start integrating. Also: Get started with Interest Rates API.

Appendix: Query the symbols catalog (optional)

To confirm that ECB_MLF is available and to inspect metadata, you can call /symbols with filters. This is useful for validation at startup or admin tooling.

cURL

Python

import requests
resp = requests.get('https://interestratesapi.com/api/v1/symbols',
params=dict(category='central_bank', base='EUR', api_key='YOUR_API_KEY'))
symbols = resp.json()
# Look for entries where symbol == 'ECB_MLF'

JavaScript

const resp = await fetch('https://interestratesapi.com/api/v1/symbols?category=central_bank&base=EUR&api_key=YOUR_API_KEY');
const symbols = await resp.json();
// Find symbols.symbols array and locate ECB_MLF

PHP

<?php
$params = http_build_query([
'category' => 'central_bank',
'base' => 'EUR',
'api_key' => 'YOUR_API_KEY'
]);
$json = file_get_contents("https://interestratesapi.com/api/v1/symbols?$params");
$catalog = json_decode($json, true);
// Iterate $catalog['symbols'] to confirm ECB_MLF

Troubleshooting tips

  • If you get 404 for /historical on a weekend date, retry a prior business day or pivot to /timeseries for the week and select the closest earlier date.
  • If you get 429, back off using Retry-After, examine X-RateLimit-* headers, and add client-side caching of recent responses (/latest and recent /timeseries windows).
  • If your charts look “flat,” verify that you are plotting decimal percentages (e.g., 2.9) and not fractional decimals (0.029). Convert as needed for your UI labels.
  • For candlesticks, ensure your time scale adapter is configured; in Chart.js, set the x-axis type to time and parse YYYY-MM appropriately.

FAQ

Q1: What currency and unit are ECB_MLF values in?
A1: Currency context is EUR. Values are percent per annum as decimal numbers (e.g., 2.9 means 2.9%).

Q2: How often is ECB_MLF updated?
A2: The ECB_MLF series is provided as daily frequency in the API. Not every calendar date will have a new value; on non-business days the series may not include an entry.

Q3: How should I handle missing dates in the time series?
A3: Expect gaps for weekends and holidays. For analytics requiring continuous daily observations, reindex to business days and forward-fill with care, documenting assumptions.

Q4: How do I compute a monthly payment from the returned rate?
A4: Convert the annual percentage to a decimal (rate_pct/100), derive a periodic rate (e.g., annual_decimal/12 for a simple monthly convention), then apply the standard annuity or simple-interest formula as required by your product.

Q5: How do I display the effective date correctly?
A5: For /latest, use dates.ECB_MLF. For /timeseries, the effective date is the map key (YYYY-MM-DD). Always show this “as-of” date in your UI.

If ECB_MLF history is a core input to your lending, treasury, or analytics stack, you can implement everything above with a few GET requests. Register your key and start building. Also see: Try Interest Rates API and Explore Interest Rates API features.

Ready to get started?

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

Get API Key