# Funda in Business Scraper — Dutch Commercial Property (`studio-amba/fundainbusiness-scraper`) Actor

Scrape Dutch commercial real estate from Funda in Business: kantoren, winkels, bedrijfshallen, bouwgrond, horeca, beleggingen for rent or sale. Prices with k.k./v.o.n. qualifiers, rents per month or EUR/m2/jaar, surfaces, brokers, photos. Search any Dutch city, no login needed.

- **URL**: https://apify.com/studio-amba/fundainbusiness-scraper.md
- **Developed by:** [Studio Amba](https://apify.com/studio-amba) (community)
- **Categories:** Real estate
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $20.00 / 1,000 result scrapeds

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.

Learn more: https://docs.apify.com/platform/actors/running/actors-in-store#pay-per-event

## What's an Apify Actor?

Actors are web data automations that power AI and operations. They run on the Apify platform to scrape websites, process data, connect APIs, and automate workflows.
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.
Actors are written with capital "A".

## 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.
The best way to integrate Actors is as follows.

- **AI agents and MCP clients** — the [Apify MCP server](https://docs.apify.com/integrations/mcp.md) at `https://mcp.apify.com` (remote, streamable HTTP, OAuth on first use).
- **Agentic workflows and local Actor development** — [Agent Skills](https://apify.com/.well-known/agent-skills/index.json) with the [Apify CLI](https://docs.apify.com/cli/docs.md): `npm install -g apify-cli`, then `apify login`.
- **JavaScript/TypeScript projects** — the official [JS/TS client](https://docs.apify.com/api/client/js/docs.md): `npm install apify-client`.
- **Python projects** — the official [Python client](https://docs.apify.com/api/client/python/docs.md): `pip install apify-client`.
- **Any other language** — the [REST API](https://docs.apify.com/api/v2.md).

For usage examples, see the [API](#api) section below.

For more details, see Apify documentation as [Markdown index](https://docs.apify.com/llms.txt) and [Markdown full-text](https://docs.apify.com/llms-full.txt).

# README

## Funda in Business Scraper

Extract commercial real estate listings from [fundainbusiness.nl](https://www.fundainbusiness.nl), the commercial arm of Funda, the Netherlands' largest property portal. Around 25,000 active listings: kantoren (offices), winkels (retail), bedrijfshallen (industrial), bouwgrond (building plots), horeca and beleggingen (investment properties), for rent or for sale, across every Dutch city.

No login, no cookies, no API key. You give it a city, it returns structured JSON.

### Why use this actor

- **Prices the way Dutch commercial real estate quotes them.** Sale prices keep their k.k. (kosten koper) or v.o.n. (vrij op naam) qualifier in a separate field. Rents come as the site publishes them: per month or in EUR per m² per year, and the actor also derives the EUR/m2/jaar figure from monthly rents and surfaces so you can compare listings on one number.
- **The published wording is never thrown away.** Every row carries `priceText` exactly as it appears on the site, next to the parsed numeric fields. When parsing and source ever disagree, you can see it.
- **Honest price handling.** Price on application (op aanvraag) is normal in this vertical. Those listings come through with `price: null` and `priceOnRequest: true` instead of a fake zero.
- **Built for reliability.** The actor detects Funda's verification page by content, retires the session and retries with a fresh one. It fails loudly on zero results instead of reporting a successful empty run.

Typical uses: market rent studies per city, deal sourcing for investors and brokers, monitoring new supply in a segment, feeding valuation models with EUR/m2/jaar comparables, tracking broker inventory.

### Input

| Field | Type | Default | Description |
|---|---|---|---|
| `searchQuery` | string | whole country | Dutch city or municipality: `Amsterdam`, `Rotterdam`, `Den Haag`, `Eindhoven`. Empty or `heel-nederland` searches all of the Netherlands |
| `listingType` | string | `both` | `rent` (huur), `sale` (koop) or `both` |
| `segment` | string | `any` | `office` (kantoor), `retail` (winkel), `industrial` (bedrijfshal), `land` (bouwgrond), `hospitality` (horeca), `investment` (belegging) or `any` |
| `maxResults` | integer | `100` | Cap on returned listings |
| `proxyConfiguration` | object | NL residential | Keep the default. Funda serves a verification page to datacenter IPs |

Example input, offices for rent in Amsterdam:

```json
{
    "searchQuery": "Amsterdam",
    "listingType": "rent",
    "segment": "office",
    "maxResults": 100
}
```

Example input, building plots for sale in Rotterdam:

```json
{
    "searchQuery": "Rotterdam",
    "listingType": "sale",
    "segment": "land",
    "maxResults": 50
}
```

### Output

One JSON object per listing. Key fields:

| Field | Example | Description |
|---|---|---|
| `title` | `"Cruquiusweg 100-E, Amsterdam"` | Address plus city, as published |
| `segment` | `"office"` | office, retail, industrial, land, hospitality, investment |
| `propertyTypes` | `["Bedrijfshal", "Kantoor"]` | The site's Dutch property types for this listing |
| `listingType` | `"rent"` | rent or sale |
| `price` | `11250` | Amount to read together with `priceUnit`. Null if on application |
| `priceText` | `"€ 11.250 /mnd"` | Price exactly as published, qualifiers included |
| `priceUnit` | `"EUR/maand"` | `EUR` (sale total), `EUR/maand`, `EUR/jaar` or `EUR/m2/jaar` |
| `priceQualifier` | `"k.k."` | Sale qualifier: k.k. or v.o.n., kept from the source |
| `priceMonthly` / `priceYearly` | `11250` / `135000` | Rent totals in EUR |
| `pricePerSquareMeterYear` | `250` | Rent in EUR/m2/jaar, quoted or derived |
| `surface` | `232` | Floor area or plot size in m² (Oppervlakte) |
| `unitsFrom` | `120` | Smallest rentable unit in m², for divisible buildings |
| `city` | `"Amsterdam"` | Location |
| `isNearbyResult` | `false` | True when the site returned this listing from a nearby municipality instead of the searched one |
| `agentName` | `"Keij & Stefels B.V."` | Listing broker (makelaar) |
| `url` | `https://www.fundainbusiness.nl/kantoor/amsterdam/object-43884892-cruquiusweg-100-e/` | Detail page |

Full example record:

```json
{
    "id": "7439439",
    "tinyId": "43884892",
    "title": "Cruquiusweg 100-E, Amsterdam",
    "address": "Cruquiusweg 100-E",
    "city": "Amsterdam",
    "segment": "office",
    "propertyTypes": ["Kantoor"],
    "listingType": "sale",
    "price": 1195000,
    "priceText": "€ 1.195.000 k.k.",
    "priceUnit": "EUR",
    "currency": "EUR",
    "priceQualifier": "k.k.",
    "priceOnRequest": false,
    "priceIsFrom": false,
    "priceMonthly": null,
    "priceYearly": null,
    "pricePerSquareMeterYear": null,
    "surface": 232,
    "unitsFrom": null,
    "agentName": "Keij & Stefels B.V.",
    "agentUrl": "https://www.fundainbusiness.nl/makelaar/24463-keij-en-stefels-bv/",
    "imageUrl": "https://cloud.funda.nl/valentina_media/204/274/875_720x480.jpg",
    "isNearbyResult": false,
    "url": "https://www.fundainbusiness.nl/kantoor/amsterdam/object-43884892-cruquiusweg-100-e/",
    "source": "fundainbusiness",
    "scrapedAt": "2026-08-18T09:00:00.000Z"
}
```

### How to scrape Funda in Business data

1. Open the actor on Apify and press **Try for free**.
2. Enter a Dutch city in `searchQuery`, for example `Amsterdam` or `Utrecht`.
3. Pick `listingType` (`rent` or `sale`) and a `segment`, for example `office` for kantoren.
4. Press **Start**. The run fetches search result pages (15 listings per page) and stops at `maxResults`.
5. Export the dataset as JSON, CSV or Excel from the **Storage** tab, or pull it through the Apify API.

The same works from code with the Apify client libraries for JavaScript and Python; pass the input object shown above.

### Pricing and cost per result

The actor charges per result (pay per event): $0.02 per listing plus a small run start fee. A 100-listing run costs about $2 plus a few cents of proxy and compute usage. Residential proxy traffic is kept low because images, fonts and media are never downloaded.

Note that a run's usage cost only settles after the run reaches the SUCCEEDED state; the figure shown while the run is still going is not final.

### Limitations

- One query covers one municipality (or the whole country with `heel-nederland`). For a multi-city sweep, loop the actor over a city list.
- When a search has little or no supply (bouwgrond in a single city, for example), the site itself fills the page with listings from nearby municipalities. Those rows come through with `isNearbyResult: true` so you can filter them out.
- The actor reads search result cards. Detail-page extras (full descriptions, energy labels, all photos) are not included; open an issue if you need detail enrichment.
- Price on application listings have `price: null`. That is the advertiser's choice, not missing data; `priceOnRequest` is `true` on those rows.
- Funda protects its pages with a verification challenge. The default Dutch residential proxy configuration handles this; switching to datacenter proxies will get the run blocked.
- Sold and rented-out archive listings (verkocht/verhuurd) are not part of a normal search and are not returned.

### FAQ

**Does it cover all of the Netherlands?** Yes. Any municipality the site serves, from Amsterdam to small towns, plus a whole-country mode.

**Why do some rents come per month and others per m² per year?** That is how the advertisers publish them. The actor keeps the original quote in `priceText` and `priceUnit`, and derives `pricePerSquareMeterYear` where the surface allows it, so both styles end up comparable.

**What is the difference between k.k. and v.o.n.?** Dutch sale-price qualifiers. K.k. (kosten koper) means the buyer pays transfer costs; v.o.n. (vrij op naam) means they are included. The actor preserves the qualifier instead of silently dropping it.

# Actor input Schema

## `searchQuery` (type: `string`):

Dutch city or municipality to search, e.g. 'Amsterdam', 'Rotterdam', 'Den Haag', 'Eindhoven'. Use 'heel-nederland' (or leave empty) for the whole country. The value is converted to the site's URL slug, so accents and spaces are fine.

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

For rent (huur), for sale (koop), or both.

## `segment` (type: `string`):

Commercial segment as Funda in Business defines them. 'Any' searches the full offer (alle bedrijfsaanbod). Office = kantoor, retail = winkel, industrial = bedrijfshal, land = bouwgrond, hospitality = horeca, investment = belegging.

## `maxResults` (type: `integer`):

Maximum number of listings to return. The site serves 15 listings per page; the actor stops as soon as this cap is reached.

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

Funda serves a verification page to datacenter IPs and plain HTTP clients (see docs/site-recon/fundainbusiness.md). Dutch RESIDENTIAL proxy is required for reliable runs.

## Actor input object example

```json
{
  "searchQuery": "Amsterdam",
  "listingType": "rent",
  "segment": "office",
  "maxResults": 20,
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "RESIDENTIAL"
    ],
    "apifyProxyCountry": "NL"
  }
}
```

# Actor output Schema

## `results` (type: `string`):

No description

# 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 = {
    "searchQuery": "Amsterdam",
    "listingType": "rent",
    "segment": "office",
    "maxResults": 20,
    "proxyConfiguration": {
        "useApifyProxy": true,
        "apifyProxyGroups": [
            "RESIDENTIAL"
        ],
        "apifyProxyCountry": "NL"
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("studio-amba/fundainbusiness-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 = {
    "searchQuery": "Amsterdam",
    "listingType": "rent",
    "segment": "office",
    "maxResults": 20,
    "proxyConfiguration": {
        "useApifyProxy": True,
        "apifyProxyGroups": ["RESIDENTIAL"],
        "apifyProxyCountry": "NL",
    },
}

# Run the Actor and wait for it to finish
run = client.actor("studio-amba/fundainbusiness-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 '{
  "searchQuery": "Amsterdam",
  "listingType": "rent",
  "segment": "office",
  "maxResults": 20,
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "RESIDENTIAL"
    ],
    "apifyProxyCountry": "NL"
  }
}' |
apify call studio-amba/fundainbusiness-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,studio-amba/fundainbusiness-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/7ACN7IGbrUHU8SlQn/builds/HdY6s6pYzyCAHSJKL/openapi.json
