# German Wealth Barometer (`researchdata/german-wealth-barometer`) Actor

Wealth index per German district (Kreis) from official Regionalatlas data (income, unemployment, SGB II, population density) plus NRW Bodenrichtwerte (land values). Outputs a ranked dataset, an SVG heatmap and ZIP-code tiers.

- **URL**: https://apify.com/researchdata/german-wealth-barometer.md
- **Developed by:** [Research Analyst](https://apify.com/researchdata) (community)
- **Security:** Limited permissions
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $2.10 / 1,000 region scoreds

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.
Since this Actor supports Apify Store discounts, the price gets lower the higher subscription plan you have.

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

## German Wealth Barometer (Kreise, NRW Bodenrichtwerte)

One transparent prosperity index per German district: disposable income, unemployment, SGB-II rate, population density, average net cold rent (Zensus 2022) and official land values (Bodenrichtwerte) for Berlin, Niedersachsen, Sachsen-Anhalt and North Rhine-Westphalia (down to municipality and postal code in NRW). Open data only, documented method.

> **Beta:** the upstream API response format is parsed defensively. Please open an issue with an example if a field comes back empty.

### Why use it

- Location and site selection for retail, services and field sales
- Real-estate and investment screening by district or postal code (NRW)
- Regional marketing and flyer planning without buying purchasing-power data
- AI agents: one structured call for 'how wealthy is this region?'

No API keys, no scraping of HTML – the actor talks to the official public API, handles paging,
rate limits and retries, and returns flat JSON you can export as CSV/Excel or call from code,
Make, Zapier, n8n or AI agents (Apify MCP server).

### Input

| Field | Title | Description |
|---|---|---|
| `level` | Level | 'district' = all German Kreise and kreisfreie Städte; 'municipality' and 'postalCode' = North Rhine-Westphalia only (needs Bodenrichtwerte). |
| `states` | States | Names, codes or abbreviations, e.g. Bayern, BY, 09. Empty = all (NRW for municipality / postal code). |
| `regions` | Regions | Optional filter: part of a name (e.g. Düsseldorf) or a key prefix (district/municipality code, postal code prefix such as 402). |
| `indexIncludesLandValue` | Include land values in the index | Off (default): index from income, SGB-II and unemployment, comparable across all of Germany. On: adds land values, which exist for NRW, Niedersachsen, Sachsen-Anhalt and Berlin only, so scores of these states and of the other states are not comparable. Municipality and postal-code levels always use land values. |
| `includeRent` | Include Zensus rent | Adds the average net cold rent per m² of rented dwellings (Zensus 2022, 1 km grid aggregated to districts, dwelling-weighted) as extra columns for all of Germany. Needs one extra ~11 MB download; if it is unavailable the rent columns are null. |
| `indexIncludesRent` | Include rent in the index | Off (default): index unchanged. On: adds district rent as a component (weight 20 %, higher rent = wealthier). Rent exists for all of Germany, so scores stay comparable. The rent grid is downloaded even if 'Include Zensus rent' is off; the run fails with a clear message if it is unavailable. |
| `heatmap` | Create heatmap | Stores a self-contained HTML heatmap in the key-value store (key HEATMAP): colored districts, or colored dots per municipality / postal code in NRW. Also stores PLZ_TIERS (regions grouped into five tiers; per postal area for postal codes). |
| `maxResults` | Max rows | Upper limit of returned rows (cost control). |

Example input:

```json
{
  "level": "district",
  "states": [
    "NW"
  ],
  "indexIncludesLandValue": false,
  "includeRent": true,
  "indexIncludesRent": false,
  "heatmap": true,
  "maxResults": 500
}
```

### Output (one dataset item per result)

```json
{
  "level": "district",
  "key": "05111",
  "name": "Düsseldorf",
  "state": "Nordrhein-Westfalen",
  "stateCode": "05",
  "incomePerInhabitantEur": 29355.0,
  "incomePerInhabitantEurYear": 2022,
  "populationDensityPerKm2": 2845.7,
  "populationDensityPerKm2Year": 2024,
  "unemploymentRatePct": 8.0,
  "unemploymentRatePctYear": 2025,
  "sgb2RatePct": 9.2,
  "sgb2RatePctYear": 2025,
  "landValueMedianEurPerM2": 1025.0,
  "landValueMinEurPerM2": 450.0,
  "landValueMaxEurPerM2": 4200.0,
  "landValueZones": 198,
  "landValueReferenceDate": "2026-01-01",
  "rentNetColdEurPerM2": 9.02,
  "rentDwellings": 34907,
  "rentGridCells": 193,
  "rentUncertainShare": 0.0,
  "rentReferenceDate": "2022-05-15",
  "wealthIndex": 59.8,
  "wealthTier": "medium",
  "indexBasis": "income+sgb2+unemployment",
  "indexRank": 167
}
```

#### Status values

`wealthIndex` = weighted mean of percentile ranks (0-100, higher = wealthier): income 35 %, land value 35 % (only if enabled or at municipality / postal-code level), rent 20 % (only if `indexIncludesRent`), SGB-II rate 15 % and unemployment 15 % (both inverted). Missing components are left out and the weights renormalised; `indexBasis` lists the components used. `wealthTier`: very high ≥ 80, high ≥ 60, medium ≥ 40, low ≥ 20, very low. Percentiles are computed against all German districts (or all NRW municipalities / postal codes), not against your filter. Postal-code rows also carry `plzArea` (first two digits), `latitude`/`longitude` (mean of the zone reference points) and the key-value store holds `HEATMAP` (HTML, hover for details) and `PLZ_TIERS` (JSON: postal codes per tier and median index per postal area). Municipality and postal-code rows carry the indicators of their district (including rent); `districtsSpanned` shows when a postal code crosses districts. `rentNetColdEurPerM2` is the dwelling-weighted mean of the 1 km grid cells whose mid point lies inside the district outline; `rentDwellings` is the sum of the grid's dwelling counts used as weights (not the district's total dwelling stock), `rentGridCells` the number of cells and `rentUncertainShare` the share of cells the Statistical Offices flag as statistically uncertain (KLAMMERN). Rent is the average net cold rent of rented dwellings in residential buildings (no dormitories, no rent-free dwellings), reference date 15 May 2022.

