# Immoweb Scraper - Belgium Property Listings & Prices (`sian.agency/immoweb-be-property-scraper`) Actor

Scrape Immoweb.be listings across Belgium: price, EPC label, surface, bedrooms, GPS, photos and agency contacts. Sale and rental, every property type.

- **URL**: https://apify.com/sian.agency/immoweb-be-property-scraper.md
- **Developed by:** [SIÁN OÜ](https://apify.com/sian.agency) (community)
- **Categories:** Real estate, Lead generation, Business
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $0.97 / 1,000 property searches

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

## Immoweb Scraper — Belgium Property Listings, Prices & EPC 🏠

[![SIÁN Agency Store](https://img.shields.io/badge/Store-SI%C3%81N%20Agency-1AE392)](https://apify.com/sian.agency?fpr=sian) [![Funda.nl Scraper](https://img.shields.io/badge/Store-Funda.nl%20Scraper-FF6200)](https://apify.com/sian.agency/funda-property-scraper?fpr=sian) [![SeLoger Scraper](https://img.shields.io/badge/Store-SeLoger%20Scraper-E2001A)](https://apify.com/sian.agency/seloger-property-scraper?fpr=sian) [![Apartments.com Property Scraper](https://img.shields.io/badge/Store-Apartments.com-1AE392)](https://apify.com/sian.agency/apartments-com-property-scraper?fpr=sian)

#### 🇧🇪 Every Belgian listing, with the EPC label and the agency phone number attached

##### Houses, apartments, land and commercial property from immoweb.be — for sale and for rent, as clean rows

Immoweb carries roughly 48,000 houses for sale and 12,000 apartments for rent at any moment, and its search page shows you thirty of them at a time. This Immoweb scraper takes a location — typed the way you say it, `Brussels` or `Ghent` or `1000` — and returns every matching listing as structured data: asking price, living area, plot size, bedrooms, street, GPS coordinates, photos and the publishing agency. Switch on full details and every row also carries the EPC label with its kWh/m²/year, the cadastral income, construction year, flood-zone status and the agency's phone, email and IPI number.

Built for market analysis, renovation sourcing, agency lead generation and new-listing monitoring. Test it with 25 listings free: no credit card, no API key, no login.

### 🔎 What is the Immoweb Belgium Property Scraper — and when should you use it?

The **Immoweb Belgium Property Scraper** turns public Immoweb.be property listings from anywhere in Belgium into clean, structured rows you can filter, export and feed straight into a spreadsheet, database or AI agent. No account, no portal API key, no browser automation to maintain.

**Use it when you need:** Belgian sale and rental listings as rows: asking price or monthly rent, living area, plot size, bedrooms, locality, street, GPS coordinates, photos, the publishing agency and the direct listing URL. Switch on full details and each row also carries the agent's description, the EPC label with its kWh/m²/year, the cadastral income, construction year, condition, flood-zone status and the agency's phone, email and IPI registration number.

**Use something else when:** the property is not in Belgium. Use [Funda.nl Scraper](https://apify.com/sian.agency/funda-property-scraper?fpr=sian) for the Dutch market next door, with its own price-per-m² and agent data. Use [SeLoger Scraper](https://apify.com/sian.agency/seloger-property-scraper?fpr=sian) for France, including the Ardennes and Lille border markets Belgian buyers also shop. Use [Apartments.com Property Scraper](https://apify.com/sian.agency/apartments-com-property-scraper?fpr=sian) for US managed rentals with floor plans and amenity data. This actor covers the public listing sections of immoweb.be. Sold and withdrawn history is out of scope because the site publishes only what is currently on the market, and private-seller contact runs through Immoweb's own form, so the contact block is the publishing agency's rather than a homeowner's.

### 🤖 Use with AI agents

Already connected to the [Apify MCP server](https://mcp.apify.com)? Just ask for this Actor by name: sian.agency/immoweb-be-property-scraper

**Your agent can pay for its own runs.** This Actor is eligible for [agentic payments](https://docs.apify.com/platform/actors/publishing/monetize), so an agent can discover it, run it and settle the bill over [x402](https://www.x402.org/) (USDC on Base) or [Skyfire](https://www.skyfire.xyz/) — without an Apify account or API token of its own. Billing is the same either way: per successful row, never for errors.

Otherwise copy this prompt into Claude, ChatGPT, Cursor or any MCP-enabled assistant:

```text
I want property listings and prices from Immoweb.be using the Apify Actor `sian.agency/immoweb-be-property-scraper`.

Use it when I need: Belgian sale and rental listings as rows: asking price or monthly rent, living area, plot size, bedrooms, locality, street, GPS coordinates, photos, the publishing agency and the direct listing URL. Switch on full details and each row also carries the agent's description, the EPC label with its kWh/m²/year, the cadastral income, construction year, condition, flood-zone status and the agency's phone, email and IPI registration number.

Don't use it when: the property is not in Belgium — use funda-property-scraper or seloger-property-scraper or apartments-com-property-scraper instead.

How to call it: give `locations` a list of Belgian place names or 4-digit postal codes (`Brussels`, `Ghent`, `1000`) — they are resolved against Immoweb's own location index, so you do not need its internal codes — plus a `propertyType` and `transactionType`. Narrow with `minPrice`, `maxPrice`, `minBedroomCount`, `minSurface`, `minLandSurface`, `epcScores`, `buildingCondition`, `hasGarden`, `hasTerrace`, `hasSwimmingPool` or `isNewlyBuilt`. `includeDetails` adds the description, EPC certificate, cadastral income and agency contact for an extra charge per listing. To expand listings you already have, set `operation` to `detail` and pass `listingUrls`; to reuse a search you built on immoweb.be, paste it into `searchUrls`.

Start with this input:
{
  "locations": [
    "Brussels"
  ],
  "propertyType": "house",
  "transactionType": "for-sale",
  "maxResults": 100
}

Ask me which Belgian cities or postal codes to cover, whether they want sale or rental listings, and whether the EPC label and agency contact details are worth the extra per-listing charge, then run the Actor and summarise the results as a table.
```

**Things you can ask your agent for:**

- *Pull every house for sale in Ghent and Antwerp under €400,000 and rank them by price per square metre.*
- *Find EPC E, F and G apartments in Brussels marked to renovate, with the cadastral income and construction year.*
- *Give me this week's new rental listings in postal codes 1000, 1030 and 1180 with the agency phone number.*

Machine-readable API, MCP config and OpenAPI definition for this Actor are published at [apify.com/sian.agency/immoweb-be-property-scraper.md](https://apify.com/sian.agency/immoweb-be-property-scraper.md).

### 📋 Overview

**Type a city, pick house or apartment, press Run.** This Immoweb scraper turns any Belgian property search into a spreadsheet, in about ten seconds.

**Why professionals choose this Immoweb scraper:**

- ✅ **All of Belgium in one run**: Flanders, Wallonia and Brussels, from a list of cities or postal codes
- 📍 **Locations by name**: type `Ghent`, `Liège` or `1000` — no internal district codes to look up
- ⚡ **30 listings per request**: a 100-row run finishes in about ten seconds and four requests
- 🔋 **EPC label on every enriched row**: score, kWh/m²/year, certificate reference and the Flemish renovation-obligation flag
- 📞 **Agency contact included**: name, phone, email, website and IPI/BIV registration number
- 💰 **From $1.10 per 1,000 listings**: pay per row delivered, never for a failed one
- 📸 **Photos and GPS on every row**: the full gallery in full size, plus exact coordinates
- 🆕 **Newest-first monitoring**: schedule it daily and pay only for what appeared since yesterday

### ✨ Features

- 🏠 **12 property sections**: houses, apartments, both together, villas, apartment blocks, building land, garages, offices, business premises, industrial buildings and new-build projects
- 🤝 **Sale and rental**: rental rows carry the monthly rent and the charges on top where the agency published them
- 📍 **Name, postal code or province**: each location is resolved against Immoweb's own index at run time
- 💵 **Price bands**: min and max, applied at the source so you are not billed for rows you filtered out
- 📐 **Size filters**: minimum living area, minimum plot size and minimum bedroom count
- 🔋 **EPC filter**: keep only the labels you want, A++ through G, or just the E/F/G renovation stock
- 🔨 **Condition filter**: as new, just renovated, good, to be done up, to renovate, to restore
- 🌿 **Amenity filters**: garden, terrace, swimming pool, new build
- 📄 **Full details on demand**: description, EPC certificate, cadastral income, construction year, flood zone and agency contact
- 🔗 **Paste-a-URL mode**: drop in any immoweb.be search URL and every filter in it is honoured
- 🗣️ **Three languages**: English, Dutch or French labels and price formatting
- 📊 **Export anywhere**: JSON, CSV, Excel, or straight into your own code via the API

### 🎬 Quick Start

Give it a location and a property type. No account, no API key, no proxy configuration. Press Run and the rows arrive.

```bash
curl -X POST https://api.apify.com/v2/acts/sian.agency~immoweb-be-property-scraper/runs?token=[YOUR_TOKEN] \
-d '{"locations": ["Brussels"], "propertyType": "house", "transactionType": "for-sale"}'
```

### 🚀 Getting Started (3 Simple Steps)

#### Step 1: Name your locations

Type Belgian place names or postal codes, one per line: `Brussels`, `Ghent`, `Antwerp`, `1000`, `9000`. Leave the list empty to take the whole country.

#### Step 2: Pick what you are looking for

Choose the property type (houses, apartments, land, offices…), sale or rent, then set your price band, minimum bedrooms or EPC label.

#### Step 3: Press Run

The first rows land in seconds. Download as CSV or JSON, or pull them straight from the API.

**That's it! In about ten seconds, you'll have:**

- Every matching listing with price, size, bedrooms, locality, GPS and photos
- Direct listing URLs that still resolve after the agency re-files the property
- A run report telling you what you got and exactly what it cost

### 📥 Input Configuration

| Field | Type | Required | Description |
|-------|------|----------|-------------|
| operation | string | No | `search` (listings by location) or `detail` (full data for listing URLs) |
| locations | array | No | Belgian place names or 4-digit postal codes. Empty means all of Belgium |
| propertyType | string | No | `house`, `apartment`, `house-and-apartment`, `villa`, `apartment-block`, `land`, `garage`, `office`, `business`, `industry`, `new-real-estate-project-houses`, `new-real-estate-project-apartments` |
| transactionType | string | No | `for-sale` or `for-rent` |
| maxResults | integer | No | Stop after this many listings across all locations (default 100) |
| sort | string | No | `newest`, `relevance`, `cheapest`, `most_expensive` or `postal_code` |
| language | string | No | `en`, `nl` or `fr`. Sets the label and price-text language |
| includeDetails | boolean | No | Add the description, EPC certificate, cadastral income and agency contact. Extra charge per listing |
| minPrice | integer | No | Cheapest listing to include, in euros. 0 means no lower bound |
| maxPrice | integer | No | Most expensive listing to include, in euros. 0 means no upper bound |
| minBedroomCount | integer | No | Minimum bedrooms. 0 means no minimum |
| minSurface | integer | No | Minimum net habitable surface in m². 0 means no minimum |
| minLandSurface | integer | No | Minimum plot size in m². 0 means no minimum |
| epcScores | array | No | Keep only these EPC labels: `A++`, `A+`, `A`, `B`, `C`, `D`, `E`, `F`, `G` |
| buildingCondition | string | No | `any`, `AS_NEW`, `JUST_RENOVATED`, `GOOD`, `TO_BE_DONE_UP`, `TO_RENOVATE`, `TO_RESTORE` |
| hasGarden | boolean | No | Skip listings with no garden |
| hasTerrace | boolean | No | Skip listings with no terrace |
| hasSwimmingPool | boolean | No | Skip listings with no swimming pool |
| isNewlyBuilt | boolean | No | Only newly built properties |
| searchUrls | array | No | immoweb.be search URLs. Every filter in the URL is honoured |
| listingUrls | array | No | Listing URLs or IDs to expand, for Property Detail mode |

**Example:**

```json
{
  "locations": ["Brussels"],
  "propertyType": "house",
  "transactionType": "for-sale",
  "maxResults": 100
}
```

**Multi-city market sweep:**

```json
{
  "locations": ["Ghent", "Antwerp", "Bruges", "Leuven"],
  "propertyType": "house-and-apartment",
  "transactionType": "for-sale",
  "minPrice": 200000,
  "maxPrice": 500000,
  "minBedroomCount": 3,
  "maxResults": 2000
}
```

**Renovation stock with full details:**

```json
{
  "locations": ["Liège", "Charleroi"],
  "propertyType": "house",
  "transactionType": "for-sale",
  "epcScores": ["E", "F", "G"],
  "buildingCondition": "TO_RENOVATE",
  "includeDetails": true,
  "maxResults": 500
}
```

**New rental listings by postal code, on a daily schedule:**

```json
{
  "locations": ["1000", "1030", "1180"],
  "propertyType": "apartment",
  "transactionType": "for-rent",
  "sort": "newest",
  "maxResults": 200
}
```

**Paste an Immoweb search URL:**

```json
{
  "searchUrls": ["https://www.immoweb.be/en/search/house/for-sale?provinces=ANTWERP&minPrice=300000&hasGarden=true"]
}
```

**Expand specific listings:**

```json
{
  "operation": "detail",
  "listingUrls": [
    "https://www.immoweb.be/en/classified/house/for-sale/oosterzele/9860/21798321",
    "21797010"
  ]
}
```

### 📤 Output

Every listing is one flat row, ready for Excel, a database or an AI agent.

| Field | Type | Description |
|-------|------|-------------|
| listingId | number | Immoweb listing ID |
| propertyTitle | string | Listing title as the agency wrote it |
| url | string | Direct listing URL |
| price | number | Asking price, or monthly rent for a rental |
| priceText | string | Price as Immoweb displays it, including rental charges |
| oldPrice | number | Previous price, when the listing has been reduced |
| transactionType | string | `FOR_SALE` or `FOR_RENT` |
| propertyType | string | `HOUSE`, `APARTMENT`, `LAND`, `OFFICE`… |
| propertySubtype | string | Immoweb's finer grade, e.g. `VILLA`, `GROUND_FLOOR`, `EXCEPTIONAL_PROPERTY` |
| bedroomCount | number | Bedrooms |
| netHabitableSurface | number | Living area in m² |
| landSurface | number | Plot size in m² |
| locality | string | Town or municipality |
| postalCode | string | Belgian postal code |
| street | string | Street name, where the agency published it |
| streetNumber | string | House number, where the agency published it |
| district | string | Immoweb district, e.g. `Gent` |
| province | string | Province, e.g. `East Flanders` |
| region | string | `Flanders`, `Wallonia` or `Brussels` |
| latitude | number | Latitude |
| longitude | number | Longitude |
| agencyName | string | Publishing agency |
| imageUrl | string | First photo |
| imageUrls | array | Every photo, full size |
| imageCount | number | Number of photos |
| listingFlag | string | Badge Immoweb shows: `new`, `under_option`, `price_drop`… |
| updatedAt | string | Last time the agency updated it (ISO 8601) |
| descriptionText | string | Full description, with Add full details on |
| epcScore | string | EPC label A++ to G, with Add full details on |
| epcConsumptionPerSqm | number | Primary energy consumption in kWh/m²/year |
| epcReference | string | EPC certificate reference |
| hasRenovationObligation | boolean | Whether the property carries a Flemish renovation obligation |
| cadastralIncome | number | Kadastraal inkomen / revenu cadastral, in euros |
| constructionYear | number | Year built |
| buildingCondition | string | `AS_NEW`, `GOOD`, `TO_RENOVATE`… |
| heatingType | string | `GAS`, `FUELOIL`, `ELECTRIC`… |
| floodZoneType | string | Flood-zone classification |
| agencyPhone | string | Agency phone number |
| agencyEmail | string | Agency email |
| agencyWebsite | string | Agency website |
| agencyIpiNumber | string | IPI/BIV registration number |
| viewCount | number | How many times Immoweb has shown the listing |

**Example:**

```json
{
  "listingId": 21798321,
  "propertyTitle": "Vier slaapkamers en ruimte voor uw plannen",
  "url": "https://www.immoweb.be/en/classified/house/for-sale/oosterzele/9860/21798321",
  "price": 299000,
  "priceText": "€299,000",
  "transactionType": "FOR_SALE",
  "propertyType": "HOUSE",
  "bedroomCount": 4,
  "netHabitableSurface": 242,
  "landSurface": 670,
  "locality": "Oosterzele",
  "postalCode": "9860",
  "street": "Stationsstraat",
  "streetNumber": "117",
  "province": "East Flanders",
  "region": "Flanders",
  "latitude": 50.9358347,
  "longitude": 3.774472,
  "agencyName": "OC vastgoed",
  "imageCount": 17,
  "epcScore": "F",
  "epcConsumptionPerSqm": 549,
  "hasRenovationObligation": true,
  "cadastralIncome": 725,
  "constructionYear": 1931,
  "buildingCondition": "TO_RENOVATE",
  "agencyPhone": "+3292330200",
  "agencyIpiNumber": "502286",
  "status": "success"
}
```

### 💼 Use Cases & Examples

#### 1. Belgian Property Market Analysis

**Analysts and appraisers measure a market instead of eyeballing it.**

**Input:** a province or a cluster of postal codes, houses and apartments, no price filter
**Output:** asking price, living area, plot size, bedrooms, EPC label and coordinates for every listing
**Use:** price per square metre by locality, stock split by energy label, and what a three-bedroom house really lists for in Ghent versus Liège

#### 2. Renovation and Energy-Sieve Sourcing

**Renovators find the properties Belgian energy law is about to reprice.**

**Input:** `epcScores: ["E","F","G"]`, `buildingCondition: TO_RENOVATE`, `includeDetails: true`
**Output:** EPC label with kWh/m²/year, renovation-obligation flag, cadastral income, construction year and condition
**Use:** a shortlist where the numbers can be run before anyone visits, because the fields that decide the deal are already on the row

#### 3. Estate Agency Lead Generation

**Portals, proptech and agency-services vendors find who holds the stock.**

**Input:** a district, `includeDetails: true`
**Output:** agency name, phone, email, website and IPI/BIV registration number on every listing
**Use:** group by agency to rank them by live inventory in a district, then approach the ones that matter

#### 4. New Listing Monitoring

**Buyers' agents and investors see a property the morning it appears.**

**Input:** your postal codes, `sort: newest`, on a daily schedule
**Output:** listings ordered by publication, with a previous-price value on anything reduced
**Use:** move on new stock before the weekend viewings, and pay only for rows that are new since yesterday

#### 5. Rental Yield and Investment Screening

**Investors compare what a property costs against what it rents for.**

**Input:** two runs over the same postal codes, one `for-sale` and one `for-rent`
**Output:** asking prices and monthly rents with matching bedroom counts and living areas
**Use:** a gross-yield picture per locality that no single Immoweb page shows

#### 6. Relocation and Corporate Housing Research

**HR and relocation teams size the rental market around an office.**

**Input:** postal codes within commuting distance, apartments for rent, minimum bedrooms
**Output:** monthly rent, charges, living area, availability date and agency contact
**Use:** a defensible housing allowance per site, backed by current listings rather than a survey

### 🔗 Integration Examples

#### JavaScript/Node.js

```javascript
import { ApifyClient } from 'apify-client';
const client = new ApifyClient({ token: 'YOUR_TOKEN' });

const run = await client.actor('sian.agency/immoweb-be-property-scraper').call({
  locations: ['Ghent', 'Antwerp'],
  propertyType: 'house',
  transactionType: 'for-sale',
  maxResults: 500
});

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

#### Python

```python
from apify_client import ApifyClient
client = ApifyClient('YOUR_TOKEN')

run = client.actor('sian.agency/immoweb-be-property-scraper').call(
    run_input={
        'locations': ['Liège', 'Charleroi'],
        'propertyType': 'house',
        'transactionType': 'for-sale',
        'epcScores': ['E', 'F', 'G'],
        'includeDetails': True
    }
)

for item in client.dataset(run['defaultDatasetId']).iterate_items():
    print(item['listingId'], item['price'], item.get('epcScore'), item.get('agencyPhone'))
```

#### cURL

```bash
curl -X POST 'https://api.apify.com/v2/acts/sian.agency~immoweb-be-property-scraper/runs?token=YOUR_TOKEN' \
-H 'Content-Type: application/json' \
-d '{"locations": ["Brussels"], "propertyType": "apartment", "transactionType": "for-rent", "maxResults": 100}'
```

#### Automation Workflows (N8N / Zapier / Make)

1. **Trigger**: Schedule it daily with `sort: newest`
2. **HTTP Request**: Call the actor API
3. **Process**: Handle the JSON rows and drop listing IDs you have already seen
4. **Action**: Push new listings to your CRM, a Google Sheet or a Slack alert

### 📊 Performance & Pricing

#### FREE Tier (Try It Now)

- **25 listings** per run, with every field and every filter
- No credit card required
- Enough to check the data before you commit

#### PAID Tier (Production Ready)

- **Unlimited** listings per run, across as many locations as you list
- 30 listings per request, so a 1,000-row sweep takes about a minute
- Pay per result: charged only for rows delivered, never for a failure

| Metric | Value |
|--------|-------|
| Speed | 30 listings per request, ~10 s for 100 rows |
| Coverage | All of Belgium, 12 property sections, sale and rent |
| Ceiling | 9,990 listings per search (Immoweb's own limit) |
| Free tier | 25 listings per run |
| Paid tier | Unlimited |

💰 **From $1.10 per 1,000 listings**, with full details at $2.50 per 1,000 enriched rows. That is level with the cheapest Immoweb scrapers on the Store, and the field leader charges the same for listings alone: it sells listing detail as a second actor, so listings plus EPC and agency contact means two runs and two bills there and one here.

🔗 [View current pricing](https://apify.com/sian.agency/immoweb-be-property-scraper?fpr=sian)

### ❓ Frequently Asked Questions

**Q: Do I need an API key, a login or a proxy?**
A: No. Give it a location and press Run.

**Q: How do I name a location?**
A: Type it the way you would say it: Brussels, Ghent, Antwerp, Liège, Bruges, Namur. A 4-digit postal code such as 1000 or 9000 works too, and so does a province name. Each entry is resolved against Immoweb's own location index at the start of the run, so a locality Immoweb adds tomorrow works tomorrow.

**Q: How many listings can one search return?**
A: 9,990. Immoweb serves 333 pages of 30 and answers page 334 with an error. That is its own ceiling, not ours. To go wider, split the search by postal code, by price band or by property type.

**Q: What do the full details add?**
A: The agent's written description, the EPC label with its kWh/m²/year and certificate reference, the renovation-obligation flag, the cadastral income, construction year, condition, facade count, heating and kitchen type, garden and terrace surfaces, flood-zone status, and the agency's phone, email, website and IPI number. It also replaces the four thumbnails on the card with the full photo gallery.

**Q: What does the full-details option cost?**
A: It fetches each listing's own record, so it bills one Property Detail event per enriched listing on top of the listing row. Leave it off and you pay for listing rows only.

**Q: Can I paste an Immoweb search URL instead of filling the form?**
A: Yes. Build the search on immoweb.be, copy the address bar into Search URLs, and every filter in that URL is used, including facets this form does not expose.

**Q: Does it return rental listings?**
A: Yes. Set For sale or for rent to rent, and the price field carries the monthly rent while the price text shows the charges on top where the agency published them.

**Q: Are the addresses exact?**
A: Where the agency published a street and number they come through, along with latitude and longitude. Plenty of Belgian listings deliberately publish only the locality and postal code, and in those the street fields are empty rather than approximated.

**Q: Can I get the owner's phone number?**
A: No. Immoweb routes private-seller contact through its own form, so the contact block on a listing belongs to the publishing agency. A column labelled "owner phone" would be a fiction, so there isn't one.

**Q: What output formats are available?**
A: JSON, CSV and Excel, straight from the Apify dataset, or over the API in your own code.

**Q: How do I only get new listings?**
A: Sort by newest and schedule the run daily, keeping the listing IDs you already have. You are billed for the new rows only, instead of re-buying the whole market every morning.

**Q: Is this legal?**
A: It only reads listings that are already public on Immoweb. See the legal note below before you collect anything that could count as personal data.

### 🐛 Troubleshooting

**"…is not a place Immoweb knows"**

- Use a Belgian city or municipality name, a 4-digit postal code, or a province
- Check the spelling against immoweb.be's own search box; both Ghent and Gent work, Zzzz does not

**"…is not an EPC label"**

- Only reachable from the API — the form is a dropdown. Send the labels exactly: A++, A+, A, B, C, D, E, F, G
- The run stops instead of continuing without the filter, because Immoweb accepts an unknown label and then quietly returns the whole country, which you would have paid for

**Fewer listings than expected**

- Immoweb caps a single search at 9,990 results; split by postal code or price band to go wider
- A narrow filter set — a small locality plus an EPC label plus a price band — can genuinely match very little
- Free accounts are capped at 25 rows per run

**A listing URL returns "sold, rented or withdrawn"**

- Immoweb removes listings once the property is off the market
- Re-run the search to get live ones

**Empty EPC, cadastral income or agency phone**

- Those fields only come back with Add full details switched on, or in Property Detail mode
- Some agencies leave the EPC blank on a new listing until the certificate is issued

**Empty street or house number**

- Many Belgian agencies publish only the locality and postal code; the row shows what the listing shows

### ⚖️ Is it legal to scrape data?

Our actors are ethical and do not extract any private user data, such as email addresses, gender, or location. They only extract what the user has chosen to share publicly. We therefore believe that our actors, when used for ethical purposes by Apify users, are safe.

However, you should be aware that your results could contain personal data. Personal data is protected by the **GDPR** in the European Union and by other regulations around the world. You should not scrape personal data unless you have a legitimate reason to do so. If you're unsure whether your reason is legitimate, consult your lawyers.

You can also read Apify's blog post on the [legality of web scraping](https://blog.apify.com/is-web-scraping-legal/).

### 🤝 Support

[![Telegram Support](https://img.shields.io/badge/Telegram-Support%20Group-0088cc?logo=telegram)](https://t.me/+vyh1sRE08sAxMGRi)

**Join our active support community**

- 🐛 Found a bug? File an issue in the Apify Console Issues tab
- ⭐ Loving the tool? Leave a 5-star review — it helps us build more
- 🛠️ More automation tools in the [SIÁN Agency Store](https://apify.com/sian.agency?fpr=sian)
- 📧 <apify@sian-agency.online>

***

**Built by [SIÁN Agency](https://www.sian-agency.online)** | **[More Tools](https://apify.com/sian.agency?fpr=sian)**

Immoweb is a trademark of Immoweb SA. This actor is not affiliated with, endorsed by, or sponsored by Immoweb.

# Actor input Schema

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

Pick one per run. Property Search returns listing rows for any Belgian location and filter set; Property Detail takes Immoweb listing URLs or IDs and returns the description, EPC certificate, cadastral income and agency contact details.

## `locations` (type: `array`):

Where to search. Give city or district names (Brussels, Ghent, Antwerp, Liège, Bruges), 4-digit postal codes (1000, 9000, 2000), or province names. Each entry is resolved against Immoweb's own location index, so you do not need its internal codes. Leave the list empty to search the whole of Belgium.

## `propertyType` (type: `string`):

Which Immoweb section to search. 'Houses and apartments' covers both residential types in one run, which is what most market studies want.

## `transactionType` (type: `string`):

Sale listings carry an asking price; rental listings carry a monthly rent and, where the agency published it, the charges on top.

## `maxResults` (type: `integer`):

Stop after this many listings across every location in the run. One call returns 30 listings, so the run finishes at the first call that crosses your limit.

## `sort` (type: `string`):

Newest first is what you want when you run this on a schedule and only care about what appeared since the last run.

## `language` (type: `string`):

Immoweb serves the same listings in three languages. This sets the language of the labels and the formatted price text; agent-written descriptions come back in whatever language the agency typed them.

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

Fetch each listing's own record to add the full description, EPC score and consumption, cadastral income, construction year, condition, and the agency's phone, email and website. Costs one extra request per listing and bills the Property Detail event on top of the listing row.

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

Lowest price to include, in euros. 0 means no lower bound. For rentals this is a monthly rent.

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

Highest price to include, in euros. 0 means no upper bound. Pairing this with a min price is also how you split a search that would otherwise exceed Immoweb's 9,990-result ceiling.

## `minBedroomCount` (type: `integer`):

Only listings with at least this many bedrooms. 0 means no minimum.

## `minSurface` (type: `integer`):

Minimum net habitable surface in square metres. 0 means no minimum.

## `minLandSurface` (type: `integer`):

Minimum land surface in square metres. Useful for houses and building land; apartments rarely carry it.

## `epcScores` (type: `array`):

Keep only listings carrying one of these EPC labels. Leave it empty to return every label. Belgian renovation obligations bite at E, F and G, which is where renovation buyers look.

## `buildingCondition` (type: `string`):

Immoweb's own condition grading, as the agency filled it in. 'To renovate' and 'To restore' are the two that flag a project property.

## `hasGarden` (type: `boolean`):

Skip listings with no garden.

## `hasTerrace` (type: `boolean`):

Skip listings with no terrace.

## `hasSwimmingPool` (type: `boolean`):

Skip listings with no swimming pool.

## `isNewlyBuilt` (type: `boolean`):

Only newly built properties, which on Immoweb also means the ones sold under VAT rather than registration duty.

## `searchUrls` (type: `array`):

Paste Immoweb search URLs instead of filling the fields above. Build the search on immoweb.be, copy the address bar, and every filter in it is read straight off the URL — including facets this form does not expose.

## `listingUrls` (type: `array`):

Used by the Property Detail operation: Immoweb listing URLs to expand, e.g. https://www.immoweb.be/en/classified/house/for-sale/oosterzele/9860/21798321. A bare listing ID such as 21798321 works too.

## Actor input object example

```json
{
  "operation": "search",
  "locations": [
    "Brussels"
  ],
  "propertyType": "house",
  "transactionType": "for-sale",
  "maxResults": 100,
  "sort": "newest",
  "language": "en",
  "includeDetails": false,
  "minPrice": 0,
  "maxPrice": 0,
  "minBedroomCount": 0,
  "minSurface": 0,
  "minLandSurface": 0,
  "epcScores": [],
  "buildingCondition": "any",
  "hasGarden": false,
  "hasTerrace": false,
  "hasSwimmingPool": false,
  "isNewlyBuilt": false,
  "searchUrls": [],
  "listingUrls": []
}
```

# Actor output Schema

## `immowebListings` (type: `string`):

Every listing this run returned.

## `scrapingSummary` (type: `string`):

HTML summary showing successful and failed results with key metrics

# 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 = {
    "operation": "search",
    "locations": [
        "Brussels"
    ],
    "propertyType": "house",
    "transactionType": "for-sale",
    "maxResults": 100,
    "sort": "newest",
    "language": "en",
    "includeDetails": false,
    "minPrice": 0,
    "maxPrice": 0,
    "minBedroomCount": 0,
    "minSurface": 0,
    "minLandSurface": 0,
    "epcScores": [],
    "buildingCondition": "any",
    "hasGarden": false,
    "hasTerrace": false,
    "hasSwimmingPool": false,
    "isNewlyBuilt": false,
    "searchUrls": [],
    "listingUrls": []
};

// Run the Actor and wait for it to finish
const run = await client.actor("sian.agency/immoweb-be-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 = {
    "operation": "search",
    "locations": ["Brussels"],
    "propertyType": "house",
    "transactionType": "for-sale",
    "maxResults": 100,
    "sort": "newest",
    "language": "en",
    "includeDetails": False,
    "minPrice": 0,
    "maxPrice": 0,
    "minBedroomCount": 0,
    "minSurface": 0,
    "minLandSurface": 0,
    "epcScores": [],
    "buildingCondition": "any",
    "hasGarden": False,
    "hasTerrace": False,
    "hasSwimmingPool": False,
    "isNewlyBuilt": False,
    "searchUrls": [],
    "listingUrls": [],
}

# Run the Actor and wait for it to finish
run = client.actor("sian.agency/immoweb-be-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 '{
  "operation": "search",
  "locations": [
    "Brussels"
  ],
  "propertyType": "house",
  "transactionType": "for-sale",
  "maxResults": 100,
  "sort": "newest",
  "language": "en",
  "includeDetails": false,
  "minPrice": 0,
  "maxPrice": 0,
  "minBedroomCount": 0,
  "minSurface": 0,
  "minLandSurface": 0,
  "epcScores": [],
  "buildingCondition": "any",
  "hasGarden": false,
  "hasTerrace": false,
  "hasSwimmingPool": false,
  "isNewlyBuilt": false,
  "searchUrls": [],
  "listingUrls": []
}' |
apify call sian.agency/immoweb-be-property-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,sian.agency/immoweb-be-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/4dt4s97skHEHYGg7b/builds/bVfFUiv55mda4lMxW/openapi.json
