# Bundesbank Economic Time Series Scraper (SDMX, No API Key) (`ninhothedev/bundesbank-scraper`) Actor

$0.5/1K 🔥 Bundesbank scraper! German interest rates, money supply, FX & property price series. No key. JSON, CSV, Excel or API in seconds. Feed macro research & financial models ⚡

- **URL**: https://apify.com/ninhothedev/bundesbank-scraper.md
- **Developed by:** [ninhothedev](https://apify.com/ninhothedev) (community)
- **Categories:** Developer tools, Automation
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $0.50 / 1,000 results

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/platform/actors/running/actors-in-store#pay-per-event

## What's an Apify Actor?

Actors are web data automations that power AI and operations. They run on the Apify platform to scrape websites, process data, connect APIs, and automate workflows.
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.
Actors are written with capital "A".

## 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.
The best way to integrate Actors is as follows.

- **AI agents and MCP clients** — the [Apify MCP server](https://docs.apify.com/integrations/mcp.md) at `https://mcp.apify.com` (remote, streamable HTTP, OAuth on first use).
- **Agentic workflows and local Actor development** — [Agent Skills](https://apify.com/.well-known/agent-skills/index.json) with the [Apify CLI](https://docs.apify.com/cli/docs.md): `npm install -g apify-cli`, then `apify login`.
- **JavaScript/TypeScript projects** — the official [JS/TS client](https://docs.apify.com/api/client/js/docs.md): `npm install apify-client`.
- **Python projects** — the official [Python client](https://docs.apify.com/api/client/python/docs.md): `pip install apify-client`.
- **Any other language** — the [REST API](https://docs.apify.com/api/v2.md).

For usage examples, see the [API](#api) section below.

For more details, see Apify documentation as [Markdown index](https://docs.apify.com/llms.txt) and [Markdown full-text](https://docs.apify.com/llms-full.txt).

# README

## Bundesbank Economic Time Series Scraper (SDMX, no API key)

Download **German economic time series straight from the Deutsche Bundesbank** — policy and money-market interest rates, Bund yields, monetary aggregates (M1/M2/M3), balance of payments, residential and commercial real estate price indices and euro FX reference rates — as clean, dated, one-row-per-observation JSON/CSV/Excel.

The actor talks to the official Bundesbank SDMX REST service at `https://api.statistiken.bundesbank.de/rest`. It is **free, needs no API key and no registration**. The hard part — Bundesbank SDMX-JSON is *index based* — is solved for you: series keys like `"0:0:0:0:0:0"` and observation keys like `"0"` are resolved back to **real dimension names and real time periods**, so you get `2026-07-28 → 1.1367` instead of meaningless `0:0:0` labels.

- **Cost:** roughly **$0.5 per 1,000 items** (a single 512 MB compute unit fetches thousands of observations in seconds).
- **Speed:** one HTTP request per series; 100 observations of 3 series finish in a couple of seconds.
- **Output:** one dataset item per observation, plus a discovery mode that lists all 90+ Bundesbank dataflows.

### How is this different from the ECB and Eurostat actors?

This actor scrapes the **Deutsche Bundesbank's own statistics service** — Germany's national central bank. That is a different institution, a different API host and a largely different universe of data than our other macro actors:

| Actor | Source | What it is best for |
|---|---|---|
| **This actor** (`bundesbank-scraper`) | Deutsche Bundesbank SDMX (`api.statistiken.bundesbank.de`) | **German** national statistics: Bund yields and the German term structure, Bundesbank interest rate statistics, MFI/BSI banking data, German balance of payments, German residential + commercial property price indices, German external trade, plus the euro reference rates as republished by the Bundesbank. Deep German detail (regional property indices, Bundesbank base rate, HGB discount rates) that simply does not exist in the ECB or Eurostat feeds. |
| [`ecb-exchange-rates-scraper`](https://apify.com/ninhothedev/ecb-exchange-rates-scraper) | European Central Bank | Daily euro foreign exchange reference rates and currency conversion across the ECB currency list. |
| [`eurostat-scraper`](https://apify.com/ninhothedev/eurostat-scraper) | Eurostat | EU-wide harmonised statistics across all member states (HICP, GDP, unemployment, trade) for cross-country comparison. |

Rule of thumb: **Germany-specific and central-bank-specific → this actor. Euro FX only → ECB actor. Cross-EU comparison → Eurostat actor.**

### What is a flowRef and a key?

Bundesbank data is addressed by two things:

```
https://api.statistiken.bundesbank.de/rest/data/{flowRef}/{key}
                                                 BBEX3   D.USD.EUR.BB.AC.000
```

- **flowRef** — the *dataflow*, i.e. the statistical dataset. Examples: `BBEX3` (exchange rates), `BBSIS` (yields on listed securities), `BBBS2` (monetary aggregates), `BBIN1` (central bank rates), `BBIG1` (money market rates), `BBDY1` (residential property indicator system), `BBDR1` (real estate prices), `BBFBOPV` (balance of payments), `BBNZ1` (national accounts).
- **key** — the dot-separated list of dimension codes that pins down one series inside that dataflow. The first dimension is almost always the frequency (`D`, `M`, `Q`, `A`). Every dataflow has its own number of dimensions — `BBEX3` has 6, `BBIG1` has 8, `BBBS2` has 11, `BBFBOPV` has 17. A key with the wrong number of parts returns HTTP 404.

You write them together as `FLOWREF/KEY`, e.g. `BBEX3/D.USD.EUR.BB.AC.000`.

Find keys in the **Bundesbank time series explorer**: <https://www.bundesbank.de/en/statistics/time-series-databases> (each chart page shows its series code, e.g. `BBEX3.D.USD.EUR.BB.AC.000` — just swap the first dot for a slash). The API docs live at <https://www.bundesbank.de/en/statistics/time-series-databases/help-for-sdmx-web-service>. You can also run this actor in **catalog mode** to dump all 90+ available dataflows with their English and German names.

### Verified example series

All of these were live-tested and return data:

| `FLOWREF/KEY` | Series |
|---|---|
| `BBEX3/D.USD.EUR.BB.AC.000` | ECB euro reference rate, USD per EUR, daily |
| `BBSIS/D.I.ZAR.ZI.EUR.S1311.B.A604.R09XX.R.A.A._Z._Z.A` | Yield on Federal securities (Bunds), 9-year residual maturity, daily |
| `BBBS2/M.U2.Y.U.M30.X.1.U2.2300.Z01.E` | Monetary aggregate **M3**, outstanding amounts, monthly |
| `BBIN1/M.D0.ECB.ECBMIN.EUR.ME` | ECB main refinancing rate, end of month |
| `BBIN1/M.D0.ECB.ECBFAC.EUR.ME` | ECB deposit facility rate, end of month |
| `BBIG1/M.D0.EUR.MMKT.EURIBOR.M03.AVE.MA` | 3-month EURIBOR, monthly average |
| `BBDY1/Q.B10.N.G100.P0040.A` | German owner-occupied housing price index (vdp), quarterly |
| `BBDR1/Q.5R51.N.GIP.GBUK.S.I22.A` | German commercial property price index, offices, quarterly |
| `BBFBOPV/M.N.DE.4A.S1.S1.T.A.FA.P.F._Z.EUR._T.M.N.ALL` | Balance of payments, portfolio investment abroad, monthly |

### Input

| Field | Type | Default | Description |
|---|---|---|---|
| `mode` | select | `series` | `series` = download observations, `catalog` = list all available dataflows |
| `seriesKeys` | array of strings | 3 verified series | `FLOWREF/KEY` combinations to download |
| `lastNObservations` | integer | `100` | Most recent N observations per series (max 5000) |
| `startPeriod` | string | – | Optional first period, e.g. `2020-01-01`, `2020-01`, `2020` |
| `endPeriod` | string | – | Optional last period, same format |
| `maxItems` | integer | `1000` | Hard cap on pushed items (max 20000) |

```json
{
  "mode": "series",
  "seriesKeys": [
    "BBEX3/D.USD.EUR.BB.AC.000",
    "BBIN1/M.D0.ECB.ECBMIN.EUR.ME"
  ],
  "lastNObservations": 250,
  "maxItems": 1000
}
```

### Output

One item per observation (`type: "observation"`):

```json
{
  "type": "observation",
  "flow_ref": "BBEX3",
  "series_key": "D.USD.EUR.BB.AC.000",
  "resolved_key": "D.USD.EUR.BB.AC.000",
  "series_name": "Daily | USD | EUR | BB | AC | 000",
  "title": "Euro foreign exchange reference rate of the ECB / EUR 1 = USD ... / United States",
  "dimensions": {
    "BBK_STD_FREQ": "Daily",
    "BBK_STD_CURRENCY": "USD",
    "BBK_ERX_PARTNER_CURRENCY": "EUR",
    "BBK_ERX_SERIES_TYPE": "BB",
    "BBK_ERX_RATE_TYPE": "AC",
    "BBK_ERX_SUFFIX": "000"
  },
  "date": "2026-07-28",
  "period_raw": "2026-07-28",
  "value": 1.1367,
  "value_raw": "1.1367",
  "unit": null,
  "frequency": "Daily",
  "frequency_code": "D",
  "obs_status": null,
  "attributes": { "BBK_ID": "BBEX3.D.USD.EUR.BB.AC.000", "BBK_DECIMALS": "4" },
  "source": "bundesbank",
  "scraped_at": "2026-07-28T18:12:27.611241+00:00"
}
```

Catalog mode pushes one item per dataflow (`type: "dataflow"`) with `flow_ref`, `name`, `name_de`, `description`, `agency`, `version`, `data_structure`, `url`, `source`, `scraped_at`.

Notes on the fields:

- `date` is the ISO start date of the period; `period_raw` keeps the original SDMX period (`2026-Q1`, `2026-06`, `2026-07-28`). Quarterly, monthly, half-yearly, weekly and annual periods are all mapped.
- `value` is a float, or **`null` when the Bundesbank reports a missing observation** (holidays in daily FX series, unpublished periods). Nulls are kept, not dropped, so your time index stays complete.
- `series_name` is built from the resolved dimension *names*; `title` is the Bundesbank's own English long title where available.
- Every field is nullable — the dataset schema is permissive, so nothing breaks when a series lacks a unit or a status flag.

### Use cases

- **Macro research** — build a German rates + money supply panel (policy rate, EURIBOR, Bund curve, M3) without touching a PDF.
- **Financial modelling** — feed discount curves and Bund yields into DCF, ALM or pension models; the HGB §253 discount rates flow (`BBSDI`) is in here too.
- **German market analysis** — track residential and commercial property price indices by region, German external trade and the German balance of payments.
- **Economic dashboards** — schedule the actor daily and pipe the dataset straight into BI tools, Google Sheets or a database via the Apify API.

### Notes and limits

- Data is public and free; please stay polite with request volume. The Bundesbank returns HTTP 413 if a single query would return too many series — narrow your key instead of using wildcards everywhere.
- Wildcards are supported by the API: leave a dimension empty (`BBIN1/M......`) to fetch every series in that slice — but the number of dots must match the dataflow's dimension count exactly.
- A key that does not exist returns 404; the actor logs it, drops that series and continues with the rest.

### Related actors

- [ECB Exchange Rates Scraper](https://apify.com/ninhothedev/ecb-exchange-rates-scraper)
- [Eurostat Scraper](https://apify.com/ninhothedev/eurostat-scraper)
- [World Bank Scraper](https://apify.com/ninhothedev/worldbank-scraper)
- [Energy Charts Scraper](https://apify.com/ninhothedev/energy-charts-scraper)

### Development

```bash
python tests/test_smoke.py     # 6 offline test groups, stdlib only
python -m src.main             # needs the Apify SDK + an input
```

Data source: © Deutsche Bundesbank. Use of the data is subject to the Bundesbank's terms of use.

# Actor input Schema

## `mode` (type: `string`):

What to scrape. 'series' downloads observations for the flowRef/key combinations below (one dataset item per observation). 'catalog' lists every dataflow (statistical dataset) the Bundesbank publishes, so you can discover new flowRefs.

## `seriesKeys` (type: `array`):

Bundesbank time series to download, written as FLOWREF/KEY, e.g. 'BBEX3/D.USD.EUR.BB.AC.000' (USD per EUR, daily). The flowRef is the dataset (BBEX3 = exchange rates, BBSIS = securities yields, BBBS2 = monetary aggregates, BBIN1 = central bank rates, BBIG1 = money market rates, BBDY1 = residential property indicators, BBFBOPV = balance of payments). The key is the dot separated dimension code list. A wrong key returns HTTP 404 and is skipped. Only used in 'series' mode.

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

How many of the most recent observations to download per series. Ignored when a start or end period is set (then the period window wins). Maximum 5000.

## `startPeriod` (type: `string`):

Optional first period to download, e.g. '2020-01-01' for daily series, '2020-01' for monthly or '2020' for annual series. Leave empty to use 'Last N observations' instead.

## `endPeriod` (type: `string`):

Optional last period to download, same format as the start period, e.g. '2026-06-30'. Leave empty to download up to the latest published observation.

## `maxItems` (type: `integer`):

Hard cap on how many dataset items (observations or dataflows) the run pushes. Use it to keep runs cheap and predictable. Maximum 20000.

## Actor input object example

```json
{
  "mode": "series",
  "seriesKeys": [
    "BBEX3/D.USD.EUR.BB.AC.000",
    "BBSIS/D.I.ZAR.ZI.EUR.S1311.B.A604.R09XX.R.A.A._Z._Z.A",
    "BBBS2/M.U2.Y.U.M30.X.1.U2.2300.Z01.E"
  ],
  "lastNObservations": 100,
  "maxItems": 1000
}
```

# 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 = {
    "seriesKeys": [
        "BBEX3/D.USD.EUR.BB.AC.000",
        "BBSIS/D.I.ZAR.ZI.EUR.S1311.B.A604.R09XX.R.A.A._Z._Z.A",
        "BBBS2/M.U2.Y.U.M30.X.1.U2.2300.Z01.E"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("ninhothedev/bundesbank-scraper").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 = { "seriesKeys": [
        "BBEX3/D.USD.EUR.BB.AC.000",
        "BBSIS/D.I.ZAR.ZI.EUR.S1311.B.A604.R09XX.R.A.A._Z._Z.A",
        "BBBS2/M.U2.Y.U.M30.X.1.U2.2300.Z01.E",
    ] }

# Run the Actor and wait for it to finish
run = client.actor("ninhothedev/bundesbank-scraper").call(run_input=run_input)

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

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

```

## CLI example

```bash
echo '{
  "seriesKeys": [
    "BBEX3/D.USD.EUR.BB.AC.000",
    "BBSIS/D.I.ZAR.ZI.EUR.S1311.B.A604.R09XX.R.A.A._Z._Z.A",
    "BBBS2/M.U2.Y.U.M30.X.1.U2.2300.Z01.E"
  ]
}' |
apify call ninhothedev/bundesbank-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "command": "npx",
            "args": [
                "mcp-remote",
                "https://mcp.apify.com/?tools=ninhothedev/bundesbank-scraper",
                "--header",
                "Authorization: Bearer <YOUR_API_TOKEN>"
            ]
        }
    }
}

```

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/acts/BFWPGjctl8X4H6hI8/builds/564ihr2USX8wbsne7/openapi.json
