# ImmobilienScout24 Scraper - Germany Real Estate (`scrapesage/immobilienscout24-scraper`) Actor

Scrape Germany property listings from immobilienscout24.de search URLs: price, price per m2, rooms, living space, full address, energy class, agent and contact phone, images and 50+ fields. Sale and rental, apartments and houses. Bypasses anti-bot protection. Paste search URLs or import a file.

- **URL**: https://apify.com/scrapesage/immobilienscout24-scraper.md
- **Developed by:** [Scrape Sage](https://apify.com/scrapesage) (community)
- **Categories:** Real estate, Integrations, Agents
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $1.65 / 1,000 listing scrapeds

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?

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

## ImmobilienScout24 Scraper - Germany Real Estate Listings

> **Disclaimer:** This Actor is an independent tool and is not affiliated with, endorsed by, or sponsored by Immobilien Scout GmbH or any of its subsidiaries. All trademarks mentioned are the property of their respective owners. "ImmobilienScout24" is referenced only to describe the publicly available website this Actor collects data from.

> This Actor is an independent tool and is not affiliated with, endorsed by, or sponsored by ImmobilienScout24,
> ImmoScout24 or Scout24 SE. All trademarks mentioned are the property of their respective owners.

Scrape property listings from **immobilienscout24.de**, Germany's largest real-estate portal, straight into
**JSON, CSV or Excel**. Paste any immobilienscout24.de search URL - **buy** (`wohnung-kaufen`, `haus-kaufen`) or
**rent** (`wohnung-mieten`, `haus-mieten`), any city, district or radius - and get clean rows with **price**,
**price per m2**, **rooms**, **living space**, **full address with coordinates**, **energy class**, **amenity
flags** (balcony, lift, cellar, built-in kitchen...), **agent company** and - where the lister publishes it -
a **direct contact name and phone number**.

ImmoScout24 sits behind enterprise anti-bot protection (AWS WAF) that answers ordinary HTTP scrapers with a 401.
This actor **handles that for you**: no proxy setup, no browser fingerprinting, no captcha service, and **no API
key on your side**. You paste a search URL and get rows.

### What you get per listing - 50+ fields

| Field | Type | Meaning |
|---|---|---|
| `id` / `url` | string | ImmoScout24 listing id and canonical `immobilienscout24.de/expose/<id>` link |
| `title` | string | Listing headline |
| `propertyType` | string | Typed by the source: `ApartmentBuy`, `ApartmentRent`, `HouseBuy`, `HouseRent`... |
| `marketingType` | string | `PURCHASE` or `RENT` |
| `price` | number | Asking price (sale) or base rent (rentals) |
| `pricePerSqm` | number | Price divided by living space, computed for you |
| `totalRent` | number | Total rent incl. service costs, on rental listings that publish it |
| `livingSpaceSqm` / `plotAreaSqm` / `rooms` | number | Living space, plot area (houses), rooms |
| `street`, `houseNumber`, `postcode`, `city`, `quarter`, `fullAddress` | string | Full address, down to house number where the lister publishes it |
| `latitude` / `longitude` | number | WGS84 coordinates for mapping |
| `energyEfficiencyClass` | string | `A+`...`H` where the listing carries a certificate |
| `constructionYear` | number | Year built |
| `builtInKitchen`, `balcony`, `garden`, `lift`, `guestToilet`, `cellar`, `barrierFree` | boolean | True amenity booleans - a real `false` stays `false` |
| `commissionFree` | boolean | `true` when the listing is provisionsfrei for the buyer |
| `privateOffer` | boolean | Private seller vs professional agent |
| `agentCompany`, `contactName`, `contactPhone` | string | Listing company plus the contact person and phone the lister publishes on the card |
| `tags` | array | Card badges, e.g. *"Provisionsfrei für Kaufende"*, *"Balkon/Terrasse"* |
| `images` / `image` | array / string | Up to 10 photo URLs (800x600), floorplans excluded |
| `hasFloorplan`, `hasVideo` | boolean | Media flags |
| `listingTier` | string | ImmoScout24's own placement tier (`S`/`M`/`L`/`XL`/`XXL`) - premium listings identified |
| `isNewBuildProject`, `projectName`, `projectUrl` | - | New-build project info when the unit belongs to one |
| `publishedAt` / `modifiedAt` | string | Source timestamps - spot fresh supply and price edits |
| `attributes` | object | The card's own formatted attribute set, verbatim (per-type extras like plot area) |
| `type`, `sourceUrl`, `scrapedAt` | - | Record type (`listing`), originating search URL, fetch timestamp |

**Field coverage, measured on real unlocked Berlin pages (40 listings):** `price`, `livingSpaceSqm`, `rooms`,
`pricePerSqm`, `postcode`, `city`, `quarter`, all seven amenity booleans, `agentCompany`, `contactName`, `images`
were present on **40 of 40**. `contactPhone` on **36 of 40 (90%)**. `street`/`houseNumber`/coordinates on **78%**

- ImmoScout24 only shows the exact address when the lister opts in. `constructionYear` **80%**.
  `energyEfficiencyClass` **45%** - listings without a published certificate genuinely do not carry it.
  `totalRent` and `plotAreaSqm` apply to rentals and houses respectively and are `null` on other segments.

### Example output

One real row, exactly as written to the dataset (truncated to the highlights):

```json
{
  "type": "listing",
  "id": "169863156",
  "url": "https://www.immobilienscout24.de/expose/169863156",
  "title": "Perfekt für Paare - mit Platz fürs Homeoffice",
  "propertyType": "ApartmentBuy",
  "marketingType": "PURCHASE",
  "price": 494000,
  "currency": "EUR",
  "pricePerSqm": 7347.91,
  "livingSpaceSqm": 67.23,
  "rooms": 2.5,
  "street": "Ella-Kay-Straße",
  "houseNumber": "24",
  "postcode": "10405",
  "city": "Berlin",
  "quarter": "Prenzlauer Berg (Prenzlauer Berg)",
  "latitude": 52.53964,
  "longitude": 13.43045,
  "energyEfficiencyClass": "A+",
  "constructionYear": 2027,
  "builtInKitchen": false,
  "balcony": true,
  "lift": true,
  "cellar": true,
  "barrierFree": true,
  "commissionFree": true,
  "privateOffer": false,
  "agentCompany": "Ella Living GmbH & Co. KG",
  "contactName": "Thomas Brinktriene",
  "contactPhone": "0172 1880284",
  "tags": ["Nur hier gefunden", "Provisionsfrei für Kaufende", "Balkon/Terrasse", "Keller", "Aufzug", "Stufenlos"],
  "image": "https://pictures.immobilienscout24.de/listings/78327a38-...jpg/ORIG/legacy_thumbnail/800x600/format/webp/quality/50",
  "sourceUrl": "https://www.immobilienscout24.de/Suche/de/berlin/berlin/wohnung-kaufen",
  "scrapedAt": "2026-08-26T18:04:21.007Z"
}
```

### Input

```json
{
  "startUrls": ["https://www.immobilienscout24.de/Suche/de/berlin/berlin/wohnung-kaufen"],
  "maxPagesPerUrl": 5,
  "maxItems": 1000
}
```

- **immobilienscout24.de search URLs** - build the search you want on immobilienscout24.de (city, price range,
  rooms, m2, any filter), then paste the URL from the address bar. One per line, as many as you want. Every filter
  is carried through, because the actor scrapes exactly the URL you gave it.
- **Import URLs from a file** - paste a whole list, or give a single link to a public `.txt`/`.csv`, a Google
  Sheet or Drive link, or an Apify key-value-store record. Blank lines and `#` comments are ignored. A file that
  cannot be read tells you so and charges nothing.
- **Max pages per URL** - 20 listings per page (default 10 pages).
- **Max listings** - overall cap across all URLs.
- **Output fields** - tick only the columns you want and every record is trimmed to exactly those, which keeps
  CSV and Google Sheets exports lean.

Leave everything empty and the run scrapes a small one-page sample search, so you can see the output shape before
committing to a real job.

### Which ImmoScout24 URLs work

| Search type | URL pattern | Status |
|---|---|---|
| Apartments for sale | `immobilienscout24.de/Suche/de/<state>/<city>/wohnung-kaufen` | Validated |
| Apartments for rent | `.../wohnung-mieten` | Same embedded data model |
| Houses for sale / rent | `.../haus-kaufen`, `.../haus-mieten` | Same embedded data model |
| Any filtered search | the same paths with ImmoScout24's filter query parameters | Carried through verbatim |

Pagination is automatic (`?pagenumber=2`, `?pagenumber=3`, ...) up to your page limit, and the actor stops early
on its own when the search's own result count is exhausted, so you never pay for a page of repeats. Rows are
de-duplicated by listing URL across every start URL in the run.

### Reliability

immobilienscout24.de is protected by enterprise anti-bot (AWS WAF) - plain scrapers get an HTTP 401 instead of
listings. This actor routes every request through a premium unblocking layer that clears the challenge and
returns the real page, then parses the site's own embedded result model (typed JSON, not brittle CSS selectors).

On top of that:

- **Short-render detection.** The unlocking layer occasionally returns a page whose listing area did not finish
  rendering. The actor reads each page's own result count and pagination block, refetches any page that falls
  short of what the search says it should hold (keeping the best of up to 3 fetches), and never mistakes a bad
  render for the end of the search. A page that stays short even after refetching is disclosed in the run's
  status message instead of being passed off as complete.
- **Wall-clock budget.** Long runs stop cleanly before the platform timeout, save everything collected up to that
  point, and say so in the run status instead of dying as TIMED-OUT.
- **Every ending explains itself.** A run that finds nothing tells you why - bad search URL, unreadable import
  file, or a fetch that failed - and bills **$0**.

### What people use it for

- **Comparables and valuations** - pull every apartment in a Bezirk with `pricePerSqm` already computed.
- **Rental yield analysis** - scrape the same area twice, once `-kaufen` and once `-mieten`, and divide.
- **Market monitoring** - schedule a daily run per city and track price movements, new supply (`publishedAt`) and
  price edits (`modifiedAt`).
- **Agent and lead intelligence** - `agentCompany`, `contactName` and `contactPhone` give you who is listing
  what, at what volume, in any German market - with a direct line where the lister publishes one.
- **Energy-renovation targeting** - filter `energyEfficiencyClass` F/G/H stock for retrofit and financing leads.
- **Mapping and territory analysis** - `latitude`/`longitude` on every precisely-addressed listing.
- **Feeding AI agents and data pipelines** - see the MCP section below.

### Honest limits

- **The exact street address and coordinates appear only when the lister opts in** (roughly 3 in 4 listings on
  our measured pages). `postcode`, `city` and `quarter` are always present.
- **`energyEfficiencyClass` exists only where the listing carries an energy certificate** - about half of stock
  in our measurement. That is the source's behaviour, not an extraction gap.
- **`totalRent` is a rental-segment field and `plotAreaSqm` a house-segment field** - they are `null` on other
  segments by design.
- **`contactPhone` is the number the lister prints on the results card.** Most professional listers publish one
  (90% measured); private listings may not.
- **A page can rarely still come back short.** A full results page holds 20 listings; the anti-bot layer
  sometimes serves a partial render. The actor detects that against the search's own count and refetches
  automatically; if a page stays short after all refetches, the run's status message says so rather than
  presenting the result as complete - and you are only billed for rows actually delivered.
- **Runs are a little slower than an unprotected site**, because every page goes through the unblocking layer.

### Pricing

**Pay per listing** - you are charged only for listings actually written to the dataset. A run that finds
nothing, or that cannot read your import file, costs **$0**. The rate covers the premium anti-bot unblocking that
makes ImmoScout24 scrapable at all, and it drops automatically on higher Apify plans (tiered pay-per-event
pricing).

### Output views

- **Listings** - a table of title, price, living m2, rooms, city, EUR/m2 and the listing URL, ready to eyeball or
  export to CSV, Excel, JSON or Google Sheets. The full record with every field is always in the dataset behind it.

### Use with AI assistants (MCP)

Available through the [Apify MCP server](https://docs.apify.com/platform/integrations/mcp), so an assistant or
agent can pull live Germany property listings past ImmoScout24's anti-bot in a single call - compare prices per
m2 across districts, watch a market for new supply, or enrich an address list without anyone touching a browser.

### Agent-ready: autonomous payments (x402 & Skyfire)

This actor is **agent-ready** — AI agents can discover it, run it, and **pay for it autonomously**, with no Apify account and no human in the loop. It uses [pay-per-event](https://docs.apify.com/platform/actors/publishing/monetize/pay-per-event) pricing and [limited permissions](https://docs.apify.com/platform/actors/development/permissions), so it qualifies for Apify's agentic-payment standards:

- **[x402](https://docs.apify.com/platform/integrations/x402)** — an open, HTTP-native payment protocol. Agents pay per run in USDC on the Base network directly through the [Apify MCP server](https://docs.apify.com/platform/integrations/mcp) — no account, no API key.
- **[Skyfire](https://docs.apify.com/platform/integrations/skyfire)** — agent-to-service payments for fully autonomous AI-agent workflows.

Building an AI agent, MCP tool, or autonomous data pipeline? This scraper is ready to plug in and pay as it goes.

### Automate & schedule

Run this Actor on autopilot and pull results into your own stack:

- **[Apify API](https://docs.apify.com/api/v2)** - start runs, fetch datasets and manage schedules over REST.
- **[apify-client for JavaScript](https://docs.apify.com/api/client/js/)** and **[apify-client for Python](https://docs.apify.com/api/client/python/)** - official SDKs.
- **[Schedules](https://docs.apify.com/platform/schedules)** - run it hourly, daily or weekly and keep your dataset current.
- **[Webhooks](https://docs.apify.com/platform/integrations/webhooks)** - trigger downstream actions (CRM import, Slack alert, email sequence) the moment a run finishes.

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

const client = new ApifyClient({ token: 'MY_APIFY_TOKEN' });

const run = await client.actor('scrapesage/immobilienscout24-scraper').call({
    "startUrls": [
        "https://www.immobilienscout24.de/Suche/de/berlin/berlin/wohnung-kaufen"
    ],
    "maxPagesPerUrl": 1
});

const { items } = await client.dataset(run.defaultDatasetId).listItems();
console.log(`Got ${items.length} records`);
```

### Integrate with any app

Connect the dataset to thousands of apps - no code required:

- **[Make](https://docs.apify.com/platform/integrations/make)** - multi-step automation scenarios.
- **[Zapier](https://docs.apify.com/platform/integrations/zapier)** - push new records straight into your CRM or spreadsheet.
- **[Slack](https://docs.apify.com/platform/integrations/slack)** - get notified when a scheduled run finds something new.
- **[Google Drive / Sheets](https://docs.apify.com/platform/integrations/drive)** - auto-export every run to a spreadsheet.
- **[Airbyte](https://docs.apify.com/platform/integrations/airbyte)** - pipe results into your data warehouse.
- **[GitHub](https://docs.apify.com/platform/integrations/github)** - trigger runs from commits or releases.

### More scrapers from scrapesage

Related Actors in the same category:

- **[Real Estate Scraper for Redfin](https://apify.com/scrapesage/redfin-scraper)** - Listings, Sold Comps & Leads
- **[BizBuySell Scraper](https://apify.com/scrapesage/bizbuysell-scraper)** - Businesses For Sale & Broker Leads
- **[VivaReal & ZAP Imóveis Scraper](https://apify.com/scrapesage/vivareal-zap-imoveis-scraper)** - Brazil Real Estate
- **[PropertyGuru Scraper](https://apify.com/scrapesage/propertyguru-scraper)** - Singapore Property & Agent Leads
- **[Airbnb Scraper & Market Monitor](https://apify.com/scrapesage/airbnb-scraper)**

### FAQ

**Do I need an ImmoScout24 account, API key or proxies?**
No. Everything needed to reach immobilienscout24.de is built in.

**Can I scrape rentals as well as sales?**
Yes. `wohnung-mieten` and `haus-mieten` URLs work exactly like the `-kaufen` ones; `price` is then the base rent
and `totalRent` fills where the listing publishes it.

**How many listings will I get per search URL?**
Up to 20 per page. `maxPagesPerUrl` decides how deep to go, and `maxItems` caps the whole run. A Berlin apartment
search reports 11,000+ listings across 570+ pages, so the depth is yours to choose. Short page renders are
refetched automatically, and the status message tells you if any page stayed short. You only ever pay for the
rows you actually receive.

**Can I run it on a schedule?**
Yes - schedule the actor or any saved task in Apify and the results land in a dataset each time, ready for the
API, a webhook, or an export to Sheets, S3 or your warehouse.

**Does it open every listing's detail page?**
No. It reads ImmoScout24's search-results data model, which already carries everything in the field table above -
that is what keeps it fast and cheap across thousands of listings.

### Disclaimer

This Actor is an independent tool and is not affiliated with, endorsed by, or sponsored by ImmobilienScout24,
ImmoScout24 or Scout24 SE. All trademarks mentioned are the property of their respective owners. It collects only
publicly available listing information and is intended for lawful research, market analysis and
comparable-pricing use. You are responsible for how you use the data, including compliance with applicable law.

### Need help?

Open an issue on the Actor's **Issues** tab, or visit the [Apify help center](https://help.apify.com/). Feature requests are welcome - this Actor is actively maintained.

# Actor input Schema

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

immobilienscout24.de search URLs, one per line. Build a search on immobilienscout24.de with your filters (city, price, rooms...), then paste the URL from the address bar. Buy and rent, apartments and houses all work. <b>Leave empty and the run returns a small free sample.</b>

## `startUrlsFromFile` (type: `string`):

Bulk-load immobilienscout24.de URLs. Either <b>paste the whole list</b> (one per line), or give <b>a single link</b> to a public <code>.txt</code>/<code>.csv</code>, a Google Sheet/Drive link, or an Apify key-value-store record. A file that cannot be read says so and charges nothing.

## `maxPagesPerUrl` (type: `integer`):

How many result pages to follow for each start URL (20 listings per page).

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

Overall cap across all URLs. You are only charged for listings actually saved.

## `outputFields` (type: `array`):

Pick the fields you want and every record is trimmed to exactly those - handy for lean CSV/Sheets exports.

## Actor input object example

```json
{
  "startUrls": [
    "https://www.immobilienscout24.de/Suche/de/berlin/berlin/wohnung-kaufen"
  ],
  "maxPagesPerUrl": 10,
  "maxItems": 1000
}
```

# Actor output Schema

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

Each listing - price, living space, rooms, address, energy class, agent and contact - as a JSON item in the default dataset.

# 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 = {
    "startUrls": [
        "https://www.immobilienscout24.de/Suche/de/berlin/berlin/wohnung-kaufen"
    ],
    "startUrlsFromFile": ""
};

// Run the Actor and wait for it to finish
const run = await client.actor("scrapesage/immobilienscout24-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 = {
    "startUrls": ["https://www.immobilienscout24.de/Suche/de/berlin/berlin/wohnung-kaufen"],
    "startUrlsFromFile": "",
}

# Run the Actor and wait for it to finish
run = client.actor("scrapesage/immobilienscout24-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 '{
  "startUrls": [
    "https://www.immobilienscout24.de/Suche/de/berlin/berlin/wohnung-kaufen"
  ],
  "startUrlsFromFile": ""
}' |
apify call scrapesage/immobilienscout24-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,scrapesage/immobilienscout24-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/VfkEfKPQaZS4VqkGL/builds/7rpi15yoa8MBBJu1H/openapi.json
