# Immowelt.de Scraper \[$0.9💰] Price, Energy & Agent Leads 🇩🇪 (`ahmed_jasarevic/immowelt-property-scraper`) Actor

Extract property listings from Immowelt.de for $0.9/1,000 results. Get price, price per m², rooms, energy class (A+–F), plus deep details: agent contact, geo coordinates, exposure dates. Fast Cheerio-based extraction — no browser needed. Germany's #2 real estate portal.

- **URL**: https://apify.com/ahmed\_jasarevic/immowelt-property-scraper.md
- **Developed by:** [Ahmed Jasarevic](https://apify.com/ahmed_jasarevic) (community)
- **Categories:** Real estate, Automation, Lead generation
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: 5.00 out of 5 stars

## Pricing

from $0.63 / 1,000 results

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

## Immowelt.de Scraper — German Property Listings, Price & Agent Data 🇩🇪

💰 **From $0.9 per 1,000 results** — price, price per m², rooms, energy class, plus deep-detail fields: agent contact, geo coordinates, exposure dates.

**Scrape German property listings from [immowelt.de](https://www.immowelt.de)** — one of Germany's largest real estate portals — and get structured data on every listing in seconds. Built for investors, agents, researchers, and proptech teams who need clean, ready-to-use real estate data without maintaining their own scraper.

***

### Why use this actor?

- 💸 **Cheap & fast** — search-result pages are parsed with plain HTTP (Cheerio), no browser needed. A full listing card, including price per m² and energy class, is extracted in a single request.
- 📊 **Investor-ready fields** — price per m² lets you compare listings instantly; energy class (A+ to F) helps identify cost-risk properties.
- 📞 **Lead generation** — agent/agency contact details (phone, email, company) are extracted from listing detail pages.
- 📍 **Location intelligence** — geo coordinates, full address, and district names for mapping and research.
- 🔒 **Safe to run** — all traffic routes through the Apify proxy (residential recommended), protecting your IP.
- 🇩🇪 **Germany-focused** — targets immowelt.de specifically, Germany's #2 property portal, with fields tuned to German listing conventions (Kaltmiete, Kaufpreis, Energieausweis).

***

### Use cases

#### Market research & price comparables

**Analysts benchmarking rents and sale prices across German cities.**
Input: search URLs per city · Output: price, price/m², rooms, energy class · Use: build price/rent comparables and heatmaps.

#### Lead generation for real estate agents

**Agents sourcing listings and contacts to win new mandates.**
Input: search by region · Output: agent name, phone, email, company · Use: build outreach lists and prioritize follow-ups.

#### Investment & rental-yield analysis

**Investors modelling yields on apartments and houses.**
Input: filtered search by price/area · Output: price, price/m², energy data · Use: compute gross yields and cost-risk scores at scale.

#### PropTech & data products

**Builders feeding a German property data product or valuation model.**
Input: scheduled runs per region · Output: structured JSON · Use: power a search or valuation app without an Immowelt API key.

#### Relocation & site selection

**Companies and relocation services finding housing near a new office or for clients moving cities.**
Input: search by city/postcode · Output: address, geo coordinates, price, energy class · Use: build map-ready shortlists.

#### Energy & housing research

**Researchers and journalists studying building efficiency or housing affordability.**
Input: detail-mode runs per region · Output: energy class, construction year, heating type · Use: analyze the German housing stock.

***

### How to use

1. Open the actor's **Input** tab.
2. Paste one or more immowelt.de search URLs. Good defaults:
   - `https://www.immowelt.de/suche/kaufen/wohnung/deutschland/ad02de1` (buy apartments, whole Germany)
   - any other `/suche/...` URL from the immowelt sitemaps (or your own filters)
   - direct expose URLs `/expose/{id}` are also accepted
3. Set **Max listings** (default 100), **Max pages per search** (default 5), and whether to **scrape details**.
4. Click **Run** (free preview gives 10 listings), then download the dataset as JSON, CSV, Excel, or HTML.

***

### Input

| Field | Type | Default | Description |
|---|---|---|---|
| `startUrls` | array | Germany-wide buy search | immowelt.de search or expose URLs |
| `maxItems` | int | 100 | Max listings to scrape |
| `maxPagesPerSearch` | int | 5 | SERP pages per search URL (~25 listings each) |
| `scrapeDetails` | bool | true | Fetch expose pages for energy/contact/dates/geo |
| `maxRequestsPerCrawl` | int | 250 | Hard cap on HTTP requests |
| `proxy` | proxy object | Apify Residential | Proxy group to use |

**Example input:**

```json
{
  "startUrls": ["https://www.immowelt.de/suche/kaufen/wohnung/hamburg/ad08de1113"],
  "maxItems": 200,
  "maxPagesPerSearch": 8,
  "scrapeDetails": true,
  "proxy": { "useApifyProxy": true, "apifyProxyGroups": ["RESIDENTIAL"] }
}
```

***

### Output

Example dataset item:

```json
{
  "exposeId": "0c5b0a9b-48ab-4a2f-85c7-1f27fb289993",
  "url": "https://www.immowelt.de/expose/0c5b0a9b-48ab-4a2f-85c7-1f27fb289993",
  "title": "Maisonette zum Kauf",
  "listingType": "buy",
  "price": 92000,
  "pricePerSqm": 1832,
  "priceText": "92.000 €  1.832 €/m²",
  "rooms": 2,
  "livingAreaSqm": 50.2,
  "address": "Königsbrück, Königsbrück (01936)",
  "energyClass": "E",
  "description": "Vermietete 2-Zimmer-Eigentumswohnung in Königsbrück...",
  "detailScraped": true,
  "detailBlocked": false,
  "energy": {
    "efficiencyClass": "D",
    "certificateType": "Verbrauchsausweis",
    "endEnergyConsumption": "145 kWh/(m²·a)",
    "primaryEnergySource": "Erdgas",
    "heatingType": "Zentralheizung",
    "constructionYear": 1995
  },
  "contact": {
    "company": "Immobilien GmbH",
    "contactPerson": "Max Mustermann",
    "phone": "+49 123 456 789",
    "email": "info@example-immobilien.de"
  },
  "exposureDates": {
    "published": "01.06.2026",
    "availableFrom": "sofort"
  },
  "geo": { "latitude": 51.27, "longitude": 13.92 },
  "scrapedAt": "2026-08-12T08:00:00.000Z"
}
```

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

#### Data table

| Field | Description |
|---|---|
| `title` | Listing headline |
| `price` / `pricePerSqm` | Purchase/rental price (EUR) and price per m² |
| `rooms` / `livingAreaSqm` | Rooms and living area |
| `address` | City, district, postcode |
| `energyClass` | Energy efficiency class (A+..F) |
| `energy.*` | Detail: certificate type, kWh consumption, energy source, heating, construction year |
| `contact.*` | Detail: agency/company, contact person, phone, email |
| `exposureDates.*` | Detail: published / available-from dates |
| `geo` | Detail: latitude / longitude |
| `detailScraped` / `detailBlocked` | Whether the expose page was scraped / blocked |

***

### Integration examples

#### JavaScript / Node.js

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

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

const run = await client.actor('ahmed_jasarevic/immowelt-de-property-scraper').call({
  startUrls: ['https://www.immowelt.de/suche/mieten/wohnung/deutschland/ad02de1'],
  maxItems: 100,
  scrapeDetails: true,
});

const { items } = await client.dataset(run.defaultDatasetId).listItems();
console.log(items[0]);
```

#### Python

```python
from apify_client import ApifyClient

client = ApifyClient('YOUR_TOKEN')

run = client.actor('ahmed_jasarevic/immowelt-de-property-scraper').call(run_input={
    'startUrls': ['https://www.immowelt.de/suche/kaufen/wohnung/deutschland/ad02de1'],
    'maxItems': 100,
    'scrapeDetails': True,
})

for item in client.dataset(run['defaultDatasetId']).iterate_items():
    print(item)
```

#### cURL

```bash
curl -X POST "https://api.apify.com/v2/acts/ahmed_jasarevic~immowelt-de-property-scraper/runs?token=YOUR_TOKEN" \
  -H 'Content-Type: application/json' \
  -d '{"startUrls":["https://www.immowelt.de/suche/kaufen/wohnung/deutschland/ad02de1"],"maxItems":100,"scrapeDetails":true}'
```

#### Automation workflows (n8n / Zapier / Make)

1. **Trigger**: schedule or webhook
2. **HTTP Request**: call the actor API
3. **Process**: parse the JSON results
4. **Action**: save to a sheet/DB, notify, or feed into your own valuation model

***

### How much does it cost to scrape immowelt.de?

The actor is **Cheerio-based**, so compute costs are low — roughly one request per SERP card plus one request per expose detail page. A 100-listing run typically uses well under 1 Compute Unit. Free runs are capped at 10 listings.

At **$0.9 per 1,000 results**, a 1,000-listing overview run costs less than a coffee.

***

### Tips and advanced options

- **SERP pages have no bot protection** — if you only need price / price-per-m² / rooms / area / energy class, set `scrapeDetails: false` and the run is very fast and cheap.
- **Expose detail pages are protected by DataDome** — enable the **Residential** proxy group for the best success rate. If detail pages come back blocked, the actor still saves the full SERP-level record with `detailBlocked: true`.
- Use `maxPagesPerSearch` to control depth; combine multiple filtered search URLs to build broad city/region coverage.
- Check immowelt's `robots.txt` / `sitemaps/sitemap_index.xml` for canonical search URLs to feed into `startUrls`.

***

### FAQ

**How much does it cost?**
$0.9 per 1,000 results. Free tier gives 10 listings per run to test before you scale up.

**Do I need a proxy?**
Not for SERP-only runs. For detail pages (agent contact, geo, energy data), a Residential proxy group is strongly recommended since those pages are protected by DataDome.

**What's the difference between overview and detail scraping?**
Overview (`scrapeDetails: false`) returns everything visible on the search-results card — fast and cheap. Detail mode additionally visits each expose page for energy data, agent contact, exposure dates, and geo coordinates.

**Can I scrape a specific city or region only?**
Yes — paste a filtered immowelt.de search URL (city, price range, property type, rent/buy) into `startUrls`; the actor respects whatever filters are already in the URL.

**Can I scrape rentals and sales in the same run?**
Yes — add multiple `startUrls`, one per search type (e.g. one `mieten` URL and one `kaufen` URL).

**Is scraping immowelt.de legal?**
Scraping public property data for research and analysis is generally acceptable, but always respect immowelt.de's Terms of Service and German data protection rules (GDPR). Do not resell personal contact data without a legal basis. Read more in [Apify's blog post on the legality of web scraping](https://blog.apify.com/is-web-scraping-legal/).

**Will it break when Immowelt updates their site?**
The actor is actively maintained and updated when Immowelt changes its page structure.

**What output formats are supported?**
JSON, CSV, Excel, and HTML — all exportable directly from the Apify dataset.

***

### Known limitations

- immowelt.de uses DataDome on expose detail pages; without a residential proxy (or in rare hard-block cases) detail fields may be unavailable.
- Field availability varies by listing — private sellers often omit energy data.

***

### Support

Found a bug or need a custom field? Open an issue in the actor's **Issues** tab, or reach out for custom German real-estate scraping solutions.

> *Immowelt® is a trademark of its respective owner. This actor is an independent tool and is not affiliated with, endorsed by, or sponsored by Immowelt or the AVIV Group.*

# Actor input Schema

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

One or more immowelt.de search (SERP) URLs, e.g. https://www.immowelt.de/suche/kaufen/wohnung/deutschland/ad02de1 . Direct expose URLs (/expose/{id}) are also accepted.

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

Maximum number of property listings to scrape.

## `maxPagesPerSearch` (type: `integer`):

Maximum number of SERP pages to follow per search URL (each page holds ~25 listings).

## `scrapeDetails` (type: `boolean`):

Also fetch each listing's expose detail page to get energy data, agent contact, exposure dates and geo coordinates. Requires residential proxy to pass DataDome protection.

## `maxRequestsPerCrawl` (type: `integer`):

Hard cap on the total number of HTTP requests made in this run.

## `proxy` (type: `object`):

Apify Proxy with Residential IPs is recommended to avoid blocking on listing detail pages.

## Actor input object example

```json
{
  "startUrls": [
    {
      "url": "https://www.immowelt.de/suche/kaufen/wohnung/deutschland/ad02de1"
    }
  ],
  "maxItems": 100,
  "maxPagesPerSearch": 5,
  "scrapeDetails": false,
  "maxRequestsPerCrawl": 250,
  "proxy": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "RESIDENTIAL"
    ]
  }
}
```

# Actor output Schema

## `results` (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 = {
    "startUrls": [
        {
            "url": "https://www.immowelt.de/suche/kaufen/wohnung/deutschland/ad02de1"
        }
    ],
    "proxy": {
        "useApifyProxy": true,
        "apifyProxyGroups": [
            "RESIDENTIAL"
        ]
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("ahmed_jasarevic/immowelt-property-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.immowelt.de/suche/kaufen/wohnung/deutschland/ad02de1" }],
    "proxy": {
        "useApifyProxy": True,
        "apifyProxyGroups": ["RESIDENTIAL"],
    },
}

# Run the Actor and wait for it to finish
run = client.actor("ahmed_jasarevic/immowelt-property-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.immowelt.de/suche/kaufen/wohnung/deutschland/ad02de1"
    }
  ],
  "proxy": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "RESIDENTIAL"
    ]
  }
}' |
apify call ahmed_jasarevic/immowelt-property-scraper --silent --output-dataset

```

## MCP server setup

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