Immowelt.de Scraper - Properties, Prices & Agent Contacts
Pricing
from $0.80 / 1,000 results
Immowelt.de Scraper - Properties, Prices & Agent Contacts
Scrape detailed property listings from Immowelt.de into clean structured data. Extract prices, GPS coordinates, rooms, living area, photos, energy class, property features, agent contact details, and more.
Pricing
from $0.80 / 1,000 results
Rating
0.0
(0)
Developer
Abot API
Maintained by CommunityActor stats
0
Bookmarked
5
Total users
0
Monthly active users
3 days ago
Last modified
Categories
Share
Immowelt Scraper: German Property Listings with Price, Agent & GPS Data
Immowelt Scraper turns immowelt.de into structured property data. Get price, price per m², rooms, living area, floor, energy class, full address, GPS coordinates, agent name, company, phone, website, rating, and a full image gallery for Buy and Rent listings across Germany. Search by state and city, paste a search URL you already refined in your browser, or monitor a saved search on a schedule and get back only what changed. Export to JSON, CSV or Excel, or pull results straight into your app through the API.
Why This Scraper?
- 40+ fields per listing. Price, price per m², address, GPS coordinates, rooms, living area, floor, energy class, image gallery, agent name, company, phone, website, rating and more.
- GPS coordinates on nearly every listing. Latitude and longitude are added automatically from Immowelt's own map data, on by default; very large searches (beyond roughly 2000 results) may have null coordinates on later listings.
- Two ways to search. Pick a German state and city from dropdowns, or paste any Immowelt search URL you already refined in your browser.
- Rich filter set. Price, rooms, living area, construction year and sort order, passed straight through to Immowelt so results match what the site itself would show.
- Both Buy and Rent. Apartments, houses, plots and offices.
- Auto pagination. Walks forward through every result page up to the limit you set, 30 listings per page.
- Built for recurring monitoring. Incremental mode classifies each listing as new, updated, unchanged or gone since your last scheduled run, so a repeat search returns only what changed.
Use Cases
- Real estate investors: track price per m² across cities and property types to find undervalued listings.
- PropTech and market research teams: build a live feed of Buy and Rent listings with coordinates for mapping and comparison tools.
- Relocation and rental agencies: monitor a specific city or filter combination for new listings the moment they appear, using a schedule with Incremental mode.
- Lead generation: collect agent names, companies, phone numbers and websites from active listings for outreach.
- Data teams: build historical datasets of price, size, energy class and location for pricing and valuation models.
Data You Get
| Field | Example |
|---|---|
id | "26QPUH3FZ3H7" |
url | Immowelt expose link for the listing |
listingType | "Buy" (also "Rent") |
propertyType | "APARTMENT" (also "HOUSE", "PLOT", "OFFICE") |
title | "Studio zum Kauf" |
priceValue / priceDisplay | 545000 / "545.000 €" |
pricePerSqm | "12.520 €/m²" |
rooms | 1 |
livingSpace | 43.5 |
floor | "EG" |
energyClass | "C" |
city / district / postcode | "München" / "Altstadt-Lehel" / "80538" |
latitude / longitude | 48.1344 / 11.5843 (added when GPS coordinates is on) |
agentName / agentCompany | "Frau Anna Beispiel" / "Beispiel Immobilien GmbH" |
agentPhones / agentWebsite | ["+4989000000"] / agency website URL |
agentRating / agentReviews | 4.3 / 47 |
imageCount | 13 |
images | array of full-size image URLs |
hasFloorplan / has3DTour | true / true |
isNew / hasBrokerageFee | false / false |
origin | "strict" (also "enlarged", "suggested", a filter-radius fallback) |
creationDate / updateDate | ISO timestamps from Immowelt |
changeType | "NEW" / "UPDATED" / "UNCHANGED" / "REAPPEARED" / "EXPIRED". Only present when incrementalMode is on |
scrapedAt | ISO timestamp of this scrape |
Every listing also carries legacyId (Immowelt's internal id used to build the URL), plotArea (houses and plots only), addressPublished (whether Immowelt is showing the exact street), agentType (AGENCY or PRIVATE), agentAddress, and imagesAnnotated (each image URL paired with its room classification, such as kitchen or bathroom). Turning on Visit each listing's detail page additionally fills constructionYear, energyValue and the long description; without it these three stay null. In incremental mode, changedFields lists which fields changed since the last run, and firstSeenAt / lastSeenAt track when the listing first appeared and was last seen.
How to Use
- Pick a Search mode: Filter mode (state plus city from dropdowns) or URL mode (paste Immowelt search URLs).
- Fill in the fields for that mode: for Filter mode, one or more locations, Buy or Rent, property type, and any price, room, living space or construction year filters; for URL mode, paste one or more search URLs.
- Set Max total listings (and optionally Max pages per search) to control run size and cost, then click Start.
- Download the dataset as JSON, CSV or Excel, or read it through the API.
Search by location:
{"mode": "filter","locations": [{ "state": "berlin", "city": "Berlin" }],"listingType": "Buy","propertyType": "Apartment","maxListings": 100}
Search with filters:
{"mode": "filter","locations": [{ "state": "bayern", "city": "München" }],"listingType": "Buy","propertyType": "Apartment","priceMin": 400000,"priceMax": 800000,"roomsMin": 2,"roomsMax": 3,"livingSpaceMin": 50,"livingSpaceMax": 100,"sortBy": "PriceAsc","maxListings": 200}
Direct URL with auto pagination:
{"mode": "url","urls": ["https://www.immowelt.de/classified-search?distributionTypes=Rent&estateTypes=Apartment&locations=AD08DE1113&numberOfRoomsMin=2&spaceMin=60"],"maxPages": 20}
Recurring monitoring of a saved search:
{"mode": "filter","locations": [{ "state": "berlin", "city": "Berlin" }],"listingType": "Buy","propertyType": "Apartment","maxListings": 300,"incrementalMode": true}
The first run of this last example returns every listing as NEW. Schedule it and every later run instead returns only NEW and UPDATED listings for that same search, with UNCHANGED ones suppressed from the dataset by default.
Run it from your code
Python:
from apify_client import ApifyClientclient = ApifyClient("<YOUR_APIFY_TOKEN>")run = client.actor("abotapi/immowelt-de-scraper").call(run_input={"mode": "filter","locations": [{"state": "berlin", "city": "Berlin"}],"listingType": "Buy","propertyType": "Apartment","maxListings": 100,})for listing in client.dataset(run["defaultDatasetId"]).iterate_items():print(listing["title"], listing["priceDisplay"])
JavaScript:
import { ApifyClient } from 'apify-client';const client = new ApifyClient({ token: '<YOUR_APIFY_TOKEN>' });const run = await client.actor('abotapi/immowelt-de-scraper').call({mode: 'filter',locations: [{ state: 'berlin', city: 'Berlin' }],listingType: 'Buy',propertyType: 'Apartment',maxListings: 100,});const { items } = await client.dataset(run.defaultDatasetId).listItems();
Or connect it to Make, Zapier, n8n, Google Sheets or webhooks from the Integrations tab.
Locations and disambiguation
The state is what tells same-named towns apart: Germany has several towns sharing a name, so { "state": "bayern", "city": "Neustadt" } and { "state": "sachsen", "city": "Neustadt" } resolve to two different towns and return two different result sets. When a state has more than one town matching what you typed, the closest match is used and the full resolved name is written to the run log, so you can see exactly which one you got.
Max pages, max listings, and resuming a full-catalogue walk
Max pages per search and Max total listings cap a single run. Leave Max pages per search empty to walk every result page; Max total listings defaults to a hard cap of 20, and 0 removes it (still bounded by Max pages if that is set).
For an unbounded pull, two things protect a long run:
resumeFromRunIdlets you continue in a brand-new run: paste the ID of a previous run (or its dataset), and this run skips everyidalready saved there, appending only new listings.- A checkpoint is saved automatically as the run progresses. If the run is interrupted by an Apify platform migration, or you click Resurrect on a failed run, it picks back up from where it left off in the same run, without re-saving already-collected listings. No input is needed for this; it is automatic.
Resume and incremental mode
These are two different features that both sound like "continue a search":
- Resume (
resumeFromRunId) continues ONE interrupted crawl. Paste a previous run or dataset ID and this run only adds listings it has not already saved there. - Incremental mode (
incrementalMode) is for a search you run again and again on a schedule. The actor remembers its own baseline in its own storage, keyed bystateKey(or auto-derived from the search scope), and classifies every scraped listing asNEW,UPDATED(withchangedFields), orUNCHANGED(suppressed from the dataset and not billed unlessemitUnchangedis on). A listing is only classifiedEXPIREDonce a run reaches the natural end of that search's results withemitExpiredon; a run capped by Max total listings or Max pages, or one continuing viaresumeFromRunId, skipsEXPIREDdetection, since it never proved the listing is actually gone.REAPPEAREDonly happens to a listing that was previously markedEXPIREDon an earlier complete scan and is then found again; it is not something that happens "by default" on an ordinary recurring run where nothing was ever marked expired. - Combining
incrementalModewithresumeFromRunIdis only supported to bootstrap the very first incremental run from a prior full-catalogue crawl. Once a baseline exists for a state key, the run fails fast asking you to removeresumeFromRunIdor pick a differentstateKey.
Send results into your apps (MCP connectors)
Optionally pipe the scraped results into the apps you already use, via Model Context Protocol (MCP) connectors. This is an extra delivery step after the scrape: the Apify dataset is never changed.
What gets written to the connector: a condensed, human-readable summary of each record, not the full JSON. Each item becomes one entry with a title and its key fields flattened to plain text. The complete record always stays in the Apify dataset.
- Authorize a connector once under Apify > Settings > Integrations (Notion, Linear, Airtable, or Apify).
- Select it in the "Pipe results into your apps" input field. (If the picker is empty, you haven't authorized a connector yet.)
- For Notion, also set
notionParentPageUrlto the page where items should be created.
The connection is mediated by Apify's MCP proxy, so this actor never sees your third-party credentials. Leave the field empty to skip.
Input Parameters
| Parameter | Type | Default | Description |
|---|---|---|---|
mode | string | filter | Filter mode (state plus city dropdowns) or URL mode (paste search URLs). |
locations | array | no default (prefill: state berlin, city Berlin) | Locations to search. Filter mode only. |
listingType | string | Buy | Buy or Rent. In Filter mode this builds the search. In URL mode it never filters: the value is read from each pasted URL when the URL states one, and this field is only the fallback label for URLs that do not. |
propertyType | string | Apartment | Apartment, House, Plot, or Office. Filter mode only. |
priceMin | integer | no default | Minimum price in EUR. Filter mode only. Leave empty for no minimum. |
priceMax | integer | no default | Maximum price in EUR. Filter mode only. Leave empty for no maximum. |
roomsMin | integer | no default | Minimum number of rooms. Filter mode only. |
roomsMax | integer | no default | Maximum number of rooms. Filter mode only. |
livingSpaceMin | integer | no default | Minimum living area in m². Filter mode only. |
livingSpaceMax | integer | no default | Maximum living area in m². Filter mode only. |
constructionYearMin | integer | no default | Earliest construction year. Filter mode only. |
constructionYearMax | integer | no default | Latest construction year. Filter mode only. |
sortBy | string | Default | Sort order for results. Filter mode only; in URL mode the sort is taken from your URL. |
urls | array | no default (prefill: one sample search URL) | One or more Immowelt search URLs. URL mode only. If a URL contains page=N, scraping starts at page N and walks forward. |
maxPages | integer | no default (empty = walk every result page) | How many result pages to walk per location or URL, 30 listings per page. Applies to both modes. |
maxListings | integer | 20 | Hard cap across the whole run. 0 = unlimited, still bounded by Max pages if set. |
includeCoordinates | boolean | true | Add latitude and longitude to each listing. Minimal overhead: about one extra request per search page. |
fetchDetails | boolean | false | Visit each listing's detail page for the long description and a couple of extra fields; multiplies proxy bandwidth roughly tenfold, so leave it off unless you need the long description. |
proxy | object | no default (prefill: Apify RESIDENTIAL, country DE) | Connection settings. A German residential proxy gives the cleanest data. |
mcpConnectors | array | no default | Optional: send a summary of each listing to apps you authorized under Integrations. |
notionParentPageUrl | string | no default | Notion connector only: page under which item pages are created. |
maxNotifyListings | integer | 50 | Cap on items written to each connector per run. Does not affect the dataset. |
resumeFromRunId | string | no default | A previous run ID or dataset ID to continue a full-catalogue walk across separate runs. |
incrementalMode | boolean | false | Recurring monitoring of the same search: classify every listing as NEW/UPDATED/UNCHANGED/REAPPEARED/EXPIRED against this actor's own remembered baseline. |
stateKey | string | no default | Manually name the incremental baseline. Leave empty to auto-derive one from the search scope. |
emitUnchanged | boolean | false | Also save UNCHANGED listings to the dataset. Returns and bills every listing every run. |
emitExpired | boolean | false | Also save an EXPIRED row for a previously tracked listing that no longer appears, once a run reaches a complete scan. |
Output Example
{"id": "EXAMPLE0001","legacyId": "00000000-0000-0000-0000-000000000000","url": "https://www.immowelt.de/expose/00000000-0000-0000-0000-000000000000","listingType": "Buy","origin": "strict","propertyType": "APARTMENT","title": "Studio zum Kauf","priceValue": 545000,"priceCurrency": "EUR","priceDisplay": "545.000 €","pricePerSqm": "12.520 €/m²","rooms": 1,"livingSpace": 43.5,"plotArea": null,"floor": "EG","constructionYear": null,"energyClass": "C","energyValue": null,"country": "DEU","city": "München","district": "Altstadt-Lehel","postcode": "80538","street": null,"latitude": 48.1344,"longitude": 11.5843,"addressPublished": false,"agentName": "Frau Anna Beispiel","agentCompany": "Beispiel Immobilien GmbH","agentType": "AGENCY","agentPhones": ["+4989000000"],"agentWebsite": "https://www.example-immobilien.de/","agentProfileUrl": "https://www.immowelt.de/profil/0000000000000000000000000000","agentRating": 4.3,"agentReviews": 47,"agentAddress": "Beispielstraße 1, 80331 München","imageCount": 2,"images": ["https://mms.immowelt.de/3/c/e/b/sample1.jpg", "https://mms.immowelt.de/e/a/d/d/sample2.jpg"],"hasFloorplan": true,"has3DTour": true,"hasBrokerageFee": false,"isExclusive": false,"isNew": false,"creationDate": "2026-04-13T10:41:40.410Z","updateDate": "2026-04-13T10:41:54.893Z","description": null,"scrapedAt": "2026-04-21T08:45:02.602Z"}
Plan Requirement
This actor needs a German residential proxy to return complete data. The default connection setting (Apify Residential, country DE) works out of the box. If your Apify plan does not include residential proxy access, uncheck "Use Apify proxy" under Connection and paste your own residential proxy URLs there instead; the actor rotates through them automatically. The Pricing tab shows the current rates.
FAQ
How much does it cost?
You pay per listing returned. The Pricing tab shows the current rates. Use Max total listings to cap the cost of any run, and leave fetchDetails off unless you need the long description, since it multiplies the work per listing.
Is it legal to scrape immowelt.de?
This actor collects only publicly available property listing data. You are responsible for how you use it: follow immowelt.de's terms and the laws that apply to you, and get legal advice if you plan commercial redistribution. Listing facts such as price, rooms and address are generally not protected, but photos and agent branding may be subject to third-party rights.
Can I get only new or changed listings on a schedule?
Yes. Schedule the actor from the Schedules tab and turn on Incremental mode. Each run then returns only new and updated listings for that search, and unchanged ones are suppressed from the dataset (and not billed) unless you turn emitUnchanged on.
What's the difference between Resume and Incremental mode?
They solve different problems. Resume (resumeFromRunId) continues ONE interrupted full-catalogue crawl: paste the ID of an earlier run and this run only adds listings it has not already saved there. Incremental mode (incrementalMode) is for a search you run again and again on a schedule: it remembers its own baseline and reports only what is new, updated, or gone since the previous scheduled run. Use one or the other, not usually both; combining them is only supported to bootstrap the very first incremental run from a prior full crawl.
Why did my run return 0 listings instead of failing?
If immowelt.de blocks every request for a search, this actor logs a warning and moves on rather than stopping the whole run, so your dataset can end up empty (or partial, if only some locations were blocked) while the run still shows as succeeded. Check the run log for the warning, then re-run in a few minutes or try a different proxy country under Connection. The run does fail outright when the connection itself cannot be set up at all, or when a pasted "Resume from a previous run" ID does not match a run or dataset you can read.
Can I use it with AI agents or MCP?
Yes. Call it from any Apify integration or MCP client, and use the connector field to push results into Notion, Linear or Airtable.
🔗 Want more real estate data?
Pair this actor with these related scrapers from the same team:
| 🏠 ImmobilienScout24.de Scraper $0.9💰/1K for Gold discount. Extract property listings from immobilienscout24.de... | 🏠 SeLoger Scraper Scrape SeLoger.com properties for sale and rent. Search by location with price, room and... |
| 🏠 Fotocasa.es From $1/1K. Scrape Spain property listings from fotocasa.es. Get price, surface, rooms... | 🏠 Pap.fr From $1/1k. Extract property listings from pap.fr. Get fully-detailed listings with... |
| 🏠 Funda in Business Scraper Scrape Funda in Business commercial listings: offices, retail, industrial, catering and... | 🏠 Otodom.pl Scraper Scrape Otodom.pl properties for sale and rent, including apartments, houses, plots... |
💬 Support
- 🐞 Found a bug or a missing field? Open a ticket on the Issues tab. We usually reply within hours.
- 🛠️ Need another site, extra fields or a private build? Email contact@abotapi.com.
- ⭐ Enjoying it? A quick review on the actor page helps other users find it.