Purpose
Given a Dutch property address (street + house number, ideally with postcode and city), locate its listing on funda.nl and return the current listing status (for sale / sold / under offer / for rent / rented) together with core listing facts: canonical address, property type, asking price (or rent), and the listing URL. Read-only — never contacts an agent, places a bid, or saves a favourite.
When to Use
- Checking whether a specific address is currently listed on Funda and, if so, whether it is still available, sold, under offer, or rented.
- Monitoring the status of a known address over time (e.g. "is Singel 109-F still for sale?").
- Enriching an address with Funda's canonical listing data (type, asking price, time on market, sale date) before a deeper workflow.
- Anywhere you'd otherwise scrape the Funda search UI — the address→listing resolution + HTTP fetch path below is faster, cheaper, and dodges Funda's Akamai bot wall and its flaky location-only search box.
Workflow
The optimal path pairs the browserless_search tool with a single proxied page
load — no interactive DOM driving. Funda detail pages are fully server-rendered
(status, address, price, and a JSON-LD block are all in the initial HTML), so
once you have the listing URL a single browserless_agent goto yields
everything. The only non-trivial part is resolving an address to its listing
URL — Funda's own search box can't do it reliably (see Gotchas), so use
browserless_search instead.
Resolve the address to a Funda detail URL with the
browserless_searchtool:browserless_search query: "{street} {number} {postcode} {city} funda"In the returned
results[], take the first entry whoseurlhost iswww.funda.nland whose path starts with/detail/. The resulttitlealready encodes the status, in the form"{Type} {verb}: {street} {postcode} {city} | Funda"whereverbis one ofte koop(for sale),verkocht(sold),te huur(for rent),verhuurd(rented). Verify the result's street + house number + city match the queried address before trusting it — for some addresses the exact house number is not the top hit and a neighbouring number is returned instead (treat a mismatch as ambiguous / not found).Load the detail page through a residential proxy (Funda is behind Akamai Bot Manager — a plain load can be challenged; a residential proxy passes). One
browserless_agentcall, navigate then read the HTML:{ "proxy": { "proxy": "residential" }, "commands": [ { "method": "goto", "params": { "url": "{detail_url}", "waitUntil": "load", "timeout": 45000 } }, { "method": "html", "params": { "selector": "html" } } ] }Check the
gotoHTTP status.200→ parse the HTML;404("Deze pagina kunnen we niet vinden") → the listing has been de-listed, reportstatus: "not_found".Extract the data from the returned
contentHTML:- Status (authoritative): the
Statusrow in the features list (Kenmerken → Overdracht). Rendered asStatus</dt>...<dd>{value}</dd>. Values:Beschikbaar(available / for sale),Verkocht(sold),Verkocht onder voorbehoud(sold subject to conditions),Onder bod(under offer); rentals useBeschikbaar/Verhuurd. - Address, type, price from the JSON-LD block
(
<script type="application/ld+json">, the first one is the property):name= street + number,@type=["{PropertyType}", "Product"](type is element 0, e.g.Appartement,Huis),offers.price= asking price in EUR,address.{streetAddress, addressLocality, addressRegion}. Postcode is in the<title>/description(not in the JSON-LD address). - Sold-only extras (when status is
Verkocht*): the features list also carriesAangeboden sinds(listed since),Verkoopdatum(sale date) andLooptijd(time on market).
- Status (authoritative): the
Return the assembled JSON (see Expected Output). The page
<title>verb and, for sold listings, the/verkocht/URL segment both corroborate theStatusfield — cross-check them.
Browser fallback
If browserless_search can't resolve the address or the direct load fails,
drive a stealth browserless_agent session and goto the detail URL directly.
The page is server-rendered, so a single snapshot (≈470 refs) contains the
status, price, type and full features list — no clicks needed. Read the Status
value from the snapshot. Do not read the body text (it returns the
consent-banner CSS/JS, not content) — use snapshot. Accept the cookie dialog
("Alles accepteren") with a click if it blocks the view. This was validated
end-to-end (correct extraction). Note that constructing a detail URL from
scratch is impossible without the listing's numeric id, so the browser fallback
still depends on browserless_search resolving the URL.
Site-Specific Gotchas
- Akamai Bot Manager: Funda sets
ak_bmsc/bm_s/bm_sscookies and anX-Akamai-Transformedheader. Abrowserless_agentgotowithproxy: { proxy: "residential" }returns clean 200s for both search and detail pages; assume a plain (no-proxy) load may be challenged. The probe of the bare homepage reported "no antibots", but that only reflects the301root redirect — the app pages are Akamai-protected. - The homepage search box is location-only and unreliable for addresses.
The combobox placeholder is "Zoek op plaats, buurt of postcode"; it resolves
cities / streets / postcodes / neighbourhoods, not full house numbers.
Typing
Singel 109,Singel Amsterdam, or even a bare postcode1012 VGreturned "We kunnen deze locatie niet vinden" in automated sessions. Also, setting the value directly (afill-style write) does not fire the per-keystroke events the React combobox listens to, so no suggestion request fires — you must use real keystrokes (type). Even then suggestions frequently failed to render. Don't build the skill on this control. free_textquery param does not filter.https://www.funda.nl/zoeken/koop?free_text=...is reflected in the page's JSON-LD but the SSR result set stays the full ~95,768-listing default regardless of the value (confirmed across three distinct queries incl. a nonsense string). Confirmed dead end — don't use it for address lookup.- Geo-suggestion API is CORS-locked. The combobox calls
POST https://listing-search-wonen.funda.nl/geo-wonen-alias-prod/_search/templatewith body{"id":"searchbox_20250621","params":{"value":"...","area_types":[...]}}. It is an Elasticsearch stored-template endpoint scoped to the page origin — a cross-originfetch()from an injected script fails with "Failed to fetch". Don't waste time trying to call it directly; and even if reached it returns areas, not individual listings. - Sold listings move under
/detail/koop/verkocht/{city}/...(an extra/verkocht/path segment) and return 200 withStatus: Verkocht. But some older sold/withdrawn listings are fully de-listed and return HTTP 404 — handle 404 asnot_found, not as an error. - Search-API resolution is good but not perfect. Exact, well-known addresses
(e.g.
Singel 109-F Amsterdam) resolve to the right detail URL as the top hit; for some addresses the precise house number is absent and a neighbouring number is returned. Always verify street + number + city against the result title/JSON-LD; on mismatch, reportambiguous/not_foundrather than the wrong listing. - JSON-LD
@typeis an array like["Appartement","Product"]— the human property type is element[0]. The JSON-LDaddressomits the postcode; read the postcode from the<title>("...: {street} {postcode} {city} | Funda"). - Prices are k.k. ("kosten koper" — buyer pays transfer costs) for
koop; rentals (/detail/huur/...) show a per-month figure.offers.priceis the numeric value without thek.k.suffix.
Expected Output
{
"success": true,
"query_address": "Singel 109-F, 1012 VG Amsterdam",
"matched": true,
"address": "Singel 109-F",
"postcode": "1012 VG",
"city": "Amsterdam",
"region": "Noord-Holland",
"property_type": "Appartement",
"offering_type": "koop",
"price_eur": 1125000,
"status": "Beschikbaar",
"status_label_en": "available / for sale",
"listed_since": null,
"sale_date": null,
"time_on_market": null,
"listing_url": "https://www.funda.nl/detail/koop/amsterdam/appartement-singel-109-f/43703804/",
"error_reasoning": null
}Sold listing:
{
"success": true,
"query_address": "Van Oldenbarneveldtstraat 89-5, 1052 JX Amsterdam",
"matched": true,
"address": "Van Oldenbarneveldtstraat 89-5",
"postcode": "1052 JX",
"city": "Amsterdam",
"region": "Noord-Holland",
"property_type": "Appartement",
"offering_type": "koop",
"price_eur": 425000,
"status": "Verkocht",
"status_label_en": "sold",
"listed_since": "14 juni 2025",
"sale_date": "15 juli 2025",
"time_on_market": "4 weken",
"listing_url": "https://www.funda.nl/detail/koop/verkocht/amsterdam/appartement-van-oldenbarneveldtstraat-89-5/89417959/",
"error_reasoning": null
}Not found / de-listed (HTTP 404, or no Funda /detail/ result matching the
queried address):
{
"success": false,
"query_address": "Some Street 999, 9999 ZZ Nowhere",
"matched": false,
"status": "not_found",
"listing_url": null,
"error_reasoning": "No funda.nl /detail/ listing matched the address (search returned only neighbouring numbers / the detail page returned HTTP 404 — listing de-listed)."
}