### Use with AI agents (Apify MCP server)

Add the Apify MCP server (`https://mcp.apify.com`) to Claude, Cursor or any MCP client and enable this actor
(`researchdata/german-wealth-barometer`). The agent can then call it directly: describe what you need, the agent fills the input
fields above, runs the actor and reads the dataset. Because results are flat JSON with explicit nulls, an agent can
use them without extra parsing. Set a maximum cost per run to keep agent calls capped.

### Pricing

Pay per event: **$0.003 per `region-scored`** (region scored). You only pay for results you get;
set a max cost per run to cap spending.
Higher Apify plans get automatic volume discounts: Bronze −10 %, Silver −20 %, Gold −30 %.

#### Cost example

At $0.003 per result: 50 results ≈ $0.15, 1,000 results ≈ $3.00.
Set a maximum cost per run in the run options to cap spending.

### Limits

- Not a purchasing-power product: income data are district-level official statistics (latest year is often 2-3 years old). Land values are official zone values (Bodenrichtwerte), not market prices, and only North Rhine-Westphalia, Niedersachsen, Sachsen-Anhalt and Berlin are covered so far (the value is the median of the residential zones per district; including Niedersachsen makes a run noticeably slower because that service delivers about 300 MB of zone geometry; reference dates differ: NRW, Niedersachsen and Sachsen-Anhalt 1 Jan 2026, Berlin 1 Jan 2025).
- The index is a relative ranking, not a valuation. Do not use it as the sole basis for financial decisions.
- Rent comes from the Zensus 2022 grid (reference date 15 May 2022, no asking rents). Cells are assigned to districts by their mid point using generalised district outlines, so border districts can differ slightly from the official district figures; cells without published values (confidentiality) are missing. Spot checks show the grid-based values are a few percent below the published district figures (Düsseldorf 9.02 vs. about 9.2, Köln 8.81 vs. about 9.4 as reported for Zensus 2022; the dwelling-weighted national mean of the grid is 6.73 EUR/m² vs. the official 7.28), and two close districts can swap places. Use rent to compare broad differences, not as an exact district statistic; that is why it is off in the index by default.

### FAQ

