# ImmobilienScout24 Scraper — German Buy & Rent Listings (`khadinakbar/immobilienscout24-scraper`) Actor

Scrape Immobilienscout24.de buy and rent listings by city or /Suche URL. Camoufox clears AWS WAF; returns flat MCP-ready rows: price, rooms, m², address, agency, images. Cookieless, no IS24 login.

- **URL**: https://apify.com/khadinakbar/immobilienscout24-scraper.md
- **Developed by:** [Khadin Akbar](https://apify.com/khadinakbar) (community)
- **Categories:** Real estate, Lead generation, AI
- **Stats:** 2 total users, 1 monthly users, 0.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $5.00 / 1,000 property scrapeds

This Actor is paid per event and usage. You are charged both the fixed price for specific events and for Apify platform usage.

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

## immobilienscout24-scraper

### What it does

Scrapes public [Immobilienscout24.de](https://www.immobilienscout24.de) buy and rent search results. Builds `/Suche/de/{state}/{city}/{estate}-{mieten|kaufen}` from a known German city or accepts live `/Suche` URLs. Camoufox (Firefox anti-detect) + Apify Residential DE clears AWS WAF ("Ich bin kein Roboter"). Parses the embedded `resultListModel` / `searchResponseModel` JSON into flat MCP-ready rows (~20/page) and paginates with `?pagenumber=`.

### ICP

German PropTech, agencies, investors, and AI agents monitoring Immobilienscout24 buy/rent supply — sibling to Immowelt when you need IS24 coverage.

### Why use this Actor?

- **WAF-aware:** Plain HTTP gets 401; this Actor uses Camoufox + DE residential like production Jumia/Kununu patterns.
- **Structured JSON first:** Reads `resultListModel`, not brittle CSS cards.
- **MCP-ready flat rows:** price, rooms, m², address, agency phone, images, coordinates when present.
- **Honest outcomes:** `OUTPUT` / `RUN_SUMMARY` with `COMPLETE` | `PARTIAL` | `VALID_EMPTY` | `INVALID_INPUT` | `UPSTREAM_FAILED`.

### How to use

1. Open the Actor in Apify Console (or call via API / MCP as `apify--immobilienscout24-scraper`).
2. Leave **Location** as `Berlin` (or set München / Hamburg / …) **or** paste Immobilienscout24 `/Suche` URLs.
3. Choose Rent or Buy and estate type when building from location.
4. Set **Max items** (prefill `3` for a cheap canary).
5. Keep the default **Residential DE** proxy.
6. Run. Download the dataset as JSON / CSV / Excel.

### Input

| Field | Description |
|-------|-------------|
| `startUrls` | Immobilienscout24 `/Suche/…` URLs (preferred for districts) |
| `location` | Known DE city when startUrls empty (Berlin, München, …) |
| `operation` | `rent` or `buy` |
| `estateType` | apartment, house, plot, commercial, garage, shared |
| `minPrice` / `maxPrice` | Client-side EUR filters |
| `minRooms` / `maxRooms` | Client-side Zimmer filters |
| `minSpace` / `maxSpace` | Client-side m² filters |
| `maxItems` | Cap on billed rows (1–500) |
| `proxyConfiguration` | Default Apify Residential DE |

Example:

```json
{
  "location": "Berlin",
  "operation": "rent",
  "estateType": "apartment",
  "maxItems": 3,
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": ["RESIDENTIAL"],
    "apifyProxyCountry": "DE"
  }
}
```

### Output

One dataset row per listing. Example:

```json
{
  "listingId": "159990001",
  "url": "https://www.immobilienscout24.de/expose/159990001",
  "operation": "RENT",
  "title": "Helle 3-Zimmer Wohnung",
  "price": 1450,
  "priceCurrency": "EUR",
  "priceFormatted": "1.450 €",
  "rooms": 3,
  "livingSpaceSqm": 78.5,
  "city": "Berlin",
  "zipCode": "10115",
  "district": "Mitte",
  "agencyName": "Demo Immobilien GmbH",
  "agencyPhone": "030 123456",
  "imageUrls": ["https://pictures.immobilienscout24.de/demo.jpg"],
  "source": "immobilienscout24",
  "scrapedAt": "2026-09-21T12:00:00.000Z"
}
```

| Field | Meaning |
|-------|---------|
| `listingId` | Expose ID |
| `price` | EUR number (Kaltmiete / Kaufpreis from SERP) |
| `rooms` / `livingSpaceSqm` | Zimmer / Wohnfläche |
| `address` / `city` / `zipCode` | Location fields |
| `agencyName` / `agencyPhone` | Contact when public |
| `imageUrls` | Gallery / title picture URLs |

You can download the dataset as JSON, HTML, CSV, or Excel.

### Pricing

Pay per event + **platform usage pass-through** (you pay compute/proxy):

| Event | Price |
|-------|-------|
| `apify-actor-start` | $0.00005 |
| `property-scraped` (primary) | $0.005 / listing |

Example: 3 Berlin rent listings ≈ `$0.00005 + 3 × $0.005 = $0.01505` in event charges, plus Residential DE usage.

### Tips

- Prefer pasting a live `/Suche` URL for districts (e.g. Berlin-Mitte) — the location builder covers major cities only.
- Detail `/expose/{id}` enrichment is **out of v1** (deferred); SERP rows already include the public card fields.
- If every page is WAF-blocked, the run ends `UPSTREAM_FAILED` — do not treat zero rows as success in that case.
- Sibling: [Immowelt All-in-One](https://apify.com/khadinakbar/immowelt-all-in-one-scraper) for Immowelt.de (HTTP Cheerio).

### API / MCP

```bash
apify call khadinakbar/immobilienscout24-scraper --input='{"location":"Berlin","operation":"rent","maxItems":3}'
```

MCP tool name: `apify--immobilienscout24-scraper`

### Legal disclaimer

This Actor scrapes **public** Immobilienscout24 search listings for legitimate research, market monitoring, and lead workflows. You must comply with Immobilienscout24 terms, applicable law (including GDPR), and Apify Acceptable Use. Do not use results for spam, harassment, or unauthorized bulk contact. Not affiliated with Immobilienscout24 GmbH.

### FAQ

**Why Camoufox?** Immobilienscout24 fronts AWS WAF; Cheerio/HTTP alone returns challenge HTML.

**Why Residential DE?** Non-DE / datacenter exits rarely clear the challenge.

**Empty results?** Valid empty searches return `VALID_EMPTY`. Persistent WAF → `UPSTREAM_FAILED`.

### Support

Open an Issue on the Actor page in Apify Console. Custom PropTech pipelines available on request.

# Changelog

This Actor's version history is a separate document: https://apify.com/khadinakbar/immobilienscout24-scraper/changelog.md

# Actor input Schema

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

Immobilienscout24 search URLs to scrape. Supports /Suche/de/{state}/{city}/{estate}-{mieten|kaufen} and /Suche/radius/… paths. Paginated with ?pagenumber=. Detail /expose/{id} URLs are detected but skipped in v1. Non-immobilienscout24.de hosts are rejected.

## `location` (type: `string`):

German city used when startUrls is empty. Must be a known city mapped in the Actor (Berlin, München, Hamburg, Köln, Frankfurt, …). Prefer pasting a live /Suche URL for districts or missing cities.

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

Buy or rent when building a search from location. Ignored when startUrls already encode mieten/kaufen. Defaults to rent.

## `estateType` (type: `string`):

Property type when building a search from location. Maps to IS24 path segments (wohnung, haus, grundstueck, gewerbeimmobilie, garage, wg-zimmer).

## `minPrice` (type: `integer`):

Client-side minimum price filter in EUR applied after each page is parsed. Leave empty for no minimum.

## `maxPrice` (type: `integer`):

Client-side maximum price filter in EUR. Leave empty for no maximum.

## `minRooms` (type: `number`):

Client-side minimum room count (Zimmer). Leave empty for any.

## `maxRooms` (type: `number`):

Client-side maximum room count (Zimmer). Leave empty for any.

## `minSpace` (type: `integer`):

Client-side minimum living space in square meters. Leave empty for any.

## `maxSpace` (type: `integer`):

Client-side maximum living space in square meters. Leave empty for any.

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

Maximum dataset rows to return and charge. IS24 returns about 20 listings per page; the Actor paginates with pagenumber until this cap. Defaults to 30. Hard cap 500.

## `proxyConfiguration` (type: `object`):

Proxy settings. Default is Apify Residential DE — Immobilienscout24 AWS WAF blocks datacenter and non-DE exits. Keep RESIDENTIAL + DE for reliable clears.

## Actor input object example

```json
{
  "startUrls": [
    {
      "url": "https://www.immobilienscout24.de/Suche/de/berlin/berlin/wohnung-mieten"
    }
  ],
  "location": "Berlin",
  "operation": "rent",
  "estateType": "apartment",
  "maxItems": 3,
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "RESIDENTIAL"
    ],
    "apifyProxyCountry": "DE"
  }
}
```

# Actor output Schema

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

Default dataset with one Immobilienscout24 property per row.

## `OUTPUT` (type: `string`):

Terminal outcome record (COMPLETE, PARTIAL, VALID\_EMPTY, INVALID\_INPUT, UPSTREAM\_FAILED).

## `RUN_SUMMARY` (type: `string`):

Same terminal outcome as OUTPUT for agent-friendly readback.

# 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": [
        {
            "url": "https://www.immobilienscout24.de/Suche/de/berlin/berlin/wohnung-mieten"
        }
    ],
    "location": "Berlin",
    "operation": "rent",
    "estateType": "apartment",
    "maxItems": 3,
    "proxyConfiguration": {
        "useApifyProxy": true,
        "apifyProxyGroups": [
            "RESIDENTIAL"
        ],
        "apifyProxyCountry": "DE"
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("khadinakbar/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": [{ "url": "https://www.immobilienscout24.de/Suche/de/berlin/berlin/wohnung-mieten" }],
    "location": "Berlin",
    "operation": "rent",
    "estateType": "apartment",
    "maxItems": 3,
    "proxyConfiguration": {
        "useApifyProxy": True,
        "apifyProxyGroups": ["RESIDENTIAL"],
        "apifyProxyCountry": "DE",
    },
}

# Run the Actor and wait for it to finish
run = client.actor("khadinakbar/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": [
    {
      "url": "https://www.immobilienscout24.de/Suche/de/berlin/berlin/wohnung-mieten"
    }
  ],
  "location": "Berlin",
  "operation": "rent",
  "estateType": "apartment",
  "maxItems": 3,
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "RESIDENTIAL"
    ],
    "apifyProxyCountry": "DE"
  }
}' |
apify call khadinakbar/immobilienscout24-scraper --silent --output-dataset

```

## MCP server setup

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