Funda Properties Scraper
Pricing
from $1.26 / 1,000 results
Funda Properties Scraper
Scrapes Dutch property listings from Funda: asking price, price per m², living area, rooms, build year, energy label, VvE contribution, address with postcode and neighbourhood, photos and the full Dutch feature table. For sale and for rent.
Pricing
from $1.26 / 1,000 results
Rating
0.0
(0)
Developer
Ibnu Adzim
Maintained by CommunityActor stats
0
Bookmarked
2
Total users
1
Monthly active users
4 days ago
Last modified
Categories
Share
Dutch properties for sale and to rent from Funda — full address with postcode, price, floor area, rooms and bedrooms, energy label, the selling agent, photos and listing dates, plus a 23-group facet breakdown of the whole market on every search.
Search by plain place name; areas are resolved and verified for you. HTTP only, no browser, no login.
Input
{"channel": "buy","locations": ["Amsterdam", "Den Haag"],"minPrice": 300000,"maxPrice": 750000,"minBedrooms": 2,"maxPages": 5}
locations also accepts a Funda area slug (provincie-noord-holland,
regio-groot-amsterdam, amsterdam/uilenburg, 1011lm) or a full Funda
search URL, so you can paste whatever you already have.
What you get
recordType | One per | Carries |
|---|---|---|
SEARCH_SUMMARY | location | resolved slug, area name and type, its centroid and parent areas, the slug forms tried, the upstream match count, the reachable ceiling, pages fetched, duplicates dropped, and the full facet breakdown |
LISTING | property | id, URL, full address with postcode and neighbourhood, price, floor area, rooms, energy label, agent, photos, listing date — plus the raw upstream object |
ERROR | failed input | why |
{"recordType": "LISTING","listingId": 8138160,"listingUrl": "https://www.funda.nl/detail/koop/amsterdam/appartement-nieuwe-uilenburgerstraat-9-g/44583523/","addressLine": "Nieuwe Uilenburgerstraat 9 G","postalCode": "1011LM","city": "Amsterdam","neighbourhood": "Uilenburg","district": "Nieuwmarkt/Lastage","province": "Noord-Holland","objectType": "apartment","price": 975000, "currency": "EUR", "priceCondition": "kosten_koper","floorArea": 118, "numberOfRooms": 3, "numberOfBedrooms": 2,"energyLabel": "C","agentName": "House of MAY Real Estate","publishDate": "2026-09-06T09:00:01+02:00"}
Optional: the detail pass
Set fetchDetails: true to fetch each listing's own page as well. It adds:
latitude/longitude— search results carry no coordinates at all, so this is the only way to map Funda propertiesdescription— the full Dutch listing textpricePerSqm,vveContributionMonthly,buildYear,volumeM3,insulation,heating,situation,gardenOrientation,constructionKind, room and bathroom descriptionsfeatureGroups— the complete nine-group Dutch feature table (Overdracht, Bouw, Oppervlakten en inhoud, Indeling, Energie, Kadastrale gegevens, Buitenruimte, Parkeergelegenheid, VvE checklist)brochureUrl,canonicalUrl,detailLabels,isSoldOrRented
It is off by default because it costs roughly 15× the requests — a search
page returns 15 listings, a detail page returns one. A detail page that fails
does not lose its row: the search data stays and detailError records why.
Known limits — read these before you rely on the output
Funda's default search hides more than it shows. Amsterdam reports
6,194 matches — but that is only what is on the market now
(4,068 available + 2,126 under negotiation). A further 13,698 sold or
rented listings sit behind the availability filter, which the site does
not apply by default. If you are measuring a market rather than shopping,
select all three availability states. Every summary row reports the
availability facet counts, so you can always see what was excluded.
Past 10,000 matches, Funda re-serves its last page forever. It does not
return an empty page and it does not error — page 668, page 6,148 and page
20,000 of a nationwide search are byte-identical. A "keep paging until the
page comes back empty" consumer would loop indefinitely on the same 15 rows.
This actor computes the last page from the count instead, and every summary
carries reachableCeiling. To get past it, narrow the search — a price
band, an object type, or a smaller area. Below 10,000 the count is exact and
fully reachable: Amsterdam's 6,194 comes back as 412 full pages plus a final
page of 14.
Place names are case-sensitive upstream. amsterdam returns 6,194
listings; Amsterdam returns zero, with a normal 200. This actor
normalises names before use, so you can type them naturally — but it is why
an area that does not resolve produces an ERROR row rather than a guess:
omitting the area entirely returns all 93,867 listings in the Netherlands,
so a silent fallback would hand you the wrong country-sized answer. Funda's
slug is also not always the obvious one — 's-Hertogenbosch is den-bosch.
Pass a slug from a Funda search URL when you need certainty.
New-build project rows carry a price range, not a price. 62 of
Amsterdam's rows are listingType: "group" — one row standing for a whole
development, with selling_price of [425000, 769000] and no room counts.
Those rows have price: null, priceMin/priceMax set, and
isProject: truelistingTypes: ["single"] if you want homes only.
Some homes are listed for sale and for rent at once. Funda gives these
a /detail/koophuur/ URL and puts both numbers in one object — 14 of 30 rows
on a live Amsterdam rent search. price always follows the channel you
queried, and salePrice, rentPrice and isDualListed are all populated so
you never have to guess which number you got.
A price of null can be correct. priceType: "on_request" is Funda's
"prijs op aanvraag" — a real listing whose price is genuinely not published.
Two plausible sort options do not exist. Funda silently ignores an
unknown sort and falls back to relevancy with a normal-looking page —
including floor_area_up and plot_area_up, which are exactly what you would
guess for "smallest first". Only orderings verified to actually change the
result order are offered, and anything else is refused up front.
Bad filter values fail two different ways, so both are refused before a request is made: an unknown property type or energy label returns an empty result set (reads as "nothing matched"), while an unparseable price filter is silently ignored and returns the unfiltered set (reads as a successful search).
Technical
Server-rendered Nuxt 3. The whole result set is strict JSON inside
<script id="__NUXT_DATA__">, but in Nuxt's devalue flat-array form — a
list where every value is either a literal or an index into that same list,
with real cycles — so it is resolved rather than subscripted. 15 listings per
page, paged with &search_result=.
Area resolution rides on the search request itself: Funda's response reports
which area it actually applied, so a name is resolved by trying its slug forms
(bare, gemeente-, provincie-, regio-) and reading back what upstream
used. When the first candidate resolves — the common case — that same response
is page 1, so resolution costs no extra request.
All seven TLS fingerprint profiles tried returned 200, so the pool is a real rotation rather than an allowlist.
robots.txt was checked at path level on the exact URLs fetched.
Full recon trail is in CRAWLING_METHOD.md.