Funda Properties Scraper avatar

Funda Properties Scraper

Pricing

from $1.26 / 1,000 results

Go to Apify Store
Funda Properties Scraper

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

Ibnu Adzim

Maintained by Community

Actor 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

recordTypeOne perCarries
SEARCH_SUMMARYlocationresolved 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
LISTINGpropertyid, URL, full address with postcode and neighbourhood, price, floor area, rooms, energy label, agent, photos, listing date — plus the raw upstream object
ERRORfailed inputwhy
{
"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 properties
  • description — the full Dutch listing text
  • pricePerSqm, vveContributionMonthly, buildYear, volumeM3, insulation, heating, situation, gardenOrientation, constructionKind, room and bathroom descriptions
  • featureGroups — 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: true
. Filter them out with listingTypes: ["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.