# Belgium Property Pige — FSBO Real Estate Leads Across 4 Sources (`studio-amba/belgium-property-pige`) Actor

Find FSBO (private-owner) property leads in Belgium. Runs Immoweb, 2dehands, Immovlan and Zimmo, dedupes each property across portals by a postcode + surface + price fingerprint, and flags every result private-seller or agency-listed. New-listing delta and optional KBO agency enrichment.

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

## Pricing

from $20.00 / 1,000 private-seller leads

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 a software tools running on the Apify platform, for all kinds of web data extraction and automation use cases.
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.

In JavaScript/TypeScript projects, use official [JavaScript/TypeScript client](https://docs.apify.com/api/client/js/docs.md):

```bash
npm install apify-client
```

In Python projects, use official [Python client library](https://docs.apify.com/api/client/python/docs.md):

```bash
pip install apify-client
```

In shell scripts, use [Apify CLI](https://docs.apify.com/cli/docs.md):

````bash
# MacOS / Linux
curl -fsSL https://apify.com/install-cli.sh | bash
# Windows
irm https://apify.com/install-cli.ps1 | iex
```bash

In AI frameworks, you might use the [Apify MCP server](https://docs.apify.com/integrations/mcp.md).

If your project is in a different language, use 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

## Belgium Property Pige — FSBO Real Estate Leads

Find **private-owner property leads** ("particulier" — for sale or rent by owner) across the main Belgian real estate sources in one run. Belgium Property Pige runs Immoweb, 2dehands, Immovlan and Zimmo, deduplicates the same physical property across sources, and flags every result as sold/rented by a **private owner** or by an **agency**.

This is the lead Belgian agency prospection teams do manually today: finding owners selling or renting without a mandate, before a competing agency signs them.

### What it does

- **FSBO detection.** 2dehands is a general classifieds marketplace, so its "huizen-en-kamers" (houses and rooms) listings are private-individual by default. Every 2dehands listing without an agency name in the title or description becomes a candidate lead, with the seller's display name where exposed.
- **Cross-portal dedup.** The same property listed on more than one source is merged into a single row using a content fingerprint (postcode + property type + surface, then price proximity). No shared listing ID exists between Belgian portals, so the match is content-based.
- **Agency vs private classification.** Immoweb, Immovlan and Zimmo listings carry an agency name when listed by a professional; 2dehands listings carry an inferred private/professional flag. Everything is labelled `particulier`, `professionnel`, or `unknown`.
- **The absence signal.** A private 2dehands listing that does not appear on any agency portal you scraped in the same postcode is flagged `explicit_particulier_exclusive` — an owner who has not (yet) given a mandate. This signal only exists because the actor runs every source at once.
- **New-listing delta.** Turn on "only new since last run" and each run returns only properties not seen before, backed by a per-account store. Schedule it and you get a fresh-listings feed.
- **Optional agency enrichment.** Cross-reference agency-listed properties against the Belgian company registry (KBO/BCE) to attach agency phone and enterprise number.

### How to scrape Belgian property leads

1. Enter a **location** (city, e.g. `Brussel`, `Gent`, `Antwerpen`) and a matching **postal code** (e.g. `1000`).
2. Choose **sale** or **rent**, and optionally a property type.
3. Pick your **portals**. All four (Immoweb, 2dehands, Immovlan, Zimmo) is the default — that cross-source coverage is what makes the absence signal meaningful.
4. Set a **Belgian residential proxy** (recommended — Immoweb, Immovlan and Zimmo are anti-bot-protected).
5. Leave **seller filter** on `FSBO leads only` (the default) for a pure lead feed, or switch to `All` to see agency-listed properties too.
6. Optionally turn on **only new listings** for a delta feed, or **enrich agencies** to attach KBO phone/enterprise numbers.
7. Run it. Each row is one deduplicated property with its FSBO classification, price, surface, price per m², location, and per-source links.

Schedule the actor with "only new since last run" enabled to receive a rolling feed of fresh private-seller leads for your territory.

### Hoe particuliere vastgoedadvertenties opsporen (pige)

Belgium Property Pige doet de **pige immobiliere** automatisch. Het doorzoekt Immoweb, 2dehands, Immovlan en Zimmo voor een stad en postcode, dedupliceert hetzelfde pand als het op meerdere bronnen verschijnt, en onderscheidt **advertenties van particulieren** van **advertenties van makelaars**.

- **Particuliere leads.** 2dehands is een algemene kleinadvertentiesite, dus vastgoedadvertenties zonder makelaarsnaam worden standaard als particulier beschouwd.
- **Het afwezigheidssignaal.** Een particuliere 2dehands-advertentie die niet voorkomt op een makelaarsportaal in dezelfde postcode wijst op een eigenaar zonder mandaat — het doel van de pige.
- **Delta van nieuwe advertenties.** Zet "alleen nieuwe advertenties" aan en plan de actor in om dagelijks nieuwe leads te ontvangen.
- **Makelaarsverrijking.** Optionele koppeling met het KBO/BCE om telefoonnummer en ondernemingsnummer van de makelaar op te halen.

Beschikbare velden: type pand, oppervlakte, aantal slaapkamers, prijs, prijs per m², postcode, gemeente, EPC-score indien aanwezig, type verkoper (particulier / professioneel), en links naar elke bron.

### Sources and reliability (method disclosure)

| Source | Method | Reliability | Notes |
|---|---|---|---|
| **2dehands** | Open JSON API | High | The FSBO anchor. No structured surface (m²) field, so its leads often stand alone rather than cross-matching. |
| **Immoweb** | Playwright (window.classified) | Medium-High | Belgium's largest property portal. Agency-heavy; a missing agency name is a candidate signal only. |
| **Zimmo** | Playwright + Cloudflare | Medium | Belgium's #2 property portal. Needs a Belgian residential proxy. |
| **Immovlan** | HTTP + Cheerio | Medium | Akamai bot protection; can intermittently return sparse pages. |

The actor degrades gracefully: if a source fails, the run continues with the others and records which sources succeeded in the run summary.

### Documented limits

- **FSBO detection depends on 2dehands.** It is the only source with a (inferred) private-seller signal. If 2dehands is blocked on a run, the FSBO count reflects that, not a lack of private inventory — the run summary sets `fsboSourceOk: false` and logs a warning.
- **2dehands lacks a structured surface field.** Its listings can rarely cross-match agency listings by surface, so most of its leads appear as standalone rows rather than "cross-listed" — this is expected, not a bug.
- **2dehands lacks an explicit sale/rent flag.** Its listings inherit the requested transaction type rather than exposing their own; "huizen-en-kamers" skews toward rentals.
- **No shared listing ID.** Cross-portal matching is content-based (postcode + type + surface + price), so it is high-precision but not exhaustive.
- **Seller-type inference on 2dehands is heuristic**, not an explicit flag: it checks the title and description for agency keywords (makelaar, immo, vastgoed, agence, agentschap). A private seller who mentions "via een makelaar" in the text could be misclassified; this is rare.

### Output fields

Each row is one deduplicated property:

- `isFsbo`, `fsboConfidence`, `sellerType` — the FSBO classification
- `isNew`, `firstSeenAt` — the run-over-run delta
- `crossListed`, `portalCount`, `sourcePortals`, `listings[]` — cross-portal presence and per-portal detail
- `priceEur`, `priceMinEur`, `priceMaxEur`, `priceSpreadPct`, `pricePerM2` — pricing
- `surfaceM2`, `bedrooms`, `propertyType` — the property
- `postalCode`, `city`, `latitude`, `longitude` — location
- `agencyName`, `agencyPhone`, `agencyEnterpriseNumber`, `agencyMatchedKbo` — agency detail (phone/enterprise number when enrichment is on)
- `sellerName`, `epcScore` — seller and energy detail

### Example output

```json
{
  "isFsbo": true,
  "fsboConfidence": "explicit_particulier_exclusive",
  "sellerType": "particulier",
  "isNew": true,
  "crossListed": false,
  "sourcePortals": ["2dehands"],
  "propertyType": "apartment",
  "listingTitle": "Te huur: gemeubeld appartement centrum Gent",
  "priceEur": 950,
  "surfaceM2": null,
  "postalCode": "9000",
  "city": "Gent",
  "sellerName": "Marie",
  "epcScore": null,
  "listings": [
    { "portal": "2dehands", "url": "https://www.2dehands.be/v/...", "priceEur": 950, "sellerType": "particulier" }
  ]
}
````

### How cross-portal dedup works

Belgian portals share no common listing identifier, so the same flat on Immoweb and on Zimmo has two unrelated IDs. Belgium Property Pige matches on the property itself:

1. **Coarse bucket** — same postcode and same normalized property type.
2. **Surface proximity** — within ±2 m² or ±3% (portals routinely report the same flat with a slightly different m²).
3. **Price proximity** — within ±5% (the same property is often relisted at a slightly different asking price per portal).

A property that clears all three is one row with `crossListed: true` and every source in `sourcePortals`. Listings without a postcode and surface cannot be matched safely and stay as their own row — this is the normal case for most 2dehands leads.

### Who uses this

- **Agency prospection teams** running daily pige to reach owners before a competitor signs the mandate.
- **Investors and landlords** filtering on FSBO plus location or price per m².
- **Proptech and market-analysis teams** needing a deduplicated, cross-source view of local inventory.

### Pricing

Pay per result. You pay for the run start and for each private-seller lead returned (the default output). Switching seller filter to `All` or `Agency-listed only` returns other rows too, but Apify's per-item pricing charges the same rate per row regardless of type. See the pricing tab for current rates.

### FAQ

**Which source covers FSBO best?**
2dehands. Belgian private sellers and landlords concentrate there. Keep 2dehands selected for any FSBO run.

**Can I get only the private-seller leads?**
Yes — that's the default. Seller filter is `FSBO leads only` unless you change it.

**How do I get a feed of only new listings?**
Turn on "only new listings since last run" and schedule the actor. The per-account store remembers what it has already returned.

**Do I need a proxy?**
Yes, a Belgian residential proxy is strongly recommended. The default input is configured for one.

**Is this legal?**
The actor collects publicly listed advertisements. You are responsible for how you use the leads, including Belgian prospection and GDPR rules.

### Need this data on a schedule, or a custom version?

We run this scraper as a managed service for businesses: scheduled runs, deduplication, delta detection, and delivery to your inbox, Google Sheets, or API — maintenance included. We can also build a custom version with your exact fields and filters.

See [studioamba.dev/services](https://studioamba.dev/services/) or email <hello@studioamba.dev> for a free data sample. We maintain 300+ European web scrapers and answer within one business day.

# Actor input Schema

## `location` (type: `string`):

Belgian city or municipality to search, e.g. 'Brussel', 'Gent', 'Antwerpen', 'Luik'. Drives Immoweb, Immovlan and Zimmo.

## `postalCode` (type: `string`):

Belgian 4-digit postal code matching the location, e.g. '1000' for Brussels. Drives 2dehands (postcode-based search) and is used to tag its listings, which don't expose a postcode field of their own.

## `transactionType` (type: `string`):

Sale (te koop) or rent (te huur).

## `propertyType` (type: `string`):

Restrict to one property type. Leave empty for all types.

## `portals` (type: `array`):

Which Belgian sources to run and deduplicate across. 2dehands is the FSBO anchor (a general classifieds marketplace, listings are private-individual by default). Immoweb, Immovlan and Zimmo are agency-dominated portals used for the cross-portal 'absent from every agency portal' signal. Default is all four.

## `sellerFilter` (type: `string`):

Default 'FSBO leads only' returns just private-seller leads — this matches the per-lead pricing. 'All' or 'Agency-listed only' return other rows too, but are still charged at the same per-row rate (Apify's per-item pricing can't tell them apart).

## `onlyNew` (type: `boolean`):

Return only properties not seen in a previous run. Backed by a per-account key-value store. Leave off for a full snapshot.

## `enrichAgencies` (type: `boolean`):

Cross-reference agency-listed properties against the Belgian company registry (KBO/BCE) to attach agency phone and enterprise number. Adds extra child-actor calls, so runs take longer. Off by default.

## `minPrice` (type: `integer`):

Lower price bound, passed to the sources that support it (2dehands, Immovlan). Leave empty for no minimum.

## `maxPrice` (type: `integer`):

Upper price bound, passed to the sources that support it (2dehands, Immovlan). Leave empty for no maximum.

## `maxItemsPerSource` (type: `integer`):

Cap on listings pulled from each source before dedup. Immoweb and Zimmo fetch detail pages one at a time (Playwright, no concurrency), so large values here need a matching increase to the per-source timeout below.

## `timeoutPerSourceSecs` (type: `integer`):

How long to wait for each source run before treating it as failed. Immoweb/Zimmo need roughly 10-13s per item (sequential detail-page fetches) — budget accordingly for larger maxItemsPerSource values.

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

Passed through to the child scrapers. Belgian residential proxy is strongly recommended (Immoweb, Immovlan and Zimmo are anti-bot-protected).

## Actor input object example

```json
{
  "location": "Gent",
  "postalCode": "9000",
  "transactionType": "sale",
  "propertyType": "",
  "portals": [
    "immoweb",
    "2dehands",
    "immovlan",
    "zimmo"
  ],
  "sellerFilter": "fsbo_only",
  "onlyNew": false,
  "enrichAgencies": false,
  "maxItemsPerSource": 10,
  "timeoutPerSourceSecs": 150,
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "RESIDENTIAL"
    ],
    "apifyProxyCountry": "BE"
  }
}
```

# 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 = {
    "location": "Brussel",
    "postalCode": "1000",
    "transactionType": "sale",
    "portals": [
        "immoweb",
        "2dehands",
        "immovlan",
        "zimmo"
    ],
    "sellerFilter": "fsbo_only",
    "maxItemsPerSource": 10,
    "timeoutPerSourceSecs": 150,
    "proxyConfiguration": {
        "useApifyProxy": true,
        "apifyProxyGroups": [
            "RESIDENTIAL"
        ],
        "apifyProxyCountry": "BE"
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("studio-amba/belgium-property-pige").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 = {
    "location": "Brussel",
    "postalCode": "1000",
    "transactionType": "sale",
    "portals": [
        "immoweb",
        "2dehands",
        "immovlan",
        "zimmo",
    ],
    "sellerFilter": "fsbo_only",
    "maxItemsPerSource": 10,
    "timeoutPerSourceSecs": 150,
    "proxyConfiguration": {
        "useApifyProxy": True,
        "apifyProxyGroups": ["RESIDENTIAL"],
        "apifyProxyCountry": "BE",
    },
}

# Run the Actor and wait for it to finish
run = client.actor("studio-amba/belgium-property-pige").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print("💾 Check your data here: https://console.apify.com/storage/datasets/" + run["defaultDatasetId"])
for item in client.dataset(run["defaultDatasetId"]).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{
  "location": "Brussel",
  "postalCode": "1000",
  "transactionType": "sale",
  "portals": [
    "immoweb",
    "2dehands",
    "immovlan",
    "zimmo"
  ],
  "sellerFilter": "fsbo_only",
  "maxItemsPerSource": 10,
  "timeoutPerSourceSecs": 150,
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "RESIDENTIAL"
    ],
    "apifyProxyCountry": "BE"
  }
}' |
apify call studio-amba/belgium-property-pige --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "command": "npx",
            "args": [
                "mcp-remote",
                "https://mcp.apify.com/?tools=studio-amba/belgium-property-pige",
                "--header",
                "Authorization: Bearer <YOUR_API_TOKEN>"
            ]
        }
    }
}

