# ECB Data — Exchange Rates, Policy Rates, Inflation, Money (`dalbian/ecb-statistical-data`) Actor

Official European Central Bank statistics: daily euro reference exchange rates, the three key policy rates, HICP inflation by country, Euribor and the euro area yield curve, M1/M2/M3, unemployment and GDP. Pick a series by name instead of by SDMX key. Free ECB Data Portal, no key.

- **URL**: https://apify.com/dalbian/ecb-statistical-data.md
- **Developed by:** [Benjamin Jerez](https://apify.com/dalbian) (community)
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $30.00 / 1,000 series runs

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.

Learn more: https://docs.apify.com/actors/running/actors-in-store.md#pay-per-event

## What's an Apify Actor?

An Actor is a serverless cloud program that runs on the Apify platform. It has two run modes.
In Batch mode, an Actor accepts a well-defined JSON input, performs an action which can take anything from a few seconds to a few hours,
and optionally produces a well-defined JSON output, datasets with results, or files in key-value store.
In Standby mode, an Actor provides a web server which can be used as a website, API, or an MCP server.

Apify vocabulary and the platform model are defined once, in the agent quickstart at https://apify.com/agents.md.

## How to integrate an Actor?

If asked about integration, you help developers integrate Actors into their projects.
You adapt to their stack and deliver integrations that are safe, well-documented, and production-ready.

Do not guess an integration path. Every one of them is in the agent quickstart at https://apify.com/agents.md: the Apify MCP server, Agent Skills with the Apify CLI, the JavaScript and Python clients, the REST API, and the account-free path for an agent with no human to sign in. It also carries the rule on stating cost before the first paid run.

For examples already wired to this Actor's own input schema, see the [API](#api) section below.

Each client library has reference documentation the quickstart does not restate: [JavaScript/TypeScript](https://docs.apify.com/api/client/js/docs.md) (`npm install apify-client`) and [Python](https://docs.apify.com/api/client/python/docs.md) (`pip install apify-client`).

# README

## ECB Data — Exchange Rates, Policy Rates, Inflation, Money Supply

The European Central Bank publishes about 214 statistical dataflows through its Data Portal, addressed by SDMX keys such as `EXR.D.USD.EUR.SP00.A`. That is the euro/dollar reference rate. Nobody remembers that, which is why this Actor carries a catalogue of the fifteen series people actually ask for and resolves the codes to words.

No API key. No registration. The ECB's own figures, queried live on every run.

### What a default run returns

Picking **Exchange rates** and **Policy rates**, four currencies, last 90 observations: 728 rows in 8 seconds.

| Series | Latest | Value |
| --- | --- | --- |
| `EXR.D.USD.EUR.SP00.A` | 2026-09-18 | 1.1460 US dollar per euro |
| `EXR.D.GBP.EUR.SP00.A` | 2026-09-18 | 0.8588 |
| `EXR.D.JPY.EUR.SP00.A` | 2026-09-18 | 180.94 |
| `EXR.D.CHF.EUR.SP00.A` | 2026-09-18 | 0.9462 |
| `FM.D.U2.EUR.4F.KR.DFR.LEV` | 2026-09-19 | Deposit facility 2.50 % |
| `FM.D.U2.EUR.4F.KR.MRR_FR.LEV` | 2026-09-19 | Main refinancing 2.65 % |
| `FM.D.U2.EUR.4F.KR.MLFR.LEV` | 2026-09-19 | Marginal lending 2.90 % |

Each row carries the decoded dimensions rather than the codes: `currency: "US dollar"`, `frequency: "Daily"`, `unit: "US dollar"`, `observationStatus: "Normal value"`, plus a `dimensions` object with every dimension of that dataflow spelled out — `EXR_TYPE: "Spot"`, `CURRENCY_DENOM: "Euro"`.

### The catalogue

Every key below was queried against the live API and returns observations. None of them is transcribed from documentation.

**Exchange rates** — `EXR`, daily euro reference rates, the ones fixed at 14:15 CET. 29 currencies still published (USD, GBP, JPY, CHF, CNY, AUD, CAD, SEK, NOK, DKK, PLN, CZK, HUF, RON, TRY, BRL, INR, KRW, MXN, ZAR and nine more) plus 15 the ECB stopped quoting — BGN ended 2025-12-31 when Bulgaria adopted the euro, HRK on 2022-12-30, RUB on 2022-03-01. Available daily, monthly, quarterly, half-yearly and annually.

**Policy rates** — `FM.D.U2.EUR.4F.KR.{DFR,MRR_FR,MRR_RT,MLFR}.LEV`: the deposit facility, the main refinancing rate, and the marginal lending facility, as a calendar-daily step series.

**€STR** — `EST.B.EU000A2X2A25.WT` is the rate itself (2.44 % on 2026-09-17), with the number of contributing banks, the number of transactions and the total volume alongside it, and the compounded 1-week to 12-month averages and the compounded index.

**Euribor** — `FM.{M,Q,A}.U2.EUR.RT.MM.EURIBOR{1M,3M,6M,1Y}D_.HSTA`. 3-month Euribor averaged 2.513 % in August 2026. Monthly, quarterly and annual only; the ECB does not publish a daily Euribor here.

**Yield curve** — `YC.B.U2.EUR.4F.G_N_A.SV_C_YM.SR_{3M,1Y,2Y,5Y,10Y,30Y}`, the AAA-rated euro area government spot curve, plus the all-issuer curve at 2 and 10 years. On 2026-09-17 the AAA 10-year stood at 3.4875 % and the all-issuer 10-year at 3.9424 %.

**Government bond yields** — `IRS.M.{area}.L.L40.CI.0000.EUR.N.Z`, the long-term rate for convergence purposes, for 24 areas. August 2026: Germany 3.185 %, Italy 3.986 %, euro area 3.603 %.

**Inflation** — `HICP.M.{area}.N.{item}.4D0.{ANR,INX}` for 32 countries and aggregates: headline, core excluding energy and food, the index level, and a breakdown into energy, food, services, industrial goods and non-energy industrial goods. August 2026: euro area headline 3.2 %, core 2.4 %, energy 14.3 %, food 1.1 %; Germany 2.9 %, Italy 3.2 %.

**Money supply** — `BSI.M.U2.Y.V.{M10,M20,M30,L10}.X.I.U2.2300.Z01.A` for annual growth and the `.X.1...E` variant for outstanding amounts. July 2026: M3 grew 3.38 % to EUR 17 613 983 million, M1 3.15 %, M2 3.34 %.

**Unemployment** — `LFSI.M.{area}.S.UNEHRT.TOTAL0.15_74.T`, monthly, for 34 areas including the United States and Japan. July 2026: euro area 6.4 %, Germany 4.0 %, Italy 5.8 %, France 8.3 %, Spain 10.0 %.

**GDP** — `MNA.Q.Y.{area}.W2.S1.S1.B.B1GQ._Z._Z._Z.{EUR,XDC}.LR.{N,G1,GY}`, real chain-linked volume, its quarter-on-quarter and its year-on-year growth. 28 countries plus the euro area aggregate.

### Raw keys

If you already know the key, put it in `rawSeriesKeys` as `EXR.D.USD.EUR.SP00.A` or `BSI/M.U2.Y.V.M30.X.1.U2.2300.Z01.E` and it is passed through untouched — including wildcards. An empty segment matches everything in that position, so `EXR.D..EUR.SP00.A` returns all 44 currencies at once, and `EXR.D.USD+GBP+JPY.EUR.SP00.A` returns three. The decoding and the summary rows work the same way on a raw key as on a catalogue one.

### Empty is not broken

The Data Portal has two different empty answers and one loud failure, and telling them apart is most of the work:

**HTTP 404** — no series matched the key. `EXR.D.ZZZ.EUR.SP00.A` is a perfectly well-formed SDMX key for a currency the ECB does not quote. This is reported as a summary row with `observations: 0` and a note saying so, not as an error.

**HTTP 200 with an empty body** — the series exists but the window you asked for holds nothing. Asking the daily dollar rate for Saturday 12 and Sunday 13 September 2026 returns exactly this: status 200, zero bytes, not even a CSV header. Reference rates are fixed on business days, so the answer is correct and the summary row says which window came back empty.

**HTTP 400** — the key is malformed, nearly always the wrong number of dimensions. `EXR.D.USD.EUR` has three where `EXR` takes five. The summary row names the dataflow's actual dimensions and the count you supplied, because the portal's own reply is a generic web page with nothing useful in it.

Within a longer window, a TARGET holiday is different again: it comes back as a row with a blank value and status `H`. Those are counted in `holidayPeriods` rather than dropped without trace — 62 of them in the dollar rate's 7 158-row history.

### Who uses this

Treasury and finance teams pulling the official reference rate for invoice conversion and month-end revaluation, where "official" means the ECB's own fixing rather than a broker quote. Economists and research desks building a euro area dashboard without a Bloomberg line. Fintech and accounting products that need a defensible FX source with an audit trail. Anyone who has tried to read an SDMX key and given up.

### Scope and limits

**The euro is always the base.** Reference rates are quoted as foreign currency per one euro. A dollar/sterling cross has to be derived from the two euro legs, and the ECB says explicitly that its rates are for reference, not for transactions.

**Coverage differs by series, and the run tells you which.** Japan has an unemployment rate here but no HICP; euro area GDP growth and member-state GDP growth live in two different series under two different unit codes. An area a series does not carry is dropped from the request by the ECB and the summary shows which series came back.

**Recent periods are provisional.** Inflation, GDP and unemployment are revised. `observationStatus` carries the ECB's own flag — normal, provisional, estimated — on every observation.

**Frequency is only sometimes a choice.** Exchange rates come at five frequencies and Euribor at three. Inflation, money supply, unemployment and bond yields are monthly only, and GDP quarterly only. Asking for daily inflation is answered monthly, with a note in the summary row saying that is what happened.

### Source and licence

**European Central Bank**, through `data-api.ecb.europa.eu`, the ECB Data Portal's SDMX 2.1 API. Open access, no key, no quota published. The ECB permits reuse of its statistics with attribution to the ECB as the source.

Some dataflows reached through the same endpoint are maintained by Eurostat rather than the ECB — unemployment is `EUROSTAT:LFSI` and GDP is `ESTAT:MNA` — and carry Eurostat's own reuse terms. Every row names its `dataflow` and `dataflowTitle` so the provenance travels with the data.

### Frequently asked

**Are these the real ECB rates?**
Yes. The values returned here for 2026-09-18 — USD 1.1460, JPY 180.94, GBP 0.85880, SEK 11.2915 — match the ECB's separate `eurofxref-daily.xml` feed on `www.ecb.europa.eu` exactly. Two different publication paths, the same numbers.

**Why is my daily series missing days?**
Weekends and TARGET holidays. The ECB fixes reference rates on business days only. A window covering only a weekend legitimately returns nothing, and the summary row says so rather than leaving you guessing.

**Why does the inflation figure differ from what I found in another tool?**
There are two consumer-price dataflows on this portal with almost the same name. `ICP` is the older one and its euro area headline series stops at December 2025. `HICP` is the live one and had August 2026 at 3.2 %. This Actor uses `HICP`. Any guide that tells you to query `ICP.M.U2.N.000000.4.ANR` is giving you a series that stopped updating.

**How do I combine a date range with a count?**
They stack. `startPeriod` and `endPeriod` narrow first, then `lastNObservations` takes the most recent N inside that range. A 2015 range on the dollar rate returns 21 observations; the same range with the last 4 returns the last 4 of those.

**Does the API rate-limit?**
Not observably. Twenty-five sequential and twenty concurrent requests all returned 200. The Actor still runs at four concurrent requests, because the portal sits behind a web application firewall that answers a malformed request with a block page, and a burst is what firewalls react to.

**Can I get a series that is not in the catalogue?**
Yes — `rawSeriesKeys` takes any key on the portal, across all 214 dataflows, and the dimension decoding works on it because the structure definitions are fetched at run time rather than hard-coded.

**Why is the unit on a GDP growth rate labelled "Percentage change" when the ECB says EUR?**
Because the ECB files growth series with the currency of the underlying level. `MNA...EUR.LR.GY` carries `UNIT_MEASURE` EUR and a value of 0.49, which is 0.49 per cent, not 0.49 euro. Where the transformation dimension says growth, the unit is corrected and `unitNote` records what the ECB actually filed.

# Actor input Schema

## `datasets` (type: `array`):

Curated series, each one a verified ECB key. Exchange rates follow the currencies below; inflation, unemployment, bond yields and GDP follow the countries below. Everything else is euro area wide.

## `currencies` (type: `array`):

For the exchange-rate series, one per line. Codes or names both work — USD, dollar, Swiss franc. Rates are always foreign currency per one euro. The ECB publishes 29 live reference rates plus 15 that ended when the country joined the euro or the quotation was suspended.

## `countries` (type: `array`):

For inflation, unemployment, bond yields and GDP, one per line. ISO codes or names — DE, Germany, Italy. Leave empty for the euro area aggregate. Coverage differs per series and the summary row says which requests the ECB answered.

## `rawSeriesKeys` (type: `array`):

For anyone who already knows the key. One per line, in the form DATAFLOW.KEY — EXR.D.USD.EUR.SP00.A, or BSI/M.U2.Y.V.M30.X.I.U2.2300.Z01.A. Passed through untouched, including wildcards: an empty segment or USD+GBP+JPY in one position widens the query.

## `startDate` (type: `string`):

Earliest period, as YYYY-MM-DD, YYYY-MM, YYYY-Qn or YYYY. The ECB matches it against the series' own period format, so 2020-01-01 works on a monthly series too.

## `endDate` (type: `string`):

Latest period, same formats. Leave both empty for the whole history.

## `lastNObservations` (type: `integer`):

Return only the most recent N points of each series. Applied by the ECB after the date range, so a range plus 90 gives the last 90 periods inside that range, not the first. Clear this to take every period in range — the euro dollar daily rate alone is then about 7 100 rows.

## `frequency` (type: `string`):

Applies only where the ECB publishes a choice — exchange rates at five frequencies, Euribor at three. Inflation, money supply and unemployment are monthly only and GDP quarterly only; for those this setting is ignored and the summary row says so.

## `maxObservationsPerSeries` (type: `integer`):

Cap per series, keeping the most recent points. The euro/dollar daily rate alone holds about 7 000 observations back to 1999.

## Actor input object example

```json
{
  "datasets": [
    "fx-reference-rates",
    "policy-rates"
  ],
  "currencies": [
    "USD",
    "GBP",
    "JPY",
    "CHF"
  ],
  "lastNObservations": 90,
  "frequency": "daily",
  "maxObservationsPerSeries": 5000
}
```

# Actor output Schema

# API

You can run this Actor programmatically using our API. Below are code examples in JavaScript, Python, and CLI, as well as the OpenAPI specification and MCP server setup.

## JavaScript example

```javascript
import { ApifyClient } from 'apify-client';

// Initialize the ApifyClient with your Apify API token
// Replace the '<YOUR_API_TOKEN>' with your token
const client = new ApifyClient({
    token: '<YOUR_API_TOKEN>',
});

// Prepare Actor input
const input = {
    "datasets": [
        "fx-reference-rates",
        "policy-rates"
    ],
    "currencies": [
        "USD",
        "GBP",
        "JPY",
        "CHF"
    ],
    "lastNObservations": 90
};

// Run the Actor and wait for it to finish
const run = await client.actor("dalbian/ecb-statistical-data").call(input);

// Fetch and print Actor results from the run's dataset (if any)
console.log('Results from dataset');
console.log(`💾 Check your data here: https://console.apify.com/storage/datasets/${run.defaultDatasetId}`);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
items.forEach((item) => {
    console.dir(item);
});

// 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/js/docs

```

## Python example

```python
from apify_client import ApifyClient

# Initialize the ApifyClient with your Apify API token
# Replace '<YOUR_API_TOKEN>' with your token.
client = ApifyClient("<YOUR_API_TOKEN>")

# Prepare the Actor input
run_input = {
    "datasets": [
        "fx-reference-rates",
        "policy-rates",
    ],
    "currencies": [
        "USD",
        "GBP",
        "JPY",
        "CHF",
    ],
    "lastNObservations": 90,
}

# Run the Actor and wait for it to finish
run = client.actor("dalbian/ecb-statistical-data").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print(f"💾 Check your data here: https://console.apify.com/storage/datasets/{run.default_dataset_id}")
for item in client.dataset(run.default_dataset_id).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{
  "datasets": [
    "fx-reference-rates",
    "policy-rates"
  ],
  "currencies": [
    "USD",
    "GBP",
    "JPY",
    "CHF"
  ],
  "lastNObservations": 90
}' |
apify call dalbian/ecb-statistical-data --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,dalbian/ecb-statistical-data"
        }
    }
}
```

The hosted server signs you in with OAuth on first connect, so no API token belongs in this config. Clients without OAuth support can send an `Authorization: Bearer <APIFY_API_TOKEN>` header instead, using a token from API & Integrations in Apify Console (https://console.apify.com/settings/integrations).

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/gaZtsIw2XsVDc9lLE/builds/speOs3dcbJoiXkf1a/openapi.json
