# ImmoScout24 Scraper (`lergassy/immoscout24-scraper`) Actor

Scrape ImmoScout24 listings for any German city, district or postcode: rent or price, €/m², living space, rooms, address with coordinates, energy class, photos, realtor and phone. Filter by price, rooms and size. Export JSON or CSV, call it via API, schedule it, or use n8n, Make and Zapier.

- **URL**: https://apify.com/lergassy/immoscout24-scraper.md
- **Developed by:** [Matvey](https://apify.com/lergassy) (community)
- **Categories:** Real estate, Lead generation
- **Stats:** 5 total users, 3 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $0.80 / 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.
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

**ImmoScout24 Scraper** collects listings from ImmoScout24 (immobilienscout24.de), Germany's largest property portal, for any city, district or postcode: **apartments and houses to rent or buy, WG rooms, furnished flats, building plots, garages, offices, investment properties and foreclosure auctions**. Every listing comes back as one clean row: price as a number, price per m², living space, rooms, full address with postcode and district, coordinates, energy class, photo and how long it has been online. By default each row also gets cold and warm rent, ancillary and heating costs, deposit, commission, floor, year built, condition, heating and energy data, balcony / garden / lift / kitchen flags, bedrooms, bathrooms, all photos, the full description texts and the realtor — **all included in the listing price** — plus, on request, the realtor's phone number.

It reads ImmoScout24's own app data, so there is **no browser, no login, no cookies and no proxy**: 300 fully detailed Munich listings take about 12 seconds. Export JSON, CSV or Excel, call it from the API, schedule it, or use it from n8n, Make, Zapier, Google Sheets or an AI agent through MCP.

### What is ImmoScout24 Scraper?

A pay-per-result tool for anyone who needs German real-estate listings as data instead of web pages: investors comparing rents and prices per m², agencies watching new listings, relocation and proptech teams, researchers and AI agents. You type a place (`Berlin`, `München`, `Hamburg - Eimsbüttel`, `10115`, or `Germany` for the whole country) or paste an ImmoScout24 search URL, pick the property type and filters, and get a table. Filters (price, rooms, living space) are applied by ImmoScout24 itself, so every row already matches.

### What data can ImmoScout24 Scraper extract?

| Field | Example from a real run (Berlin, 22 October 2026) |
|---|---|
| `title`, `url`, `id` | Wohnen mit Herz – wie geschaffen für zwei mit WBS 140 · link · 170975305 |
| `price`, `priceKind`, `priceText`, `currency` | 363 · baseRent (cold rent) · "363 €" · EUR |
| `pricePerSqm` | 6.98 |
| `livingSpace`, `rooms` | 52 · 2 |
| `address`, `street`, `postalCode`, `city`, `district`, `addressComplete` | Hellersdorfer Straße 87 · 12619 · Berlin · Kaulsdorf (Hellersdorf) · true |
| `latitude`, `longitude` | 52.52485 · 13.58695 (when the advertiser makes the exact address public) |
| `energyEfficiencyClass` | B |
| `isPrivateOffer` | false (true = private landlord or seller) |
| `publishedAgo`, `publishedDaysAgo` | "vor einem Monat" · 30 |
| `imageUrl`, `realtorLogoUrl` | main photo, realtor logo |
| `plusEarlyAccess`, `plusEarlyAccessUntil` | listing still in ImmoScout24's paid early-access window |
| `plotArea`, `usableArea`, `availableFrom`, `marketValue`, `lowestBid` | for houses, plots, offices, WG rooms and foreclosure auctions |
| `position`, `searchQuery`, `searchTotalResults` | rank in the results, your input, how many listings the search has |

**Listing details** (`includeDetails`, on by default, no extra charge): `baseRent`, `totalRent`, `serviceCharge`, `heatingCosts`, `purchasePrice`, `deposit`, `commission`, `brokerFee`, `floor`, `numberOfFloors`, `bedrooms`, `bathrooms`, `yearConstructed`, `condition`, `interiorQuality`, `heatingType`, `energySources`, `energyConsumption`, `energyCertificateType`, `newBuilding`, `hasBalcony`, `hasGarden`, `hasCellar`, `hasLift`, `hasBuiltInKitchen`, `isBarrierFree`, `petsAllowed`, `furnished`, `parkingType`, `parkingSpaces`, `apartmentType`, `houseType`, `state`, `quarter`, `objectNumber`, `priceRating`, `description`, `furnishingDescription`, `locationDescription`, `otherDescription`, `images`, `imageCount`, `realtorName`, `realtorCompany`, `realtorRating`, `realtorReviewCount`, `realtorProfileUrl`, `realtorAddress`, and `criteria` — every labelled fact of the listing page as label → value.

**With Realtor phone** (`includeRealtorPhone`): `realtorPhone` and `realtorPhones` — the numbers a professional realtor shows on the listing. Never filled for private landlords or sellers.

### How much does it cost to scrape ImmoScout24?

Pay per result. **No start fee, no subscription.** Error rows, "no results" rows and the run summary row are always free.

| Event | Price (Apify Free plan) | Per 1,000 |
|---|---|---|
| **Listing** (search data + full listing details) | $0.001225 | **$1.23** |
| Add-on: Realtor phone (only listings that have a phone) | $0.0035 | $3.50 |

**$1 buys about 816 fully detailed listings** — details are not an extra charge. The $5 monthly credit of the Apify Free plan covers about 4,000 listings. Paid Apify plans pay less per listing (down to $0.80 per 1,000). Platform usage on top is tiny because there is no browser and no proxy: a 300-listing run with details used $0.0015 of compute.

Set **Max listings** and the run never delivers more than that. Set **Max cost per run** in the run options and the run stops by itself, green, when the budget is used up — everything written is paid for, nothing beyond it.

### How to scrape ImmoScout24 listings

1. Click **Try for free** (a free Apify account is enough).
2. Type one or more places into **Locations**: a city, a district, a postcode or `Germany`. Or paste ImmoScout24 search URLs into **ImmoScout24 search or listing URLs**.
3. Pick the **Property type** (apartment for rent is the default) and, if you want, a price, rooms or living-space range.
4. Set **Max listings** (50 by default) and click **Start**.
5. Open the **Output** tab and download the table, or read the dataset through the API.

Leave everything empty and the Actor runs a demo search for Berlin apartments to rent.

### ⬇️ Input

Two- to three-room apartments in Hamburg up to €1,500 cold rent, newest first:

```json
{
  "locations": ["Hamburg"],
  "propertyType": "apartmentrent",
  "priceMax": 1500,
  "roomsMin": 2,
  "roomsMax": 3,
  "sortBy": "newest",
  "maxItems": 200
}
```

A search URL from your browser keeps its own place, type and filters, a radius search included:

```json
{
  "startUrls": [
    { "url": "https://www.immobilienscout24.de/Suche/de/berlin/berlin/wohnung-mieten?price=-1000.0&numberofrooms=2.0-" },
    { "url": "https://www.immobilienscout24.de/Suche/radius/wohnung-kaufen?centerofsearchaddress=Berlin;;;;;&geocoordinates=52.51051;13.43068;3.0" },
    { "url": "https://www.immobilienscout24.de/expose/172000652" }
  ],
  "maxItems": 100
}
```

Property types: `apartmentrent`, `apartmentbuy`, `houserent`, `housebuy`, `flatshareroom` (WG-Zimmer), `shorttermaccommodation` (furnished / Wohnen auf Zeit), `livingbuysite` (building plots), `garagerent`, `garagebuy`, `office`, `investment`, `compulsoryauction` (Zwangsversteigerung). `priceType: "total"` filters apartments and houses for rent by warm rent instead of cold rent. `language: "en"` returns ImmoScout24's English translation of titles.

### ⬆️ Output

A real row with `includeDetails` switched off (Berlin, 22 October 2026) — the fields every row has:

```json
{
  "type": "listing",
  "id": "170975305",
  "url": "https://www.immobilienscout24.de/expose/170975305",
  "title": "Wohnen mit Herz – wie geschaffen für zwei mit WBS 140",
  "propertyType": "apartmentrent",
  "price": 363,
  "priceKind": "baseRent",
  "priceText": "363 €",
  "livingSpace": 52,
  "rooms": 2,
  "currency": "EUR",
  "pricePerSqm": 6.98,
  "address": "Hellersdorfer Straße 87, 12619 Berlin, Kaulsdorf (Hellersdorf)",
  "addressComplete": true,
  "street": "Hellersdorfer Straße 87",
  "postalCode": "12619",
  "city": "Berlin",
  "district": "Kaulsdorf (Hellersdorf)",
  "latitude": 52.52485,
  "longitude": 13.58695,
  "energyEfficiencyClass": "B",
  "isPrivateOffer": false,
  "publishedAgo": "vor einem Monat",
  "publishedDaysAgo": 30,
  "imageUrl": "https://pictures.immobilienscout24.de/listings/e82a1d4d-05d4-44b1-b74b-c882ec19d573-2104823015.png/ORIG/resize/1500x1000>/format/webp/quality/80",
  "position": 3,
  "searchQuery": "Berlin",
  "searchTotalResults": 4467,
  "scrapedAt": "2026-10-22T14:34:52.043Z"
}
```

With Listing details (the default) and **Realtor phone** on, a Munich row also carries (shortened):

```json
{
  "baseRent": 1525, "totalRent": 1745, "serviceCharge": 220,
  "floor": 1, "yearConstructed": 2026, "condition": "first_time_use", "interiorQuality": "sophisticated",
  "energySources": "pellet_heating", "newBuilding": true,
  "hasBalcony": true, "hasCellar": true, "hasLift": true, "hasBuiltInKitchen": true, "isBarrierFree": true,
  "petsAllowed": "no", "apartmentType": "Etagenwohnung", "bedrooms": 1, "bathrooms": 1,
  "availableFrom": "2026-11-01", "state": "Bayern", "quarter": "Altaubing",
  "description": "Komfortabel geplant, großzügig geschnitten und ruhig im Münchner Westen gelegen. …",
  "images": ["https://pictures.immobilienscout24.de/listings/…jpg/ORIG/resize/1500x1000/format/webp/quality/80"],
  "imageCount": 11,
  "realtorName": "K+S Verkaufsberatung vor Ort",
  "realtorCompany": "Krieger + Schramm GmbH & Co. KG",
  "realtorAddress": "Industriestraße 34, 81245 München",
  "realtorPhone": "+49 89 232387180"
}
```

Rows with `type: "error"` explain a problem with one input (unknown place, wrong URL, a search with no results) and are free; a free `type: "notice"` row at the end sums up what was delivered and charged.

### Use cases

#### Real-estate investors

Pull every apartment for sale in a city with price, m², price per m², year built, condition and energy class, and rank by yield against the rents of the same district.

#### Agencies and property managers

Track new listings in your area daily, see which realtors are active where, and benchmark your own asking rents against the market.

#### Relocation services and tenants' platforms

Feed fresh rentals with photos, warm rent, deposit and availability date into your own search or alerts.

#### Proptech, analysts and researchers

Build rent and price indices by postcode, follow supply over time, and study energy classes of the German housing stock.

#### Lead generation

Collect realtor companies, contact names, office addresses and business phone numbers from the listings in a region.

#### AI agents and RAG

An agent can call the Actor with a plain place name and get structured JSON back: every field is described in the dataset schema, the input needs no URL, and runs finish in seconds.

### Integrations

- **API** — `POST https://api.apify.com/v2/acts/lergassy~immoscout24-scraper/run-sync-get-dataset-items?token=…` with the input JSON returns the rows directly.
- **Python / JavaScript** — `apify-client`: `client.actor("lergassy/immoscout24-scraper").call(run_input={"locations": ["Berlin"]})`, then read `client.dataset(run["defaultDatasetId"]).list_items()`.
- **n8n, Make, Zapier** — use the Apify app or node, pick this Actor and map the dataset items.
- **Google Sheets** — the Apify Google Sheets integration or the CSV export link.
- **Schedules and webhooks** — run the same input every morning; a webhook on `ACTOR.RUN.SUCCEEDED` posts the dataset link to your system.
- **MCP** — connect the Apify MCP server to Claude, Cursor or any MCP client and ask for ImmoScout24 listings in plain language.

#### Only new listings, every day

Put a name into **Only new listings — memory name** (for example `berlin-watch`), set **Sort by** to *Newest first* and schedule the run. Every run remembers the listings it delivered under that name and writes — and charges — only listings you have not received before.

### Migrating from another ImmoScout24 scraper?

| You used | Here |
|---|---|
| `startUrls` / `startUrl` with a search URL | `startUrls` (same URL works, filters included) |
| `searchLocation` / `location` | `locations` (a list, several places in one run) |
| `searchOperation` + `searchPropertyType` / `operation` + `propertyType` | `propertyType` (e.g. `apartmentrent`, `housebuy`) |
| `searchMinPrice` / `minPrice`, `searchMaxPrice` / `maxPrice` | `priceMin`, `priceMax` |
| `searchMinRooms` / `minRooms`, `searchMaxRooms` / `maxRooms` | `roomsMin`, `roomsMax` |
| `searchMinLivingSpace` / `minLivingSpace` … | `livingSpaceMin`, `livingSpaceMax` |
| `maxItems` / `pageLimit` | `maxItems` |
| `fetchDetails` | `includeDetails` |
| `monitoringMode` / `monitorMode` | `onlyNewRowsStore` (any name you choose) |
| `properties` (listing IDs) | `startUrls` with `https://www.immobilienscout24.de/expose/<id>` |

### Troubleshooting

- **"ImmoScout24 does not know the place"** — write the place the way ImmoScout24's search box suggests it (districts as `Hamburg - Eimsbüttel` or `Berlin Kreuzberg`), or paste the search URL from the site. The status message of every run shows which ImmoScout24 place each of your inputs was matched to (`Munich` → München, `Frankfurt` → Frankfurt am Main).
- **A filter was ignored** — some property types have no such filter on ImmoScout24 (garages have no rooms). The status message says which filter was not applied.
- **Fewer rows than Max listings** — the search simply has fewer listings; `searchTotalResults` shows how many exist.
- **No street or coordinates** — the advertiser hides the exact address (`addressComplete: false`); postcode and district are still given.
- **The price looks like cold rent although I filtered by warm rent** — ImmoScout24's result list always shows cold rent. Keep Listing details on (the default) to get `totalRent`.
- **Shape searches** (an area drawn on the map) are not supported; use a city, district or radius URL.

### ❓ FAQ

#### Is it legal to scrape ImmoScout24?

The Actor collects only what ImmoScout24 shows publicly to any visitor, without logging in. Whether and how you may use the data depends on your purpose and on the laws that apply to you, including the GDPR for personal data and database rights. Private landlords' names and phone numbers are never returned. If you are unsure, ask a lawyer.

#### Do I need an ImmoScout24 account, API key or proxy?

No. The Actor needs none of these.

#### How many listings can I get?

Everything a search has: ImmoScout24 lists about 4,500 apartments for rent in Berlin and over 80,000 in Germany. Set Max listings up to 100,000.

#### How fresh is the data?

Live: every run asks ImmoScout24 at that moment. `publishedAgo` shows how long a listing has been online.

#### Do listing details cost extra?

No. Description texts, all photos, costs, building and energy data and the realtor are included in the listing price and switched on by default. Switch `includeDetails` off only if you want the fastest possible search-level rows — the price stays the same.

#### Can I get the realtor's phone number?

Yes, with Realtor phone on, for listings where a professional realtor shows a number (about one in five in Munich in our tests). You pay only for listings that have one.

#### Does it work for Austria or Switzerland?

Not yet — German listings only.

### Your feedback

Missing a field, a filter or a property type? Open an issue on the **Issues** tab — every report gets an answer, and most fixes ship within days.

### You might also like

| Actor | What it does |
|---|---|
| [Zillow Scraper](https://apify.com/lergassy/zillow-scraper) | US homes for sale, rent and recently sold, with Zestimate and agent phone |
| [Airbnb Listings Scraper](https://apify.com/lergassy/airbnb-listings-scraper) | Short-term rentals with nightly prices for the same cities |
| [Booking Hotels Scraper](https://apify.com/lergassy/booking-hotels-scraper) | Hotels, prices and ratings from Booking.com |

# Actor input Schema

## `locations` (type: `array`):

Give this or <code>startUrls</code>. One place per line, in Germany: a city (<code>Berlin</code>, <code>München</code>), a district (<code>Hamburg - Eimsbüttel</code>, <code>Berlin Kreuzberg</code>), a postcode (<code>10115</code>) or <code>Germany</code> for the whole country. Each place is looked up in ImmoScout24's own place search and searched with the property type and filters below. Empty together with startUrls = a demo search for Berlin.

## `startUrls` (type: `array`):

Give this or <code>locations</code>. Paste search result URLs from immobilienscout24.de exactly as your browser shows them, e.g. <code>https://www.immobilienscout24.de/Suche/de/berlin/berlin/wohnung-mieten?price=-1000.0</code>. The URL keeps its own place, property type and filters (price, rooms, living space, radius, sort order). Single listing URLs (<code>…/expose/123456789</code>) work too.

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

What to search for in Locations. Search URLs carry their own type and ignore this field.

## `priceMin` (type: `integer`):

Lowest price in euros: monthly rent for rentals, purchase price for sales. Empty = no lower limit.

## `priceMax` (type: `integer`):

Highest price in euros: monthly rent for rentals, purchase price for sales. Empty = no upper limit.

## `priceType` (type: `string`):

For apartments and houses to rent: whether the price range and the <code>price</code> column mean cold rent (Kaltmiete, ImmoScout24's default) or total rent (Warmmiete). Ignored for sales.

## `roomsMin` (type: `number`):

Minimum number of rooms, as counted in Germany (living room + bedrooms, kitchen and bath not counted). 1.5 and 2.5 are valid.

## `roomsMax` (type: `number`):

Maximum number of rooms.

## `livingSpaceMin` (type: `integer`):

Minimum living space in square metres (room size for WG rooms).

## `livingSpaceMax` (type: `integer`):

Maximum living space in square metres.

## `sortBy` (type: `string`):

Order of results. With a small Max listings this decides which listings you get — use Newest first for a daily feed.

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

Maximum listings for the whole run, shared evenly between your locations and URLs (a place with fewer listings leaves its share to the next). Berlin apartments for rent are about 4,500 listings; all of Germany is over 80,000.

## `includeDetails` (type: `boolean`):

On by default and included in the listing price: opens every listing page and adds full description texts, all photos, cold and warm rent, ancillary and heating costs, deposit, buyer commission, floor, year built, condition, heating and energy data, balcony / garden / lift / kitchen / cellar flags, bedrooms, bathrooms, realtor name, company, rating and address. Switch off only for the fastest search-level rows.

## `includeRealtorPhone` (type: `boolean`):

Add the phone numbers a professional realtor shows on the listing page (<code>realtorPhone</code>, <code>realtorPhones</code>) plus realtor name and company. Charged as "Add-on: Realtor phone" only for listings that really have a phone number. Never filled for private landlords or sellers.

## `language` (type: `string`):

<code>de</code> returns titles as the advertiser wrote them. <code>en</code> returns ImmoScout24's English translation of titles and labels. Description texts stay in the original language either way.

## `onlyNewRowsStore` (type: `string`):

Give this run a name — <code>my-berlin-watch</code> — and the Actor remembers every listing it delivered under that name. Every later run with the same name writes and charges <b>only listings you have not received before</b>. Schedule it daily with Sort by = Newest first to get a feed of new listings. Leave empty to get everything found, every time.

## `includeRunSummary` (type: `boolean`):

One extra free row at the end with the run's totals: rows delivered, free rows, what was charged and how much in US dollars. It carries type "notice", so a filter on the data rows skips it. Switch off if your pipeline cannot tolerate an extra row.

## Actor input object example

```json
{
  "locations": [
    "Berlin"
  ],
  "propertyType": "apartmentrent",
  "priceType": "base",
  "sortBy": "relevance",
  "maxItems": 50,
  "includeDetails": true,
  "includeRealtorPhone": false,
  "language": "de",
  "includeRunSummary": true
}
```

# Actor output Schema

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

One row per ImmoScout24 listing: price, price per m², living space, rooms, address, coordinates, energy class, photos, costs, building and energy data, description texts and realtor; realtor phone with the add-on.

## `runSummary` (type: `string`):

JSON counters for the run: searches, listings delivered, listing pages opened, duplicates and already-delivered listings skipped, errors, requests.

# 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 = {
    "locations": [
        "Berlin"
    ],
    "maxItems": 50
};

// Run the Actor and wait for it to finish
const run = await client.actor("lergassy/immoscout24-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 = {
    "locations": ["Berlin"],
    "maxItems": 50,
}

# Run the Actor and wait for it to finish
run = client.actor("lergassy/immoscout24-scraper").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 '{
  "locations": [
    "Berlin"
  ],
  "maxItems": 50
}' |
apify call lergassy/immoscout24-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,lergassy/immoscout24-scraper"
        }
    }
}
```

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/lbGwSAX8DAauiqFjE/builds/TZMdS1CIL6n2CItYV/openapi.json
