# Funda.nl Scraper - Dutch Real Estate Listings Extractor (`haketa/funda-scraper`) Actor

Funda scraper & API for Dutch real estate: search homes for sale and rent and export address, price, bedrooms, living area, plot, energy label, year built, agent, photos and coordinates. Netherlands property market data and real-estate lead generation — fast, no login.

- **URL**: https://apify.com/haketa/funda-scraper.md
- **Developed by:** [Haketa](https://apify.com/haketa) (community)
- **Categories:** Real estate, Lead generation, E-commerce
- **Features:** Limited permissions
- **Stats:** 15 total users, 0 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $3.50 / 1,000 results

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?

An Actor is a serverless cloud program that runs on the Apify platform. It has two run modes.
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.

Apify vocabulary and the platform model are defined once, in the agent quickstart at https://apify.com/agents.md.

## 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.

Do not guess an integration path. Every one of them is in the agent quickstart at https://apify.com/agents.md: the Apify MCP server, Agent Skills with the Apify CLI, the JavaScript and Python clients, the REST API, and the account-free path for an agent with no human to sign in. It also carries the rule on stating cost before the first paid run.

For examples already wired to this Actor's own input schema, see the [API](#api) section below.

Each client library has reference documentation the quickstart does not restate: [JavaScript/TypeScript](https://docs.apify.com/api/client/js/docs.md) (`npm install apify-client`) and [Python](https://docs.apify.com/api/client/python/docs.md) (`pip install apify-client`).

# README

## Funda.nl Scraper 🇳🇱 — Netherlands Real Estate Listings (Price, m², Energy Label)

> **Extract structured Dutch property listings from [Funda.nl](https://www.funda.nl/) — the #1 real-estate marketplace in the Netherlands — without writing code.** This **Funda.nl scraper** lets you **scrape Funda** homes and apartments **for sale (*koop*)** or **for rent (*huur*)** with complete property details: asking price or monthly rent (`EUR`), living area (`m²`), plot area, rooms, bedrooms, **official energy label (`A++++` to `G`)**, construction year (*bouwjaar*), full street address, Dutch postal code, neighbourhood, municipality, amenity flags (garden, balcony, solar panels, heat pump), broker ID/name, description, and high-resolution photo URLs.

Export every listing to **JSON, CSV, Excel, or API** with **1,000+ results pagination** unlocked.

[![Apify Actor](https://img.shields.io/badge/Apify-Actor-blue)](https://apify.com/haketa/funda-scraper)
[![Region](https://img.shields.io/badge/Region-Netherlands%20%F0%9F%87%B3%F0%9F%87%B1-orange)]()
[![Data](https://img.shields.io/badge/Data-Koop%20\(Sale\)%20%26%20Huur%20\(Rent\)-success)]()
[![Rich Fields](https://img.shields.io/badge/Fields-35%2B%20Property%20Attributes-purple)]()
[![No Auth](https://img.shields.io/badge/Auth-None%20Required-brightgreen)]()
[![Export](https://img.shields.io/badge/Export-JSON%20%C2%B7%20CSV%20%C2%B7%20Excel-lightgrey)]()

***

### ⚡ At a glance

| Feature | Details |
| :--- | :--- |
| **Target Platform** | [Funda.nl](https://www.funda.nl/) — Dutch Real Estate Portal (NVM / VBO / Vastgoedpro listings) |
| **Transaction Types** | Homes for Sale (`koop` → `asking_price`) & Homes for Rent (`huur` → `rent_per_month`) |
| **Search Modes** | **25-City Dutch Dropdown** (`areas`), Custom Towns/Neighbourhoods (`customAreas`), Filtered Search URLs (`searchUrls`), or Direct Listing URLs (`startUrls`) |
| **Core Data Extracted** | `address`, `postalCode`, `city`, `province`, `price`, `livingArea` (`m²`), `plotArea`, `rooms`, `bedrooms`, `energyLabel`, `yearBuilt`, `propertyType`, `status`, `brokerId`, `photos` |
| **Sustainability & Amenities** | `energyLabel`, `energyEfficient`, `solarPanels` (*zonnepanelen*), `heatPump` (*warmtepomp*), `garden` (*tuin*), `balcony`, `roofTerrace`, `privateParking`, `nationalMonument` |
| **Pagination & Scale** | Automatic search pagination (15 listings/page) across **1,000+ listings** and multiple Dutch cities |
| **Deduplication** | Automatic deduplication by canonical listing `url` across all pages and cities |
| **Export Formats** | JSON, CSV, Excel (XLSX), HTML, XML, RSS, and Apify REST API |

***

### 📋 Table of contents

- [Why scrape Funda.nl?](#-why-scrape-fundanl)
- [What this Funda.nl scraper does](#-what-this-fundanl-scraper-does)
- [High-value use cases](#-high-value-use-cases)
- [Input configuration](#-input-configuration)
- [Output sample & field reference](#-output-sample--field-reference)
- [Pagination & 1,000+ scale](#-pagination--1000-scale)
- [How to use (Console & API)](#️-how-to-use-console--api)
- [Pro tips for Dutch property data](#-pro-tips-for-dutch-property-data)
- [Honest limitations](#-honest-limitations)
- [FAQ](#-faq)
- [Related scrapers](#-related-scrapers)
- [Changelog](#-changelog)

***

### 🔎 Why scrape Funda.nl?

**Funda.nl** is the definitive housing portal of the Netherlands. Almost every residential property listed for sale (*koop*) or rent (*huur*) in Amsterdam, Rotterdam, Den Haag (The Hague), Utrecht, Eindhoven, Groningen, Tilburg, Almere, Breda, and Nijmegen appears on Funda first. That makes **Funda data** the gold standard for Dutch real-estate valuation, investment screening, and housing market analytics.

However, Funda offers **no public API**, and manual copy-pasting across paginated search results and detail pages is impractical. This **Funda.nl data extractor** automates the entire workflow: it paginates through search results, visits every property detail page in parallel, merges structured JSON-LD and Nuxt property state into a 35-field record, and outputs a clean table ready for Excel, BI tools, or automated valuation pipelines.

**Common reasons teams scrape Funda.nl:**

- 🏷️ **Real-Estate Deal Sourcing** — spot newly listed homes (`sortBy: "date_down"`) and undervalued properties per square meter across target Dutch *gemeenten* and postal codes.
- 📊 **Price per m² & Energy Label Analytics** — quantify how Dutch energy labels (`A++++`, `A`, `B` vs `E`, `F`, `G`), solar panels, and heat pumps impact asking prices and rental yields.
- 🧮 **Automated Valuation Models (AVM) & Comps** — pull live comparable listings (*referentieobjecten*) with exact `livingArea`, `plotArea`, `yearBuilt`, and `postalCode`.
- 🏢 **PropTech & Relocation Feeds** — power expat housing platforms, mortgage calculators, and property alert bots with fresh Dutch inventory.
- 🧑‍💼 **Makelaar & Inventory Intelligence** — track active listings by `brokerId` / `brokerName`, `status` (`beschikbaar`, `onder bod`), and neighbourhood (`buurt`).
- 🎓 **Urban & Housing Affordability Research** — compile longitudinal datasets on Dutch housing supply, leasehold (*erfpacht*), and energy transition adoption.

***

### ✨ What this Funda.nl scraper does

- ✅ **4 Flexible Input Modes** — select from a **25-city Dutch dropdown** (`areas`), type any custom municipality or neighbourhood slug in `customAreas` (e.g., `gouda`, `amsterdam/centrum`), paste full filtered **Funda search URLs** (`searchUrls`), or scrape individual **listing URLs** (`startUrls`).
- ✅ **Both Sale (`koop`) & Rent (`huur`)** — seamlessly switches between purchase asking prices (`priceType: "asking_price"`) and monthly rents (`priceType: "rent_per_month"`).
- ✅ **35+ Structured Property Fields** — combines JSON-LD schema and Nuxt property state to extract `address`, 6-character Dutch `postalCode` (`1077ZR`), `city`, `province`, `price`, `livingArea`, `plotArea`, `rooms`, `bedrooms`, `energyLabel`, `yearBuilt`, `propertyType`, `buildType`, `leasehold`, `status`, `neighbourhood`, `municipality`, 7 boolean amenity flags, `brokerId`, `brokerName`, `description`, and full `photos` arrays.
- ✅ **Deep 1,000+ Pagination** — steps through `search_result=1, 2, 3...` (15 properties per page) across one or multiple cities until your `maxItems` target is reached.
- ✅ **Parallel Detail Extraction** — fetches property detail pages concurrently (`maxConcurrency`, up to 30) with automatic proxy rotation and retry handling.
- ✅ **Built-in Anti-Blocking Configuration** — pre-configured with Apify's `UNBLOCKER` proxy group so runs clear Funda's interstitial protection out of the box.

***

### 🎯 High-value use cases

#### 1. Dutch Property Investors & Buy-to-Let Analysts

Combine `livingArea`, `price`, `energyLabel`, and `postalCode` (4-digit + 2-letter Dutch postcode) to calculate exact asking price per m² (`price / livingArea`) and filter for properties with `energyLabel` `A` or higher that qualify for favorable Dutch mortgage terms and WWS (*woningwaarderingsstelsel*) rental points.

#### 2. Real Estate Agencies (*Makelaars*) & Appraisers (*Taxateurs*)

Monitor competing inventory in specific neighbourhoods (`customAreas: ["amsterdam/oud-zuid", "utrecht/oost"]`), track how many properties are currently `"onder bod"` vs `"beschikbaar"`, and benchmark asking prices by `yearBuilt` and `buildType` (`bestaandebouw` vs `nieuwbouw`).

#### 3. Solar, Heat-Pump & Home-Renovation Lead Generation

Because every Funda record includes `energyLabel`, `solarPanels` (`true`/`false`), `heatPump` (`true`/`false`), and `yearBuilt`, green-energy installers and renovation contractors can identify recently listed homes built before 1990 with energy labels `D`–`G` and no solar panels or heat pump installed.

***

### 📥 Input configuration

All fields are optional. Leaving all location fields empty collects a fast, multi-city sample from the largest Dutch cities.

| Parameter | Type | Default / Prefill | Description |
| :--- | :--- | :--- | :--- |
| `listingType` | `string` | `"koop"` | Whether to collect homes for sale (`"koop"`) or for rent (`"huur"`). |
| `areas` | `array` | Prefill: `["amsterdam"]` | Select one or more Dutch cities from the 25-city dropdown (`amsterdam`, `rotterdam`, `den-haag`, `utrecht`, `eindhoven`, `groningen`, `tilburg`, `almere`, `breda`, `nijmegen`, `haarlem`, `arnhem`, `enschede`, `amersfoort`, `apeldoorn`, `zwolle`, `leiden`, `maastricht`, `dordrecht`, `delft`, `alkmaar`, `leeuwarden`, `s-hertogenbosch`, `zaanstad`, `hilversum`). |
| `customAreas` | `array` | `[]` | Optional list of any Funda area slugs not in the dropdown — e.g., a town (`"gouda"`, `"amstelveen"`) or neighbourhood (`"amsterdam/centrum"`). |
| `sortBy` | `string` | `"relevancy"` | Sort order for city searches: `"relevancy"`, `"date_down"` (Newest first), `"price_up"`, or `"price_down"`. |
| `searchUrls` | `array` | `[]` | Optional full Funda search URLs (`https://www.funda.nl/zoeken/...`) with custom price, surface, room, or energy-label filters. |
| `startUrls` | `array` | `[]` | Optional direct Funda property detail URLs (`https://www.funda.nl/detail/...`). |
| `maxItems` | `integer` | Default: `30` (Prefill: `15`) | Maximum listings to collect across the run. Set `0` for no limit (or `1000+` for deep city/multi-city pulls). |
| `maxConcurrency` | `integer` | `15` (1–30) | Maximum detail pages fetched in parallel. |
| `maxRequestRetries` | `integer` | `3` (0–15) | Maximum retry attempts per request. |
| `proxyConfiguration` | `object` | `UNBLOCKER` | Proxy settings. Defaults to Apify's `UNBLOCKER` group to handle Funda's anti-bot protection automatically. |

#### Example 1 — Fast Amsterdam preview (Prefill)

```json
{
  "listingType": "koop",
  "areas": ["amsterdam"],
  "maxItems": 15,
  "maxConcurrency": 15,
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": ["UNBLOCKER"]
  }
}
```

#### Example 2 — 1,000+ Randstad multi-city extraction (Amsterdam, Rotterdam, Den Haag, Utrecht)

```json
{
  "listingType": "koop",
  "areas": ["amsterdam", "rotterdam", "den-haag", "utrecht"],
  "sortBy": "date_down",
  "maxItems": 1200,
  "maxConcurrency": 20,
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": ["UNBLOCKER"]
  }
}
```

#### Example 3 — Filtered Funda search URL (Homes €250k–€500k with Energy Label A)

```json
{
  "searchUrls": [
    { "url": "https://www.funda.nl/zoeken/koop?selected_area=[\"rotterdam\"]&price=\"250000-500000\"&energy_label=[\"A\"]" }
  ],
  "maxItems": 200
}
```

***

### 📤 Output sample & field reference

Each property is saved as a single clean record in the dataset. Below is a verified output item from a live Amsterdam run:

```json
{
  "url": "https://www.funda.nl/detail/koop/amsterdam/appartement-courbetstraat-19-3/44667073/",
  "listingType": "koop",
  "address": "Courbetstraat 19-3",
  "postalCode": "1077ZR",
  "city": "Amsterdam",
  "province": "Noord-Holland",
  "price": 1075000,
  "priceCurrency": "EUR",
  "priceType": "asking_price",
  "livingArea": 132,
  "plotArea": null,
  "rooms": 7,
  "bedrooms": 4,
  "energyLabel": "C",
  "energyEfficient": false,
  "yearBuilt": 1933,
  "propertyType": "Appartement",
  "buildType": "bestaandebouw",
  "leasehold": null,
  "status": "beschikbaar",
  "neighbourhood": "minervabuurtzuid",
  "municipality": "amsterdam",
  "garden": false,
  "balcony": true,
  "roofTerrace": false,
  "solarPanels": false,
  "heatPump": false,
  "privateParking": false,
  "nationalMonument": false,
  "brokerName": null,
  "brokerId": "24773",
  "description": "Appartement te koop: Courbetstraat 19-3 1077 ZR Amsterdam",
  "photo": "https://cloud.funda.nl/valentina_media/237/219/768_1440x960.jpg",
  "photos": [
    "https://cloud.funda.nl/valentina_media/237/219/768_1440x960.jpg",
    "https://cloud.funda.nl/valentina_media/237/219/756_1440x960.jpg"
  ],
  "photoCount": 6,
  "scrapedAt": "2026-11-10T02:30:00.000Z"
}
```

#### 🗂️ Field reference & coverage table

##### 🏡 Core Property, Address & Pricing Fields

| Field | Type | Coverage | Description |
| :--- | :--- | :--- | :--- |
| `url` | `string` | 🟢 High (100%) | Direct canonical URL to the Funda property listing (primary deduplication key). |
| `listingType` | `string` | 🟢 High (100%) | Transaction type: `"koop"` (for sale) or `"huur"` (for rent). |
| `address` | `string` | 🟢 High (100%) | Street name and house number (plus suffix). |
| `postalCode` | `string` | 🟢 High (~99%) | Official 6-character Dutch postcode (e.g., `1077ZR`). |
| `city` | `string` | 🟢 High (100%) | Dutch city or town name (*plaats*). |
| `province` | `string` | 🟢 High (~99%) | Dutch province (e.g., `Noord-Holland`, `Zuid-Holland`, `Utrecht`). |
| `neighbourhood` | `string` | 🟢 High (~98%) | Neighbourhood slug (*buurt*, e.g., `minervabuurtzuid`, `jordaan`). |
| `municipality` | `string` | 🟢 High (~99%) | Municipality slug (*gemeente*). |
| `price` | `number` | 🟢 High (~99%) | Numeric asking price (sale) or monthly rent (rental) in EUR. |
| `priceCurrency` | `string` | 🟢 High (100%) | Currency code (`"EUR"`). |
| `priceType` | `string` | 🟢 High (100%) | `"asking_price"` for sale listings or `"rent_per_month"` for rentals. |

##### 📐 Dimensions, Construction & Energy Fields

| Field | Type | Coverage | Description |
| :--- | :--- | :--- | :--- |
| `livingArea` | `number` | 🟢 High (~98%) | Interior living surface (*woonoppervlakte*) in `m²`. |
| `plotArea` | `number` | 🟡 Conditional | Land plot surface (*perceeloppervlakte*) in `m²` (populated for houses with land; null for apartments). |
| `rooms` | `number` | 🟢 High (~98%) | Total number of rooms (*aantalkamers*). |
| `bedrooms` | `number` | 🟢 High (~95%) | Number of bedrooms (*aantalslaapkamers*). |
| `energyLabel` | `string` | 🟢 High (~95%) | Official Dutch energy class (`A++++`, `A+++`, `A++`, `A+`, `A`, `B`, `C`, `D`, `E`, `F`, `G`). |
| `energyEfficient` | `boolean` | 🟢 High (~98%) | Funda's *energiezuinig* boolean indicator. |
| `yearBuilt` | `number` | 🟢 High (~96%) | Construction year (*bouwjaar*). |
| `propertyType` | `string` | 🟢 High (100%) | Property type (`Appartement`, `Huis`, `woonhuis`, `appartement`, etc.). |
| `buildType` | `string` | 🟢 High (~98%) | `"bestaandebouw"` (existing build) or `"nieuwbouw"` (new build). |
| `leasehold` | `string` | 🟡 Conditional | Ownership/ground-lease info (*erfpacht*) when explicitly structured in the payload. |
| `status` | `string` | 🟢 High (100%) | Listing availability status (e.g., `"beschikbaar"`, `"onder bod"`, `"verkocht"`). |

##### 🌿 Amenities, Broker & Media Fields

| Field | Type | Coverage | Description |
| :--- | :--- | :--- | :--- |
| `garden` / `balcony` / `roofTerrace` | `boolean` | 🟢 High (~98%) | Boolean flags for *tuin*, *balkon*, and *dakterras*. |
| `solarPanels` / `heatPump` | `boolean` | 🟢 High (~98%) | Green-tech flags for *zonnepanelen* and *warmtepomp*. |
| `privateParking` / `nationalMonument` | `boolean` | 🟢 High (~98%) | Boolean flags for on-site parking and *rijksmonument* status. |
| `brokerId` | `string` | 🟢 High (~99%) | Funda identifier (`hoofdaanbieder`) for the listing real-estate agency (*makelaar*). |
| `brokerName` | `string` | 🟡 Conditional | Broker display name when present in the SSR state payload. |
| `description` | `string` | 🟢 High (100%) | Clean listing summary/description with trailing `[funda]` markers stripped. |
| `photo` / `photos` / `photoCount` | `string` / `array` / `number` | 🟢 High (~99%) | Main cover image URL, full array of high-resolution `1440x960` photo URLs, and total photo count. |
| `scrapedAt` | `string` | 🟢 High (100%) | ISO 8601 extraction timestamp. |

***

### 🔁 Pagination & 1,000+ scale

- **15 Listings per Search Page, Unlimited Depth** — for every selected city or custom search URL, the scraper steps through `search_result=1, 2, 3...` until it collects enough unique listing URLs to satisfy your `maxItems` target (up to 500–1,000+ search pages) or reaches the last page of results.
- **Multi-City Aggregation & Deduplication** — when you select multiple cities in `areas` (or pass multiple `searchUrls`), the scraper automatically transitions from city to city and deduplicates every property URL via an in-memory `seenDetail` set.
- **Configurable Parallel Detail Fetching** — once listing URLs are gathered, detail pages are fetched in parallel batches controlled by `maxConcurrency` (up to 30 concurrent requests).

***

### ⚙️ How to use (Console & API)

#### In Apify Console

1. Open **[Funda.nl Scraper](https://apify.com/haketa/funda-scraper)** in Apify Console.
2. Select **Listing type** (`For sale (koop)` or `For rent (huur)`) and pick one or more cities in **Cities** — or paste a filtered URL into **Funda search URLs**.
3. Set **Max items** (e.g., `15` or `30` for a quick test, `500`–`1000` for a deep dataset, or `0` for all listings).
4. Click **Start** and download your dataset as **JSON, CSV, or Excel** from the **Storage** tab.

#### Via Apify API (Python)

```python
from apify_client import ApifyClient

client = ApifyClient("YOUR_APIFY_TOKEN")

run_input = {
    "listingType": "koop",
    "areas": ["amsterdam", "utrecht"],
    "sortBy": "date_down",
    "maxItems": 200,
}

run = client.actor("haketa/funda-scraper").call(run_input=run_input)

for item in client.dataset(run["defaultDatasetId"]).iterate_items():
    print(f"{item['address']} ({item['postalCode']} {item['city']}) — €{item['price']} | {item['livingArea']} m² | Label {item['energyLabel']}")
```

***

### 💡 Pro tips for Dutch property data

- **Use `searchUrls` for hyper-specific filters** — configure any combination of filters on `funda.nl` (e.g., *vraagprijs €300.000–€600.000*, *woonoppervlakte 75+ m²*, *tuin*, *energielabel A+*) and copy the URL into `searchUrls`. The scraper preserves every query parameter while paginating automatically.
- **Target specific neighbourhoods with `customAreas`** — pass `"amsterdam/de-pijp"`, `"amsterdam/jordaan"`, or `"rotterdam/kralingen-west"` in `customAreas` to isolate high-demand sub-markets.
- **Keep `UNBLOCKER` proxy enabled** — Funda protects its pages with strict anti-bot interstitials that block standard datacenter and residential proxies. The default `UNBLOCKER` configuration handles challenge resolution automatically.

***

### ⚠️ Honest limitations

- **Throughput & Proxy Cost (`UNBLOCKER`)** — because each property detail page is routed through Apify's anti-blocking proxy (`UNBLOCKER`, ~3–7s per batch), scraping 15–30 listings takes ~1–2 minutes. Scale `maxItems` and `maxConcurrency` according to your budget and time requirements.
- **Broker Name Availability** — Funda often loads the human-readable broker name asynchronously on the client side while always embedding the numeric `brokerId` (`hoofdaanbieder`) in the server-rendered state. `brokerId` is ~99% populated; `brokerName` is populated whenever present in the SSR state.

***

### ❓ FAQ

#### Can I scrape both homes for sale (*koop*) and rentals (*huur*)?

Yes. Set `listingType` to `"koop"` for sale listings or `"huur"` for rentals, or paste any `/zoeken/koop` or `/zoeken/huur` URL into `searchUrls`.

#### How many Funda listings can I extract in one run?

You can collect **1,000+ listings** in a single run across one or multiple Dutch cities. Set `maxItems: 1000` (or `0` for unlimited) and increase `timeoutSecs` when running multi-thousand-item jobs over `UNBLOCKER`.

#### Do I need a Funda account or login?

No. All extracted listings are public property pages on `funda.nl`. No login, cookies, or API keys are required.

#### Why are `plotArea` or `leasehold` sometimes `null`?

Apartments (*appartementen*) do not have an individual land plot (`plotArea: null`), and ground-lease (`leasehold`) details are only populated when structured in the listing's state object.

#### Which export formats are supported?

Export your dataset to **JSON, CSV, Excel (XLSX), HTML, XML, or RSS**, or integrate directly with **Google Sheets, Make, Zapier, n8n, Airbyte, and webhooks** via the Apify API.

#### How can I find the exact Funda slug for a smaller Dutch town or neighbourhood?

Open [funda.nl](https://www.funda.nl/), search for your desired town or neighbourhood, and look at the `selected_area` parameter in your browser's address bar (for example, `selected_area=["amsterdam/de-pijp"]` or `selected_area=["gouda"]`). Copy that string (`amsterdam/de-pijp` or `gouda`) into the `customAreas` input field, or simply paste the entire browser URL into `searchUrls`.

#### Via Apify API (JavaScript / Node.js)

```javascript
import { ApifyClient } from 'apify-client';

const client = new ApifyClient({ token: 'YOUR_APIFY_TOKEN' });

const run = await client.actor('haketa/funda-scraper').call({
    listingType: 'koop',
    areas: ['amsterdam', 'rotterdam'],
    sortBy: 'date_down',
    maxItems: 100,
});

const { items } = await client.dataset(run.defaultDatasetId).listItems();
console.log(`Extracted ${items.length} Dutch property listings from Funda.nl.`);
```

***

### 🔌 Integrations & Dutch PropTech automation

| Integration | Dutch Real-Estate Workflow |
| :--- | :--- |
| **Google Sheets** | Automatically append newly listed Amsterdam, Rotterdam, and Utrecht homes (`sortBy: "date_down"`) to a live investment tracker. |
| **Make / Zapier / n8n** | Trigger instant Slack, Telegram, or email alerts whenever a property matching your target postal code and energy label (`A` or higher) is listed. |
| **BigQuery / Snowflake / Postgres** | Schedule weekly Randstad runs to track Dutch asking prices per square meter (`price / livingArea`) and time-on-market transitions (`beschikbaar` → `onder bod`). |
| **Webhooks** | Connect an `ACTOR.RUN.SUCCEEDED` webhook to ingest structured Funda JSON directly into your PropTech or valuation backend. |

***

### 🔗 Related scrapers

Explore our other European property scrapers on Apify:

- [ImmobilienScout24 Scraper — Germany Real Estate](https://apify.com/haketa/immobilienscout24-scraper)
- [Marktplaats.nl Scraper — Netherlands Classifieds](https://apify.com/haketa/marktplaats-scraper)
- [Hemnet.se Scraper — Sweden Real Estate](https://apify.com/haketa/hemnet-scraper)
- [Boliga.dk Scraper — Denmark Real Estate](https://apify.com/haketa/boliga-scraper)
- [Otodom.pl Scraper — Poland Real Estate](https://apify.com/haketa/otodom-scraper)
- [Daft.ie Scraper — Ireland Real Estate](https://apify.com/haketa/daft-scraper)

***

### 📋 Changelog

#### v1.2 (2026-11) — Unlocked 1,000+ Deep Pagination & Concurrency Scaling

- **Unlocked 1,000+ Pagination**: Scaled `maxSearchPages` dynamically (`Math.max(500, Math.ceil(limit / 15) * 2)`) and unlocked `maxConcurrency` up to `30` in `src/main.js` to match the input schema.
- **Faster Request Timeout & Retry Recovery**: Tuned per-attempt request timeout to `35s` with rapid proxy rotation so slow anti-blocking nodes never stall a batch.
- **Fast Prefill Verification**: Configured `maxItems` prefill (`15`, default `30`) with `maxConcurrency: 15` so default test runs complete reliably in ~90–120 seconds.
- **Documentation Upgrade**: Added `⚡ At a glance` summary table, emoji-grouped field coverage tables, Dutch real-estate tips, and changelog.

#### v1.1 (2026-10) — Anti-Blocking (`UNBLOCKER`) & Nuxt 3 Devalue Parser

- Upgraded transport and default proxy configuration to `UNBLOCKER` with automatic interstitial detection and retry.
- Added recursive Nuxt 3 devalue payload decoder for 35+ property and sustainability fields.

#### v1.0 (2026-05) — Initial Release

- Initial release of Funda.nl Scraper supporting `koop` and `huur` searches across 25 Dutch cities.

# Changelog

This Actor's version history is a separate document: https://apify.com/haketa/funda-scraper/changelog.md

# Actor input Schema

## `listingType` (type: `string`):

Whether to collect homes for sale (koop) or homes for rent (huur). Applies to the cities you pick below.

## `areas` (type: `array`):

Pick one or more Dutch cities to collect listings from. Each city is searched separately. Leave empty to get a mixed sample from the biggest cities in the Netherlands. Need a smaller neighbourhood or a town that isn't listed here? Use the <b>Other cities / neighbourhoods</b> box below.

## `customAreas` (type: `array`):

Optional. Add any Funda area you don't see in the dropdown, e.g. a smaller town (<code>gouda</code>) or a neighbourhood (<code>amsterdam/centrum</code>). Tip: search on funda.nl, then copy the area name from the address bar.

## `sortBy` (type: `string`):

Order in which listings are collected for city searches.

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

Optional. Paste full Funda.nl search-result URLs (e.g. <code>https://www.funda.nl/zoeken/koop?selected_area=\["amsterdam"]\&price="250000-500000"</code>). Build any filter on funda.nl (price, surface, rooms, energy label…) and paste the URL here — all filters are respected and pagination is handled automatically.

## `startUrls` (type: `array`):

Optional. Paste direct Funda listing URLs (e.g. <code>https://www.funda.nl/detail/koop/amsterdam/appartement-koningsstraat-42/44468743/</code>) to scrape specific properties at full detail.

## `maxItems` (type: `integer`):

Maximum number of listings to scrape across the whole run. Use this to control cost. Set 0 for no limit.

## `maxConcurrency` (type: `integer`):

Maximum number of pages scraped in parallel. Keep this moderate to stay polite to Funda and get reliable results.

## `maxRequestRetries` (type: `integer`):

How many times a failed request is retried before being marked as failed.

## `proxyConfiguration` (type: `object`):

Proxy settings. Funda.nl is protected by DataDome anti-bot, so this Actor defaults to Apify's anti-blocking proxy group (<code>UNBLOCKER</code>), which reliably bypasses the challenge. Keep this default for best results; residential or datacenter proxies are usually blocked.

## Actor input object example

```json
{
  "listingType": "koop",
  "areas": [
    "amsterdam"
  ],
  "customAreas": [
    "gouda",
    "amsterdam/centrum"
  ],
  "sortBy": "relevancy",
  "maxItems": 15,
  "maxConcurrency": 15,
  "maxRequestRetries": 3,
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "UNBLOCKER"
    ]
  }
}
```

# Actor output Schema

## `datasetItems` (type: `string`):

All extracted property listings for this run.

## `overviewTable` (type: `string`):

A clean, human-readable table view of the scraped listings.

# 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 = {
    "areas": [
        "amsterdam"
    ],
    "maxItems": 15,
    "maxConcurrency": 15,
    "proxyConfiguration": {
        "useApifyProxy": true,
        "apifyProxyGroups": [
            "UNBLOCKER"
        ]
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("haketa/funda-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 = {
    "areas": ["amsterdam"],
    "maxItems": 15,
    "maxConcurrency": 15,
    "proxyConfiguration": {
        "useApifyProxy": True,
        "apifyProxyGroups": ["UNBLOCKER"],
    },
}

# Run the Actor and wait for it to finish
run = client.actor("haketa/funda-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 '{
  "areas": [
    "amsterdam"
  ],
  "maxItems": 15,
  "maxConcurrency": 15,
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "UNBLOCKER"
    ]
  }
}' |
apify call haketa/funda-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,haketa/funda-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/PC6hypOAxNHSwZUVg/builds/jlUUm3QhRAdfxImfv/openapi.json
