# Changelog of Funda Netherlands Real Estate Scraper (`devilscrapes/funda-netherlands-real-estate-scraper`) Actor

- **URL**: https://apify.com/devilscrapes/funda-netherlands-real-estate-scraper/changelog.md
- **Full Actor documentation**: https://apify.com/devilscrapes/funda-netherlands-real-estate-scraper.md

## Changelog — funda-netherlands-real-estate-scraper

### \[Unreleased]

### 0.1 — 2026-08-13

Initial local-green build (T02–T11, T13) on top of the T01 scaffold and
T12 icon. Single-market Actor for funda.nl (Netherlands), sale (`koop`)
and rent (`huur`), summary (`enrich=False`) and full-detail
(`enrich=True`) modes.

- `src/models.py` — `ActorInput` (search_urls-or-location precedence,
  REQ-2/3/4) and `ResultRow` (20-field spec.md "Output Shape").
- `src/config.py` — search/detail URL templates, `koop`/`huur` slug map,
  kenmerken Dutch-label map, and the load-bearing `listing_id_from_url`
  rule (REQ-9): the numeric ID always comes from the detail-page URL
  path, never the page's own `ld+json` internal `id`, which the spec
  confirms can diverge on the same page.
- `src/geo_guard.py` — single-marker geo-splash guard (`www.funda.nl`
  host + `lang="nl` prefix) — funda.nl has no `og:locale` meta tag,
  unlike `idealista-property-scraper`'s two-marker table.
- `src/parser.py` — pure `ld+json` `ItemList` search extraction with
  card-text price/area regex, `Product`/`BreadcrumbList` + kenmerken
  `dt`/`dd` detail-page merge, REQ-9 regression-tested against a fixture
  whose URL-path ID deliberately diverges from its `ld+json` internal id.
- `src/scraper.py` — `FundaSession` (one curl-cffi session per run,
  impersonation-profile + session rotation on 408/429/503/network
  error/challenge page/geo-guard mismatch, exponential backoff 2s→30s
  capped, max 5 attempts), REQ-8's two fault-isolation granularities
  (page-fetch-exhausted-retries continues to the next page; a
  genuinely-empty page stops pagination; a bad listing is skipped),
  `max_results` pagination stop (REQ-16), run-wide dedup by `listing_id`
  (REQ-14).
- `src/main.py` — SDK wiring, `country_code="NL"` pinned as a literal
  module constant (REQ-10, never read from input), `actor-start`/
  `result-row` PPE charging, zero-rows-across-the-run fail-loud
  (REQ-13) with a raw-HTML KVS dump for debugging.
- `.actor/input_schema.json`, `dataset_schema.json`, `output_schema.json`,
  `pay_per_event.json` mirror `models.py` exactly; prefill validated by
  `scripts/verify_input_prefill.py`.
- `tests/fixtures/input.qa.json` authored (not executed — local-green
  scope gate, Apify account over its $5/mo cap until 2026-08-15).
- `README.md` (Devil Scrapes brand voice, 10 canonical H2 sections,
  names both incumbents — `easyapi/funda-nl-scraper`,
  `ivanvs/funda-scraper`) and `promo.json` (GTM manifest).
- 104 unit tests, all local — `ruff check` clean, `pyright` clean.
- **Deferred to publish time (on/after 2026-08-15, per the account's
  budget cap)**: `apify push`, `apify call`, cloud QA. No cloud/network
  calls were made building this Actor.