```

## OpenAPI specification

```json
{
    "openapi": "3.0.1",
    "info": {
        "title": "Belgium Property Pige — FSBO Real Estate Leads Across 4 Sources",
        "description": "Find FSBO (private-owner) property leads in Belgium. Runs Immoweb, 2dehands, Immovlan and Zimmo, dedupes each property across portals by a postcode + surface + price fingerprint, and flags every result private-seller or agency-listed. New-listing delta and optional KBO agency enrichment.",
        "version": "0.1",
        "x-build-id": "0QO3Xm6RrtjeOeFIV"
    },
    "servers": [
        {
            "url": "https://api.apify.com/v2"
        }
    ],
    "paths": {
        "/acts/studio-amba~belgium-property-pige/run-sync-get-dataset-items": {
            "post": {
                "operationId": "run-sync-get-dataset-items-studio-amba-belgium-property-pige",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor, waits for its completion, and returns Actor's dataset items in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK"
                    }
                }
            }
        },
        "/acts/studio-amba~belgium-property-pige/runs": {
            "post": {
                "operationId": "runs-sync-studio-amba-belgium-property-pige",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor and returns information about the initiated run in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/runsResponseSchema"
                                }
                            }
                        }
                    }
                }
            }
        },
        "/acts/studio-amba~belgium-property-pige/run-sync": {
            "post": {
                "operationId": "run-sync-studio-amba-belgium-property-pige",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor, waits for completion, and returns the OUTPUT from Key-value store in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK"
                    }
                }
            }
        }
    },
    "components": {
        "schemas": {
            "inputSchema": {
                "type": "object",
                "properties": {
                    "location": {
                        "title": "Location (city)",
                        "type": "string",
                        "description": "Belgian city or municipality to search, e.g. 'Brussel', 'Gent', 'Antwerpen', 'Luik'. Drives Immoweb, Immovlan and Zimmo.",
                        "default": "Brussel"
                    },
                    "postalCode": {
                        "title": "Postal code",
                        "type": "string",
                        "description": "Belgian 4-digit postal code matching the location, e.g. '1000' for Brussels. Drives 2dehands (postcode-based search) and is used to tag its listings, which don't expose a postcode field of their own.",
                        "default": "1000"
                    },
                    "transactionType": {
                        "title": "Transaction",
                        "enum": [
                            "sale",
                            "rent"
                        ],
                        "type": "string",
                        "description": "Sale (te koop) or rent (te huur).",
                        "default": "sale"
                    },
                    "propertyType": {
                        "title": "Property type (optional)",
                        "enum": [
                            "",
                            "apartment",
                            "house",
                            "land",
                            "parking",
                            "commercial",
                            "room"
                        ],
                        "type": "string",
                        "description": "Restrict to one property type. Leave empty for all types.",
                        "default": ""
                    },
                    "portals": {
                        "title": "Portals",
                        "type": "array",
                        "description": "Which Belgian sources to run and deduplicate across. 2dehands is the FSBO anchor (a general classifieds marketplace, listings are private-individual by default). Immoweb, Immovlan and Zimmo are agency-dominated portals used for the cross-portal 'absent from every agency portal' signal. Default is all four.",
                        "items": {
                            "type": "string",
                            "enum": [
                                "immoweb",
                                "2dehands",
                                "immovlan",
                                "zimmo"
                            ],
                            "enumTitles": [
                                "Immoweb",
                                "2dehands",
                                "Immovlan",
                                "Zimmo"
                            ]
                        },
                        "default": [
                            "immoweb",
                            "2dehands",
                            "immovlan",
                            "zimmo"
                        ]
                    },
                    "sellerFilter": {
                        "title": "Seller filter",
                        "enum": [
                            "fsbo_only",
                            "all",
                            "agency_only"
                        ],
                        "type": "string",
                        "description": "Default 'FSBO leads only' returns just private-seller leads — this matches the per-lead pricing. 'All' or 'Agency-listed only' return other rows too, but are still charged at the same per-row rate (Apify's per-item pricing can't tell them apart).",
                        "default": "fsbo_only"
                    },
                    "onlyNew": {
                        "title": "Only new listings since last run",
                        "type": "boolean",
                        "description": "Return only properties not seen in a previous run. Backed by a per-account key-value store. Leave off for a full snapshot.",
                        "default": false
                    },
                    "enrichAgencies": {
                        "title": "Enrich agencies via KBO/BCE",
                        "type": "boolean",
                        "description": "Cross-reference agency-listed properties against the Belgian company registry (KBO/BCE) to attach agency phone and enterprise number. Adds extra child-actor calls, so runs take longer. Off by default.",
                        "default": false
                    },
                    "minPrice": {
                        "title": "Min price (EUR)",
                        "type": "integer",
                        "description": "Lower price bound, passed to the sources that support it (2dehands, Immovlan). Leave empty for no minimum."
                    },
                    "maxPrice": {
                        "title": "Max price (EUR)",
                        "type": "integer",
                        "description": "Upper price bound, passed to the sources that support it (2dehands, Immovlan). Leave empty for no maximum."
                    },
                    "maxItemsPerSource": {
                        "title": "Max items per source",
                        "type": "integer",
                        "description": "Cap on listings pulled from each source before dedup. Immoweb and Zimmo fetch detail pages one at a time (Playwright, no concurrency), so large values here need a matching increase to the per-source timeout below.",
                        "default": 25
                    },
                    "timeoutPerSourceSecs": {
                        "title": "Per-source timeout (seconds)",
                        "type": "integer",
                        "description": "How long to wait for each source run before treating it as failed. Immoweb/Zimmo need roughly 10-13s per item (sequential detail-page fetches) — budget accordingly for larger maxItemsPerSource values.",
                        "default": 240
                    },
                    "proxyConfiguration": {
                        "title": "Proxy configuration",
                        "type": "object",
                        "description": "Passed through to the child scrapers. Belgian residential proxy is strongly recommended (Immoweb, Immovlan and Zimmo are anti-bot-protected).",
                        "default": {
                            "useApifyProxy": true,
                            "apifyProxyGroups": [
                                "RESIDENTIAL"
                            ],
                            "apifyProxyCountry": "BE"
                        }
                    }
                }
            },
            "runsResponseSchema": {
                "type": "object",
                "properties": {
                    "data": {
                        "type": "object",
                        "properties": {
                            "id": {
                                "type": "string"
                            },
                            "actId": {
                                "type": "string"
                            },
                            "userId": {
                                "type": "string"
                            },
                            "startedAt": {
                                "type": "string",
                                "format": "date-time",
                                "example": "2025-01-08T00:00:00.000Z"
                            },
                            "finishedAt": {
                                "type": "string",
                                "format": "date-time",
                                "example": "2025-01-08T00:00:00.000Z"
                            },
                            "status": {
                                "type": "string",
                                "example": "READY"
                            },
                            "meta": {
                                "type": "object",
                                "properties": {
                                    "origin": {
                                        "type": "string",
                                        "example": "API"
                                    },
                                    "userAgent": {
                                        "type": "string"
                                    }
                                }
                            },
                            "stats": {
                                "type": "object",
                                "properties": {
                                    "inputBodyLen": {
                                        "type": "integer",
                                        "example": 2000
                                    },
                                    "rebootCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "restartCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "resurrectCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "computeUnits": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            },
                            "options": {
                                "type": "object",
                                "properties": {
                                    "build": {
                                        "type": "string",
                                        "example": "latest"
                                    },
                                    "timeoutSecs": {
                                        "type": "integer",
                                        "example": 300
                                    },
                                    "memoryMbytes": {
                                        "type": "integer",
                                        "example": 1024
                                    },
                                    "diskMbytes": {
                                        "type": "integer",
                                        "example": 2048
                                    }
                                }
                            },
                            "buildId": {
                                "type": "string"
                            },
                            "defaultKeyValueStoreId": {
                                "type": "string"
                            },
                            "defaultDatasetId": {
                                "type": "string"
                            },
                            "defaultRequestQueueId": {
                                "type": "string"
                            },
                            "buildNumber": {
                                "type": "string",
                                "example": "1.0.0"
                            },
                            "containerUrl": {
                                "type": "string"
                            },
                            "usage": {
                                "type": "object",
                                "properties": {
                                    "ACTOR_COMPUTE_UNITS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_WRITES": {
                                        "type": "integer",
                                        "example": 1
                                    },
                                    "KEY_VALUE_STORE_LISTS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_INTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_EXTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_RESIDENTIAL_TRANSFER_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_SERPS": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            },
                            "usageTotalUsd": {
                                "type": "number",
                                "example": 0.00005
                            },
                            "usageUsd": {
                                "type": "object",
                                "properties": {
                                    "ACTOR_COMPUTE_UNITS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_WRITES": {
                                        "type": "number",
                                        "example": 0.00005
                                    },
                                    "KEY_VALUE_STORE_LISTS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_INTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_EXTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_RESIDENTIAL_TRANSFER_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_SERPS": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    }
}
```
