# Immowelt Scraper: Germany Rent & Property Prices Report (`precious_bathmat/germany-housing-market`) Actor

Scrape Immowelt.de flats and houses for rent or sale across a whole German city: cold rent or price, €/m², m², rooms, district, energy class, days listed. Plus a market report with exact listing counts by district. No login.

- **URL**: https://apify.com/precious_bathmat/germany-housing-market.md
- **Developed by:** [Mariam Ahmed](https://apify.com/precious_bathmat) (community)
- **Categories:** Real estate, Business
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $1.00 / 1,000 listings

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

## Immowelt Scraper: Germany Rent & Property Prices Report

Scrape **Immowelt.de**, one of Germany's biggest property portals, with no login and no API key, and get a **rent or price report for every German city**:

- **Every listing**: cold rent (Kaltmiete) or purchase price, total rent with service charges, **€/m²**, living space, plot, rooms, floor, **energy class**, district, postcode, street (agency listings), days listed, last update, new build, brokerage fee, agency, photos, link
- **A whole city, not just the first page**: Immowelt shows only 30-40 listings per search page; this Actor reads the city's district and room-count pages and gathers **hundreds to thousands of listings per city**
- **Immowelt's own counts for the whole city**: listings by district and by room count, straight from Immowelt
- **Flats or houses, to rent or for sale**, in any German town or city ("Berlin", "München", "Köln", "Frankfurt am Main")
- **Market report per city**: median rent or price and €/m² with the middle half, by rooms, district and postcode, total rent, days listed, brokerage-fee-free share, energy classes, **best-value homes** (under 80% of their district's €/m²), top agencies

### What does this Immowelt scraper do?

```
Immowelt · Berlin · flats to rent · 6,028 listings
 Median cold rent €1,519 (€1,100 – €2,117) · €21.35/m² · 75 m²
 Median total rent €1,871
 Most listings: Mitte 996 · Friedrichshain-Kreuzberg 896 · Pankow 863
 89 best-value flats under 80% of their district's €/m²
```

1. Enter **German towns or cities**.
2. Pick **to rent or for sale** and **flats or houses**.
3. You get **one row per listing** and **one market report per city**.

```mermaid
flowchart LR
    A[German cities] --> C[Immowelt city page]
    C --> D[District and<br/>room-count pages]
    D --> E[Listings<br/>rent or price,<br/>€/m², district]
    E --> F[Market report<br/>€/m² by district,<br/>counts, best value]
```

### Who is it for?

- **Landlords and investors**: rents and prices per m² by district and size, and homes priced under their district
- **Tenants and buyers**: a fair rent or price for each district before you apply
- **Agencies and property managers**: supply and pricing in each district, and who lists the most
- **Proptech, banks and valuers**: fresh asking rents and prices for any German city, with energy classes
- **Analysts and journalists**: rent levels across German cities and districts

### What data do you get?

**Listings** (dataset, one row per listing)

| Field | What it tells you |
|---|---|
| `id`, `url`, `title`, `operation`, `propertyType` | The listing |
| `price`, `priceType`, `totalRent`, `pricePerSqm` | Cold rent per month or purchase price, total rent with service charges, €/m² |
| `livingSpaceSqm`, `plotSqm`, `rooms`, `floor`, `energyClass` | The home |
| `city`, `zipCode`, `district`, `street` | Where (street only for agency listings that publish it) |
| `firstListed`, `daysListed`, `lastUpdated`, `isNew` | Time on market and new builds |
| `noBrokerageFee`, `sellerType`, `agency`, `agencyWebsite` | Fees and who lists it |
| `hasFloorPlan`, `hasVirtualTour`, `photos` | Media |
| `vsAreaPercent`, `comparedWith`, `areaMedianPricePerSqm`, `bestValue` | €/m² against the district median |
| `description` | With **Descriptions** on |

**Report** (`REPORTS`, one per city)

| Field | What it tells you |
|---|---|
| `totalListings`, `listingsRead` | Immowelt's count for the city, and how many were read |
| `listingsByDistrict`, `listingsByRooms` | Immowelt's own counts for the whole city |
| `medianPrice`, `price25`, `price75`, `medianPricePerSqm`, `pricePerSqm25`, `pricePerSqm75`, `medianLivingSpaceSqm`, `medianTotalRent` | Rents or prices |
| `byRooms`, `byDistrict`, `byZipCode` | Median rent or price and €/m² by group |
| `medianDaysListed`, `listedOver90DaysPercent`, `newBuildPercent`, `noBrokerageFeePercent`, `privateSellerPercent`, `energyClasses` | The market's make-up |
| `bestValue`, `bestValueCount`, `topAgencies` | Best-value homes and the busiest agencies |

### Example: 4 October 2026

Four cities, flats to rent, 400 listings each: **1,600 listings and 4 reports in 2 minutes 38 seconds**.

| City | Flats to rent | Median cold rent (middle half) | €/m² | Median total rent | Biggest district |
|---|---|---|---|---|---|
| Berlin | 6,028 | €1,519 (€1,100 – €2,117) | 21.35 | €1,871 | Mitte (996) |
| Hamburg | 3,215 | €1,250 (€825 – €1,855) | 17.35 | €1,795 | Nord (960) |
| Köln | 2,160 | €1,036 (€760 – €1,400) | 16.00 | €1,500 | Innenstadt (708) |
| Leipzig | 1,642 | €748 (€567 – €1,111) | 12.10 | €975 | Ost (359) |

### Pricing

**$0.001 per listing** and **$0.02 per report**.

- 600 listings for one city with a report: **$0.62**
- The run above (1,600 listings, 4 reports): **$1.68**

Turn off reports to pay for listings only.

### Good to know

- **Coverage**: Immowelt shows only the first 30-40 listings of each search page. The Actor reads the city page, then its district, sub-district and room-count pages, and skips repeats. It stops when it has the number you asked for, has every listing of the city, or finds nothing new. Big cities give thousands of listings; `listingsByDistrict` and `listingsByRooms` always cover the whole city.
- **Rents**: `price` is the cold rent (Kaltmiete) per month; `totalRent` includes service charges where Immowelt gives it.
- **Best value** = €/m² under 80% of the median of the same district (or the whole city) with at least 5 listings to compare.
- **Cities** work by their German name, with or without umlauts ("München", "Muenchen", "Köln", "Frankfurt am Main"). Unknown names are skipped and listed in `RUN_SUMMARY`.
- **Privacy**: contact persons and private sellers are not named, and private sellers' street addresses are not given; agencies are named. Emails, phone numbers and named contacts in descriptions are hidden.
- Data comes from **Immowelt.de's public search pages**. **Not affiliated with Immowelt or AVIV Group.**

### Input

| Field | Meaning |
|---|---|
| **Cities** | German towns or cities |
| **To rent or for sale** | Mieten or kaufen |
| **Property type** | Flats or houses |
| **Listings per city** | 1 to 10,000 (default 600) |
| **Descriptions** | Add the description |
| **Reports** | On by default |

### Integrations

Export to JSON, CSV, Excel or Google Sheets, or connect through the Apify API, webhooks, Make, Zapier and n8n. **Schedule it weekly** to track rents in your cities.

# Actor input Schema

## `cities` (type: `array`):

German towns or cities, e.g. "Berlin", "München", "Hamburg", "Köln", "Frankfurt am Main", "Leipzig". One report each.

## `operation` (type: `string`):

Homes to rent or for sale. Rents are cold rent (Kaltmiete) per month.

## `propertyType` (type: `string`):

Flats or houses.

## `maxListingsPerCity` (type: `integer`):

Most listings to read per city. Immowelt shows 30-40 per page, so the Actor reads district and room-count pages to reach this.

## `includeDescriptions` (type: `boolean`):

Add each listing's description (contact details and names hidden).

## `includeReports` (type: `boolean`):

One market report per city: Immowelt's own listing counts by district and room count, median rent or price and €/m², by rooms, district and postcode, days listed, brokerage-fee-free share, energy classes, best-value homes, top agencies.

## Actor input object example

```json
{
  "cities": [
    "Berlin"
  ],
  "operation": "rent",
  "propertyType": "flat",
  "maxListingsPerCity": 600,
  "includeDescriptions": false,
  "includeReports": true
}
```

# Actor output Schema

## `listings` (type: `string`):

One row per listing: cold rent or price, total rent, €/m², m², rooms, floor, energy class, district, postcode, days listed, agency, link.

## `reports` (type: `string`):

Per city: listing counts by district and rooms, median rent or price and €/m², by rooms, district and postcode, days listed, best-value homes, agencies.

## `reportsCsv` (type: `string`):

One flat row per city.

## `summary` (type: `string`):

Requests, problems and the limits of the data.

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

// Run the Actor and wait for it to finish
const run = await client.actor("precious_bathmat/germany-housing-market").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 = { "cities": ["Berlin"] }

# Run the Actor and wait for it to finish
run = client.actor("precious_bathmat/germany-housing-market").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 '{
  "cities": [
    "Berlin"
  ]
}' |
apify call precious_bathmat/germany-housing-market --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,precious_bathmat/germany-housing-market"
        }
    }
}
```

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/bVrSIeVaaMCaZptVo/builds/I84pMyeNAbHLPex59/openapi.json