**Which regions have land values?**\
North Rhine-Westphalia, Niedersachsen, Sachsen-Anhalt and Berlin (official open data, district level; municipality and postal code only for NRW). More states may follow; district indicators cover all of Germany.

**Where does the rent come from?**\
From the Zensus 2022 grid data of the Statistical Offices (dl-de/by-2-0): average net cold rent per m² in 1 km cells, aggregated to districts. It is a census snapshot from May 2022, not current asking rents.

**Is this the GfK purchasing power?**\
No. It uses official open statistics; commercial purchasing-power data (GfK/NIQ, microm) are licensed products and are not included.

**Why do I get no index for some regions?**\
At least income or land value must be available; otherwise the index is null.

**What does attribution mean?**\
The sources use the licence dl-de/by-2-0: name the data providers when you publish results.

### Data source & terms

Regionalatlas Deutschland and Zensus 2022 rent grid (both Statistische Ämter des Bundes und der Länder, dl-de/by-2-0) Bodenrichtwerte NRW (Open Data NRW, dl-de/by-2-0, source: Gutachterausschüsse für Grundstückswerte NRW), Bodenrichtwerte Niedersachsen (LGLN, dl-de/by-2-0, © GDI-NI), Bodenrichtwerte Sachsen-Anhalt (LVermGeo, dl-de/by-2-0) and Bodenrichtwerte Berlin (Senatsverwaltung für Stadtentwicklung, Bauen und Wohnen, dl-de/zero-2-0). Attribution is required when you republish the data. Please respect the data provider's terms and cite the original resource in publications.
This actor is an independent tool and is not affiliated with or endorsed by the data provider.

# Actor input Schema

## `level` (type: `string`):

'district' = all German Kreise and kreisfreie Städte; 'municipality' and 'postalCode' = North Rhine-Westphalia only (needs Bodenrichtwerte).

## `states` (type: `array`):

Names, codes or abbreviations, e.g. Bayern, BY, 09. Empty = all (NRW for municipality / postal code).

## `regions` (type: `array`):

Optional filter: part of a name (e.g. Düsseldorf) or a key prefix (district/municipality code, postal code prefix such as 402).

## `indexIncludesLandValue` (type: `boolean`):

Off (default): index from income, SGB-II and unemployment, comparable across all of Germany. On: adds land values, which exist for NRW, Niedersachsen, Sachsen-Anhalt and Berlin only, so scores of these states and of the other states are not comparable. Municipality and postal-code levels always use land values.

## `includeRent` (type: `boolean`):

Adds the average net cold rent per m² of rented dwellings (Zensus 2022, 1 km grid aggregated to districts, dwelling-weighted) as extra columns for all of Germany. Needs one extra ~11 MB download; if it is unavailable the rent columns are null.

## `indexIncludesRent` (type: `boolean`):

Off (default): index unchanged. On: adds district rent as a component (weight 20 %, higher rent = wealthier). Rent exists for all of Germany, so scores stay comparable. The rent grid is downloaded even if 'Include Zensus rent' is off; the run fails with a clear message if it is unavailable.

## `heatmap` (type: `boolean`):

Stores a self-contained HTML heatmap in the key-value store (key HEATMAP): colored districts, or colored dots per municipality / postal code in NRW. Also stores PLZ_TIERS (regions grouped into five tiers; per postal area for postal codes).

## `maxResults` (type: `integer`):

Upper limit of returned rows (cost control).

## Actor input object example

```json
{
  "level": "district",
  "states": [
    "NW"
  ],
  "indexIncludesLandValue": false,
  "includeRent": true,
  "indexIncludesRent": false,
  "heatmap": true,
  "maxResults": 500
}
```

# Actor output Schema

## `results` (type: `string`):

No description

## `heatmap` (type: `string`):

No description

## `plz_tiers` (type: `string`):

No description

# 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 = {
    "states": [
        "NW"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("researchdata/german-wealth-barometer").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 = { "states": ["NW"] }

# Run the Actor and wait for it to finish
run = client.actor("researchdata/german-wealth-barometer").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 '{
  "states": [
    "NW"
  ]
}' |
apify call researchdata/german-wealth-barometer --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,researchdata/german-wealth-barometer"
        }
    }
}
```

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/LKQhHq1RUxS3RuCRW/builds/b6IxQT0WDmng2f452/openapi.json
