Immoweb Property Scraper (Belgium)
Pricing
from $0.84 / 1,000 results
Immoweb Property Scraper (Belgium)
Scrapes houses, apartments, land and commercial property from Immoweb — Belgium's #1 real-estate portal. Filter by type, postal code, price and bedrooms; returns price, address, surface, energy certificate, amenities, photos and agency contact for every listing.
Pricing
from $0.84 / 1,000 results
Rating
0.0
(0)
Developer
Ibnu Adzim
Maintained by CommunityActor stats
0
Bookmarked
2
Total users
1
Monthly active users
a day ago
Last modified
Categories
Share
Scrapes houses, apartments, land, offices and commercial property from Immoweb — Belgium's #1 real-estate portal, with roughly 81,000 houses and apartments listed for sale at any time.
Public data only. No login, no cookies, no browser — a plain HTTP client talking to the same JSON endpoint Immoweb's own website uses.
What you get
Two record types share one dataset, told apart by recordType:
PROPERTY — one row per listing
Search rows carry price, address, surface, bedrooms, photos, energy
certificate and the listing agency. With Fetch full property details on
(the default), each row also gets a propertyDetails object with:
- the complete description text (all languages the agent supplied)
- every amenity flag — garden, terrace, lift, basement, attic, air-con, alarm, fireplace, jacuzzi, sauna, disabled access, …
- energy: EPC score, certificate, heating type, insulation, glazing
- surfaces broken out — habitable, land, garden, terrace, per-room
- building: construction year, condition, number of floors, façade count
- full media set — photos at four resolutions, floor plans, virtual tour, video
- legal documents and the agency's contact block
SEARCH_SUMMARY — one row per search
Upstream's own match total, how deep the run paged, whether the query hit Immoweb's ceiling, and — importantly — which of your filters Immoweb actually applied (see the honesty note below).
Input
| Field | What it does |
|---|---|
| Property type | house, apartment, land, office, garage, commercial, industrial, plus subtypes (villa, castle, penthouse, loft, duplex, kot…) |
| For sale / for rent | the two transaction states Immoweb exposes publicly |
| Country | Belgium (where the inventory is) plus FR/NL/LU/ES/IT |
| Postal codes | e.g. 1000 Brussels, 2000 Antwerp, 9000 Ghent, 4000 Liège |
| Price / bedrooms / land surface | min–max ranges |
| Sort order | relevance, newest, cheapest, most expensive, postcode, surface |
| Classified URLs | scrape specific listings directly, skipping search |
| Max properties per search | 0 = unlimited (up to Immoweb's own 9,990 ceiling) |
| Fetch full property details | off = fast listing-only crawl, 1 request per 30 properties |
Example
{"propertyType": "house","transactionType": "for-sale","country": "BE","postalCodes": ["1000", "1050"],"minPrice": 250000,"maxPrice": 600000,"minBedrooms": 3,"maxItems": 500,"includePropertyDetails": true}
Two things this actor is honest about
1. Immoweb silently ignores filters it does not understand. Ask for postal
code 9999 and it answers HTTP 200 with all 47,777 nationwide houses — not an
error, just quietly the wrong data. This actor reads back the filter set
Immoweb reports it actually honoured and puts it on every SEARCH_SUMMARY row:
"filtersApplied": {"postalCodes": ["1000"], "postalCodeLabels": ["Brussels City (1000)"]},"filtersIgnored": [],"allFiltersApplied": true
If something was dropped, filtersIgnored names it and the run logs a warning.
Property types are checked against a verified allowlist before the first
request, so a typo is refused rather than answered with unfiltered results.
2. Immoweb caps pagination at 9,990 results per query (333 pages × 30),
even when it reports far more matches. When a run hits that ceiling,
resultCapReached: true appears on the summary row and the log tells you to
narrow by postcode or price. No actor can page past it — the endpoint returns
HTTP 500 at page 334.
Notes on reliability
- No WAF challenge. Immoweb sits behind Cloudflare but serves data cold on every TLS profile tested. Nothing to solve, nothing to refresh.
- Runs unattended. No human-captured session, no expiring token — safe on a schedule.
- Residential proxy by default for cloud runs. Container egress is a different posture than a home connection, and this portfolio has lost a full cloud run to that difference before.
- Failures never vanish. A listing that sells mid-crawl degrades that one
row (
_detailError) instead of failing the run; every input maps to at least one output row.
Output envelope
Every record carries _input, _source and _scrapedAt. Upstream field names
are passed through verbatim — no renaming — so downstream schema drift has
exactly one place to fix. _source is S1-search-json for listing-only rows
and S1-search-json+S2-classified-var once details are attached.
See CRAWLING_METHOD.md for the full reverse-engineering trail, the pagination ceiling bisection, and the filter-trap evidence.