# Immoweb Scraper (`parseforge/immoweb-scraper`) Actor

Scrape Immoweb.be property listings from any search URL: price, address, surface, bedrooms, EPC score, construction year, garden, terrace, agency contact and photos. Export to CSV, JSON, Excel or XML.

- **URL**: https://apify.com/parseforge/immoweb-scraper.md
- **Developed by:** [ParseForge](https://apify.com/parseforge) (community)
- **Categories:** Real estate, Lead generation, Automation
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $3.30 / 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

![ParseForge Banner](https://github.com/ParseForge/apify-assets/blob/ad35ccc13ddd068b9d6cba33f323962e39aed5b2/banner.jpg?raw=true)

## 🏠 Immoweb Scraper

> 🚀 **Export Immoweb property listings with the full record in seconds.** Paste any Immoweb search URL, for sale or for rent, houses, apartments, new-build projects, garages, offices or land, and get 97 fields per listing back: price and price per square metre, exact address with coordinates, surfaces, bedrooms and bathrooms, EPC score and energy consumption, construction year, garden, terrace, parking, flood zone, cadastral income, the agency's phone, email and IPI number, and every photo. No login, no browser, no API key.

Immoweb is Belgium's largest property portal, with close to 10,000 houses and apartments for sale on any given day plus rentals, new-build projects, garages, offices and land. Its search page shows a card with a price, a locality and a photo. This Actor reads the same JSON that Immoweb's own search page loads, opens each listing for the full record the way a visitor would, and returns everything as one flat row per property, ready for a spreadsheet, a valuation model or a CRM.

Every row carries **97 fields** with full details on, or 39 in the faster card-only mode. A search page brings 30 listings in one request and each listing page adds the full record in one more, so a five-listing run in the cloud finished in 8 seconds. Prices come back as clean numbers in EUR next to the label Immoweb shows, `pricePerSqm` is computed from price and living area, and the energy score, construction year and building condition arrive as plain values you can filter on.

| 🎯 Target Audience | 💡 Primary Use Cases |
|---|---|
| Property investors and buyers | Screen a whole city by price per square metre, EPC score and construction year in one export. |
| Valuation analysts and appraisers | Build comparable datasets with exact surfaces, cadastral income and coordinates. |
| Estate agencies and lead-gen teams | Track competitors' new listings and price drops, and reach the agencies and private sellers behind them. |
| PropTech and data teams | Feed a Belgian property database from any search, on a schedule, with a fixed schema. |

### 📋 What the Immoweb Scraper does

> 💡 **Why it matters:** the listing page on Immoweb holds far more than the search card: the energy score and consumption, the construction year and building condition, the number of bathrooms and toilets, garden and terrace surfaces with their orientation, parking spaces, heating type, flood zone, cadastral income, VAT status, the agency's contact details and the complete photo set. This Actor puts all of that on one row per listing and pulls those rows for a whole search in one run.

- 🔗 **Any Immoweb search URL.** Apply your filters on immoweb.be, copy the URL and paste it. Property type, for sale or for rent, city or postal codes, price range, bedrooms, surface and sort order are all honoured because Immoweb applies them itself. English, French and Dutch URLs all work.
- 🏢 **Listing URLs too.** Paste one or more listing pages and get the same 97-field row for each. Mix searches and listings in one run.
- 💶 **Prices as data.** `price` as a number in EUR, `priceDisplay` as Immoweb shows it (`€239,000`, `€1,050 (+ €40)`), `pricePerSqm` computed per listing, the previous price after a drop, and the price range for new-build projects.
- 📍 **Full address.** Street, number, box, floor, locality, postal code, district, province, region and coordinates whenever the seller publishes them.
- ⚡ **Energy and building.** EPC score, primary energy consumption per m², EPC reference, renovation obligation, heating type, double glazing, heat pump, solar panels, construction year, condition, facades and floors.
- 🌿 **Outdoor and comfort.** Garden and terrace with surface and orientation, balcony, swimming pool, attic, basement, lift, indoor and outdoor parking, kitchen type and surface, living-room surface, furnished, pets allowed on rentals.
- 🏛 **Legal and cost lines.** Cadastral income, VAT status, monthly charges, flood-zone type and availability date.
- 📞 **The seller on every row.** Agency or private seller, name, phone, mobile, email, website, IPI licence number and logo.
- 📸 **All the photos.** Every listing photo at 2560 px, plus the virtual-tour and video links when the listing has them.
- 📅 **Real dates and engagement.** Publication and last-modified timestamps in ISO 8601, plus the listing's view and bookmark counts.
- 🏗 **New-build projects.** Project name, percentage sold, bedroom and surface ranges, and the price range across units.
- ⚡ **Card-only mode.** Switch full details off to export just the search cards, 30 listings per request, when price, location, surface and bedrooms are enough.
- 📦 **One fixed schema.** Columns never move, so your spreadsheet or database mapping never breaks.

### 🎬 Full Demo (🚧 Coming soon)

A short walkthrough video is in production and will land here.

### 📊 Output

One row per listing, 97 fields, always in this order. With full details off the row stops after `lastModifiedAt` and carries 39 fields.

| Field | Type | Description |
|---|---|---|
| 🖼 `imageUrl` | string | Main listing photo. |
| 📌 `title` | string | Readable label, e.g. `Apartment for sale in Liège (4000)`. |
| 🔗 `url` | string | The listing page. |
| 🆔 `id` | number | Immoweb listing ID. |
| 🔁 `transactionType` | string | `FOR_SALE` or `FOR_RENT`. |
| 🏠 `propertyType` | string | `HOUSE`, `APARTMENT`, `APARTMENT_GROUP`, `GARAGE`, `OFFICE`, `LAND` and the other Immoweb types. |
| 🏡 `propertySubtype` | string | `VILLA`, `DUPLEX`, `PENTHOUSE`, `GROUND_FLOOR`, `FLAT_STUDIO`, `TOWN_HOUSE` and more. |
| 🏷 `listingFlag` | string | Immoweb's card flag, e.g. `new`. |
| 💶 `price` | number | Asking price or monthly rent in EUR. |
| 💱 `currency` | string | Always `EUR`. |
| 💬 `priceDisplay` | string | The price exactly as Immoweb shows it, charges included for rentals. |
| 🧾 `priceType` | string | `residential_sale`, `residential_monthly_rent`, `group_sale` and similar. |
| 📉 `oldPrice` | number | Previous price after a price change. |
| 🔽 `priceMin` | number | Lowest unit price in a new-build project. `N/A` for single listings. |
| 🔼 `priceMax` | number | Highest unit price in a new-build project. `N/A` for single listings. |
| 📐 `pricePerSqm` | number | Price divided by living area, rounded to the euro. |
| 🏗 `projectName` | string | New-build project name. `N/A` for single listings. |
| 📊 `projectSoldPercent` | number | Share of project units already sold. |
| 🛏 `projectBedroomRange` | string | Bedroom range across the project's units. |
| 📏 `projectSurfaceRange` | string | Surface range across the project's units. |
| 📍 `locality` | string | Municipality as written on the listing. |
| 📮 `postalCode` | string | Belgian postal code. |
| 🗺 `district` | string | Arrondissement. |
| 🗺 `province` | string | Province. |
| 🌍 `region` | string | Flanders, Wallonia or Brussels. |
| 🇧🇪 `country` | string | Country. |
| 🛣 `street` | string | Street name. |
| 🔢 `streetNumber` | string | House number. |
| 📦 `box` | string | Box or unit number. |
| 🏢 `floor` | number | Floor of the unit. |
| 🧭 `latitude` | number | Latitude. |
| 🧭 `longitude` | number | Longitude. |
| 🛏 `bedroomCount` | number | Bedrooms. |
| 🚪 `roomCount` | number | Rooms, where Immoweb publishes it. |
| 📏 `netHabitableSurface` | number | Living area in m². |
| 🌳 `landSurface` | number | Plot area in m². |
| 🏢 `agencyName` | string | Agency or seller name. |
| 🖼 `agencyLogoUrl` | string | Agency logo. |
| 🎥 `hasVirtualTour` | string | `Yes` when a virtual tour is attached. |
| 🎬 `hasVideo` | string | `Yes` when a video is attached. |
| 🔄 `lastModifiedAt` | string | Last update of the listing, ISO 8601. |
| 🔖 `externalReference` | string | The agency's own reference. |
| 📄 `transactionSubtype` | string | `BUY_REGULAR`, `RENT_REGULAR` and the other Immoweb subtypes. |
| 💸 `monthlyCharges` | number | Monthly charges in EUR. |
| 🏛 `cadastralIncome` | number | Cadastral income in EUR. Sales only. |
| 🧾 `isSubjectToVat` | string | `Yes` when the sale is subject to VAT. |
| 🛁 `bathroomCount` | number | Bathrooms. |
| 🚿 `showerRoomCount` | number | Shower rooms. |
| 🚽 `toiletCount` | number | Toilets. |
| 🛋 `livingRoomSurface` | number | Living-room area in m². |
| 🍳 `kitchenType` | string | `Installed`, `Hyper equipped`, `Semi equipped` and similar. |
| 🍳 `kitchenSurface` | number | Kitchen area in m². |
| 🏗 `constructionYear` | number | Year built. |
| 🔧 `buildingCondition` | string | `Good`, `As new`, `To renovate`, `Just renovated` and similar. |
| 🧱 `facadeCount` | number | Number of facades. |
| 🏢 `floorCount` | number | Floors in the building. |
| 🛗 `hasLift` | string | `Yes` or `No`. |
| 🏚 `hasAttic` | string | `Yes` or `No`. |
| 🕳 `hasBasement` | string | `Yes` or `No`. |
| 🌿 `hasGarden` | string | `Yes` or `No`. |
| 🌿 `gardenSurface` | number | Garden area in m². |
| 🧭 `gardenOrientation` | string | Garden orientation. |
| ☀️ `hasTerrace` | string | `Yes` or `No`. |
| ☀️ `terraceSurface` | number | Terrace area in m². |
| 🧭 `terraceOrientation` | string | Terrace orientation. |
| 🪟 `hasBalcony` | string | `Yes` or `No`. |
| 🏊 `hasSwimmingPool` | string | `Yes` or `No`. |
| 🚗 `parkingIndoor` | number | Indoor parking spaces. |
| 🚗 `parkingOutdoor` | number | Outdoor parking spaces. |
| 🛋 `isFurnished` | string | `Yes` or `No`. |
| 🐾 `petsAllowed` | string | `Yes` or `No` on rentals, `N/A` on sales. |
| 🔥 `heatingType` | string | `Gas`, `Electric`, `Pellet`, `Fueloil`, `Heat pump` and similar. |
| 🪟 `hasDoubleGlazing` | string | `Yes` or `No`. |
| ♨️ `hasHeatPump` | string | `Yes` or `No`. |
| ☀️ `hasSolarPanels` | string | `Yes` or `No`. |
| ⚡ `epcScore` | string | EPC label, `A+` to `G`. |
| ⚡ `primaryEnergyConsumptionPerSqm` | number | Primary energy consumption in kWh/m²/year. |
| 🔖 `epcReference` | string | EPC certificate reference. |
| 🛠 `renovationObligation` | string | `Yes` when a Flemish renovation obligation applies. |
| 🌊 `floodZoneType` | string | `Non flood zone`, `Possible flood zone` and similar. |
| 📅 `availabilityDate` | string | When the property becomes available. |
| 🏢 `agencyType` | string | `Agency`, `Private seller`, `Notary` or `Developer`. |
| 📞 `agencyPhone` | string | Agency landline. |
| 📱 `agencyMobile` | string | Agency mobile. |
| ✉️ `agencyEmail` | string | Agency email. |
| 🌐 `agencyWebsite` | string | Agency website. |
| 🪪 `agencyIpiNumber` | string | The agency's IPI licence number. |
| 📝 `description` | string | Full listing description. |
| 📅 `publishedAt` | string | When the listing was published, ISO 8601. |
| 👁 `viewCount` | number | Views Immoweb reports for the listing. |
| 🔖 `bookmarkCount` | number | Times the listing was saved by visitors. |
| 🎥 `virtualTourUrl` | string | Virtual-tour link. |
| 🎬 `videoUrl` | string | Video link. |
| 🖼 `imageCount` | number | Number of photos. |
| 🖼 `imageUrls` | array | Every photo URL at 2560 px. |
| 🕒 `scrapedAt` | string | When this row was collected. |
| ❌ `error` | string or null | Error message for rows that could not be collected, otherwise `null`. |

#### Sample records

```json
{
  "imageUrl": "https://media-resize.immowebstatic.be/classifieds/5eaf4184-94df-4cae-b54c-f64164e198ae/736x736/47c76e4e6ea6813963b872db8834eee3.jpg",
  "title": "Apartment for sale in Liège (4000)",
  "url": "https://www.immoweb.be/en/classified/apartment/for-sale/liege/4000/21821712",
  "id": 21821712,
  "transactionType": "FOR_SALE",
  "propertyType": "APARTMENT",
  "propertySubtype": "APARTMENT",
  "listingFlag": "new",
  "price": 179000,
  "currency": "EUR",
  "priceDisplay": "€179,000",
  "priceType": "residential_sale",
  "pricePerSqm": 3140,
  "locality": "Liège",
  "postalCode": "4000",
  "district": "Liège",
  "province": "Liège",
  "region": "Wallonie",
  "country": "Belgium",
  "street": "Rue Hors-Château",
  "streetNumber": "54",
  "floor": 0,
  "latitude": 50.64700310000001,
  "longitude": 5.5787361,
  "bedroomCount": 1,
  "netHabitableSurface": 57,
  "agencyName": "JNP Immobilier",
  "lastModifiedAt": "2026-09-07T14:50:17.247Z",
  "externalReference": "7737211",
  "transactionSubtype": "BUY_REGULAR",
  "isSubjectToVat": "No",
  "bathroomCount": 1,
  "showerRoomCount": 1,
  "toiletCount": 1,
  "livingRoomSurface": 18,
  "kitchenType": "Installed",
  "kitchenSurface": 6,
  "constructionYear": 1932,
  "buildingCondition": "Good",
  "floorCount": 3,
  "hasLift": "No",
  "hasBasement": "Yes",
  "hasTerrace": "Yes",
  "terraceOrientation": "South",
  "hasSwimmingPool": "No",
  "isFurnished": "No",
  "hasDoubleGlazing": "Yes",
  "epcScore": "C",
  "primaryEnergyConsumptionPerSqm": 200,
  "epcReference": "20250507030936",
  "floodZoneType": "Non flood zone",
  "agencyType": "Agency",
  "agencyMobile": "+3243773310",
  "agencyIpiNumber": "512594",
  "publishedAt": "2026-09-07T14:49:26.895Z",
  "imageCount": 20,
  "imageUrls": [
    "https://media-resize.immowebstatic.be/classifieds/5eaf4184-94df-4cae-b54c-f64164e198ae/2560x1440/47c76e4e6ea6813963b872db8834eee3.jpg",
    "https://media-resize.immowebstatic.be/classifieds/5eaf4184-94df-4cae-b54c-f64164e198ae/2560x1440/f6d5ea0e1fe4cc9e9aad87aa051e2a57.jpg"
  ],
  "scrapedAt": "2026-09-07T14:51:16.136Z",
  "error": null
}
```

```json
{
  "imageUrl": "https://media-resize.immowebstatic.be/classifieds/8eada6d7-01e5-4c8f-a49a-91d9619b3d57/736x736/cc6d4696f9de79dd61428dc0b3d77193.jpg",
  "title": "House for sale in Oisquercq (1480)",
  "url": "https://www.immoweb.be/en/classified/house/for-sale/oisquercq/1480/21821711",
  "id": 21821711,
  "transactionType": "FOR_SALE",
  "propertyType": "HOUSE",
  "propertySubtype": "HOUSE",
  "listingFlag": "new",
  "price": 350000,
  "currency": "EUR",
  "priceDisplay": "€350,000",
  "pricePerSqm": 1842,
  "locality": "OISQUERCQ",
  "postalCode": "1480",
  "district": "Nivelles",
  "province": "Walloon Brabant",
  "region": "Wallonie",
  "country": "Belgium",
  "bedroomCount": 5,
  "netHabitableSurface": 190,
  "landSurface": 278,
  "agencyName": "Trevi Conseil Immo",
  "hasVirtualTour": "Yes",
  "externalReference": "7908 - 7501",
  "cadastralIncome": 391,
  "isSubjectToVat": "No",
  "bathroomCount": 1,
  "toiletCount": 2,
  "livingRoomSurface": 18,
  "kitchenType": "Installed",
  "constructionYear": 1940,
  "buildingCondition": "Good",
  "facadeCount": 3,
  "floorCount": 3,
  "hasLift": "No",
  "hasAttic": "Yes",
  "hasBasement": "Yes",
  "hasGarden": "Yes",
  "gardenSurface": 200,
  "hasTerrace": "Yes",
  "terraceSurface": 15,
  "parkingOutdoor": 1,
  "heatingType": "Pellet",
  "hasDoubleGlazing": "Yes",
  "hasHeatPump": "No",
  "epcScore": "D",
  "primaryEnergyConsumptionPerSqm": 297,
  "epcReference": "20260815010373",
  "floodZoneType": "Non flood zone",
  "agencyType": "Agency",
  "agencyPhone": "+3223555055",
  "agencyEmail": "trevi-conseilimmo@omniwebsites.be",
  "agencyWebsite": "http://www.treviconseil.be",
  "agencyIpiNumber": "506457",
  "description": "Oisquercq, dans une jolie rue résidentielle appréciée pour son excellente situation au calme et à seulement 7 minutes de...",
  "publishedAt": "2026-09-07T14:49:21.860Z",
  "virtualTourUrl": "https://nodalview.com/s/0jH0qm7yTFuOOinLeZj1xn",
  "imageCount": 30,
  "scrapedAt": "2026-09-07T14:51:16.160Z",
  "error": null
}
```

```json
{
  "imageUrl": "https://media-resize.immowebstatic.be/classifieds/e7db3f85-456a-406e-9b24-c04c5d7e2aa6/736x736/f7415904c1bc24d33714d97f975f88df.jpg",
  "title": "House for sale in Orp-Jauche (1350)",
  "url": "https://www.immoweb.be/en/classified/house/for-sale/orp-jauche/1350/21359179",
  "id": 21359179,
  "transactionType": "FOR_SALE",
  "propertyType": "HOUSE",
  "price": 445000,
  "currency": "EUR",
  "priceDisplay": "€445,000",
  "pricePerSqm": 2225,
  "locality": "Orp-Jauche",
  "postalCode": "1350",
  "district": "Nivelles",
  "province": "Walloon Brabant",
  "region": "Wallonie",
  "street": "Avenue Rodolphe Gossia",
  "streetNumber": "2",
  "latitude": 50.67968940000001,
  "longitude": 4.9600507,
  "bedroomCount": 4,
  "netHabitableSurface": 200,
  "landSurface": 436,
  "agencyName": "SRL Immobilière du Val",
  "externalReference": "Maison 2",
  "isSubjectToVat": "Yes",
  "bathroomCount": 1,
  "showerRoomCount": 1,
  "toiletCount": 2,
  "livingRoomSurface": 30,
  "kitchenType": "Hyper equipped",
  "kitchenSurface": 10,
  "constructionYear": 2026,
  "facadeCount": 3,
  "floorCount": 2,
  "hasGarden": "Yes",
  "gardenSurface": 186,
  "gardenOrientation": "South west",
  "hasTerrace": "Yes",
  "terraceSurface": 22,
  "terraceOrientation": "South west",
  "parkingIndoor": 1,
  "parkingOutdoor": 1,
  "heatingType": "Electric",
  "hasDoubleGlazing": "Yes",
  "hasHeatPump": "Yes",
  "hasSolarPanels": "No",
  "epcScore": "A+",
  "floodZoneType": "Non flood zone",
  "agencyType": "Agency",
  "agencyMobile": "+32485940993",
  "agencyIpiNumber": "502531",
  "publishedAt": "2026-09-07T14:49:46.936Z",
  "viewCount": 571,
  "bookmarkCount": 5,
  "imageCount": 5,
  "scrapedAt": "2026-09-07T14:51:16.203Z",
  "error": null
}
```

### ✨ Why choose this Actor

- **Every Immoweb filter, applied by Immoweb.** The search URL you paste carries the property type, transaction, location, price, bedrooms, surface and sort order, and Immoweb's own search applies them, so an export costs exactly the rows that match.
- **The full listing, not the card.** 97 fields per row, including 58 that only exist on the listing page: EPC and consumption, construction year and condition, bathrooms, garden and terrace with orientation, parking, heating, flood zone, cadastral income, the seller's contact details and the whole photo set.
- **Prices you can sort on.** A numeric `price` in EUR, the label Immoweb shows, the previous price after a drop, the project price range, and `pricePerSqm` computed on every row with a known living area.
- **The seller is a lead, not a name.** Agency or private seller, phone, mobile, email, website and IPI licence number.
- **Real timestamps.** Publication and last-modified times as ISO 8601, so a scheduled run can tell a new listing from a refreshed one.
- **Three languages, one schema.** English, French and Dutch search and listing URLs are all accepted and return the same columns.
- **Honest about its limits.** The comparison below states the 333-page ceiling Immoweb puts on a single search before you spend anything.
- **No nulls.** Identical columns on every row, with `Not Disclosed` and `N/A` sentinels instead of blanks so CSV and Excel imports stay predictable.
- **No credentials and no start fee.** No Immoweb login, no cookie, no token, and you pay per row only.
- **Fast and light.** Plain HTTP requests through residential proxies, no browser. Five listings with full details in 8 seconds in the cloud.

### 📈 How it compares to alternatives

| | This Actor | Typical Immoweb scrapers |
|---|---|---|
| Fields per listing | 97, with energy, building, outdoor, legal, seller contact and photos | 15 to 40 |
| Input | Any search URL in EN, FR or NL, plus listing URLs, mixed in one run | Search URL only, or listing URLs only |
| Price data | Number, label, previous price, project range and EUR per m² | One price value |
| Seller | Agency or private, phone, mobile, email, website, IPI number | Name only, or none |
| New-build projects | Project name, share sold, bedroom, surface and price ranges | Treated as a single listing |
| Card-only mode | Yes, 39 fields at one request per 30 listings | Rarely |
| Login or cookie required | No | No |
| Start fee per run | None | Sometimes |
| Listings per search URL | **Up to 9,990.** See the ceiling below | Same ceiling, often unstated |

**The ceiling, stated plainly.** Immoweb serves at most 333 pages of 30 listings for any one search, and its own counter stops at 9,969. The Actor logs the total Immoweb reports for each search so you know your coverage, and it stops cleanly at the last page. To go wider, split the search by postal code, province, property type or price band and pass several URLs in one run.

### 🚀 How to use

1. **Create a free Apify account.** New accounts get $5 in free credit. [Sign up here](https://console.apify.com/sign-up?fpr=vmoqkp).
2. **Open the Actor** and go to the Input tab.
3. **Build your search on immoweb.be.** Pick for sale or for rent, the property type, the city or postal codes, the price range and the sort order, then copy the URL from your browser.
4. **Paste the URL** into the search URLs field. Add more URLs or individual listing pages if you want them in the same run.
5. **Set Max Items** to the number of listings you want back across all URLs.
6. **Decide on detail.** Leave full details on for the 97-field row, or switch it off for a fast card-only export.
7. **Click Start** and watch the log. It reports the total Immoweb found for each search and names every listing as it lands.
8. **Download your data** from the Storage tab as CSV, JSON, Excel or XML, or pull it from the API.

Example input:

```json
{
  "startUrls": [
    { "url": "https://www.immoweb.be/en/search/apartment/for-sale/brussels/1000?countries=BE&minPrice=200000&maxPrice=400000&minBedroomCount=2&orderBy=newest" },
    { "url": "https://www.immoweb.be/en/classified/apartment/for-sale/berchem/2600/21819341" }
  ],
  "maxItems": 500,
  "includeDetails": true
}
```

### 💼 Business use cases

**📊 Screening a city for investment.**

An investor pastes a search for apartments for sale in Antwerp under 300,000 EUR with 500 items. The sheet sorts by `pricePerSqm`, filters `epcScore` to C or better and `constructionYear` after 2000, and keeps the rows with a terrace and indoor parking. The `agencyPhone` column turns the shortlist into a call list.

**🏛 Comparable sales for a valuation.**

An appraiser exports every house for sale in a postal code with full details. `netHabitableSurface`, `landSurface`, `cadastralIncome`, `buildingCondition` and the coordinates feed a comparables table, and `publishedAt` shows how long each one has been on the market.

**📈 Competitor and price-drop tracking.**

An agency schedules the Actor daily over its own markets. Diffing `price` against the previous run, together with `oldPrice` and `lastModifiedAt`, surfaces price drops and new instructions the morning they appear, with the listing agency on the same row.

**🏗 New-build market mapping.**

A developer exports all new-build apartment projects in Flanders. `projectName`, `projectSoldPercent`, `priceMin`, `priceMax` and `projectSurfaceRange` give a picture of what competing projects charge and how fast they sell.

### 🔌 Automating Immoweb Scraper

Schedule the Actor and route the results wherever your team already works.

- **Make and Zapier.** Trigger on a finished run and push new listings into a CRM, a Notion database or an Airtable base.
- **Slack.** Post listings under a price-per-square-metre threshold into a deals channel.
- **Airbyte.** Load the dataset into a warehouse and track asking prices by postal code over time.
- **GitHub.** Commit a weekly snapshot to a repository to keep an auditable history of a market.
- **Google Drive.** Drop each run's CSV into a shared folder for the rest of the team.
- **Apify Schedules.** Run the same search daily or weekly without touching the console.

### 🌟 Beyond business use cases

**🔬 Research.** Economists and urban planners can study asking prices, energy performance and building age across Belgian municipalities with real listing-level data.

**🙋 Personal.** House hunters can export every listing that matches their search, compare price per square metre, EPC and garden size side by side, and spot new listings the day they appear.

**🤝 Non-profit.** Housing organisations can map rental prices and energy scores by neighbourhood to support affordability and renovation programmes.

**🧪 Experimentation.** Prices, surfaces, coordinates, energy scores and construction years make a tidy dataset for hedonic pricing models, geospatial analysis and clustering experiments.

### 🤖 Ask an AI assistant about this scraper

The Actor exposes its input schema through Apify's MCP server, so an AI assistant connected to your Apify account can configure and run it for you. Ask it "get me every house for sale in Ghent under 400,000 EUR with an EPC of B or better" and it will build the search URL, set the item count and filter the rows itself.

### ❓ Frequently Asked Questions

**🔑 Do I need an Immoweb account, cookie or API key?**

No. The Actor reads the data Immoweb publishes to any visitor of its search and listing pages. There is no login and no token to manage.

**🔗 Which URLs does it accept?**

Any Immoweb search results URL, in English, French or Dutch, with any filters applied, and any Immoweb listing page. You can mix both in one run. Copy URLs from your browser rather than typing them: an unrecognised path segment makes Immoweb fall back to its default search.

**🔍 How does the search work?**

The Actor calls the same search endpoint that Immoweb's own results page loads, 30 listings per page, with your filters passed through untouched, and then opens each listing page for the full record.

**📏 How many listings can one search return?**

Immoweb serves at most 333 pages of 30 listings per search, about 9,990, and its counter stops at 9,969. The log states the total for each search. Split a large search by postal code, province, type or price band and pass several URLs to cover more.

**💶 How is the price reported?**

`price` is the number in EUR, `priceDisplay` is the label Immoweb shows including any rental charges, `oldPrice` holds the previous price after a change, and `pricePerSqm` is `price` divided by `netHabitableSurface`. New-build projects report `priceMin` and `priceMax` instead of a single price.

**🏗 How are new-build projects handled?**

A project row carries the project name, the share of units sold, the bedroom and surface ranges and the price range. Unit-level fields such as bathrooms or terrace are `Not Disclosed` on a project row because Immoweb publishes them per unit, not per project.

**📞 Does it return the agency's contact details?**

Yes. `agencyName`, `agencyType`, `agencyPhone`, `agencyMobile`, `agencyEmail`, `agencyWebsite` and `agencyIpiNumber` come from the listing page whenever the seller publishes them. Private sellers show `Private seller` and usually no phone.

**⚡ How fast is it?**

Five listings with full details finished in 8 seconds in the cloud. Search pages bring 30 listings per request, and listing pages are fetched five at a time.

**🈳 Why do I see `Not Disclosed` or `N/A` instead of empty cells?**

Because a blank cell is ambiguous. `Not Disclosed` means the seller did not publish that value for that listing, and `N/A` means the field does not apply, such as `petsAllowed` on a sale or `projectName` on a single apartment.

**🛡 Do I need a proxy?**

Yes, and it is on by default. Immoweb blocks datacenter IP ranges, so the Actor uses Apify residential proxies. Leave the proxy setting as it is.

**🌐 Which language will the data be in?**

Field values such as `propertyType` and `epcScore` are language-independent. `title` follows the language of the URL you paste, and `description` is whatever the seller wrote, with Immoweb's own note when no translation exists.

**🔄 Can I run it on a schedule?**

Yes. Save your input as a task, schedule it in Apify, and diff `price`, `lastModifiedAt` and the set of `id` values between runs to track new listings and price drops.

### 🔌 Integrate with any app

Every run's dataset is available through the Apify API, so you can pull results into any language or platform that speaks HTTP. Apify also ships official clients for JavaScript and Python, plus native integrations for Make, Zapier, Airbyte, Slack, GitHub and Google Drive.

### 🔗 Recommended Actors

- [Immowelt Property Listings Scraper](https://apify.com/parseforge/immowelt-scraper?fpr=vmoqkp) - German property listings with the same flat-row approach.
- [SeLoger.com French Real Estate Scraper](https://apify.com/parseforge/seloger-scraper?fpr=vmoqkp) - French listings for cross-border comparisons.
- [Bien Ici French Real Estate Scraper](https://apify.com/parseforge/bienici-real-estate-scraper?fpr=vmoqkp) - another French portal with energy ratings.
- [Zoopla UK Property Listings Scraper](https://apify.com/parseforge/zoopla-scraper?fpr=vmoqkp) - UK listings with price history.
- [idealista Scraper](https://apify.com/parseforge/idealista-scraper?fpr=vmoqkp) - Spain, Italy and Portugal listings.

> 💡 **Pro Tip:** browse the complete [ParseForge collection](https://apify.com/parseforge?fpr=vmoqkp).

**🆘 Need Help?** [Open our contact form](https://tally.so/r/BzdKgA)

> **⚠️ Disclaimer:** This is an independent tool, not affiliated with or endorsed by Immoweb. It collects only publicly available data.

# Actor input Schema

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

One or more Immoweb search result URLs, copied from your browser with every filter already applied (property type, for sale or for rent, city or postal codes, price range, bedrooms, sort order). English, French and Dutch URLs all work. Each URL yields up to 9,990 listings (333 pages of 30), so split large searches by postal code or price band.

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

Free users: Limited to 10 items (preview). Paid users: Optional, max 1,000,000

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

On (default): one extra request per listing to collect 40+ additional fields (EPC, construction year, bathrooms, garden, terrace, agency contact, all photos). Off: faster and lighter, search-card fields only.

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

Keep Apify residential proxies enabled. Datacenter proxies and the automatic proxy group are blocked by Immoweb.

## Actor input object example

```json
{
  "startUrls": [
    {
      "url": "https://www.immoweb.be/en/search/house-and-apartment/for-sale?countries=BE&orderBy=newest"
    }
  ],
  "maxItems": 10,
  "includeDetails": true,
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "RESIDENTIAL"
    ]
  }
}
```

# Actor output Schema

## `overview` (type: `string`):

Key identity, price, location, size and energy fields

## `fullData` (type: `string`):

Complete dataset with all 97 fields, including building, garden, terrace, parking, energy, flood zone, agency contact, description and every photo URL

# 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.immoweb.be/en/search/house-and-apartment/for-sale?countries=BE&orderBy=newest"
        }
    ],
    "maxItems": 10,
    "proxyConfiguration": {
        "useApifyProxy": true,
        "apifyProxyGroups": [
            "RESIDENTIAL"
        ]
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("parseforge/immoweb-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.immoweb.be/en/search/house-and-apartment/for-sale?countries=BE&orderBy=newest" }],
    "maxItems": 10,
    "proxyConfiguration": {
        "useApifyProxy": True,
        "apifyProxyGroups": ["RESIDENTIAL"],
    },
}

# Run the Actor and wait for it to finish
run = client.actor("parseforge/immoweb-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.immoweb.be/en/search/house-and-apartment/for-sale?countries=BE&orderBy=newest"
    }
  ],
  "maxItems": 10,
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "RESIDENTIAL"
    ]
  }
}' |
apify call parseforge/immoweb-scraper --silent --output-dataset

```

## MCP server setup

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