1.1.0 — Fail-fast on misconfigured proxies (2026-05-19)
Fixes the silent-timeout problem that caused 2 of 3 external runs in the first week to time out at 2 minutes with no useful error message.
new: preflight proxy validation in main.ts. If the user supplies a proxy config that wg-gesucht.de cannot use (no Apify Residential + no external proxyUrls), the Actor now calls Actor.fail() within ~3 seconds with a clear, actionable error message instead of letting the crawler spin to timeout.
new:failedRequestHandler watches the warm-up and first list page. If those fail after retries (the most common signal that a proxy is being blocked), the Actor fails the whole run immediately rather than continuing to burn compute on doomed downstream requests.
fix:proxy_config default was { groups, countryCode } (wrong shape) — switched to the canonical { useApifyProxy, apifyProxyGroups, apifyProxyCountry }.
docs: README now leads with a "⚠️ Before you run — proxy is required" banner. Input schema's proxy_config.description warns users about the Free-plan caveat before they click Start.
Why this matters: A Store visitor on the Free plan who accepted the default input would have all proxy creation fail silently or fall through to no-proxy crawling, hit wg-gesucht's anti-bot wall, and time out 2 minutes later — burning $1-2 of their $5/mo credits with zero output. Now they see a clear "you need Starter plan or your own DE-IP proxy" message in under 5 seconds.
1.0.0 — Store launch (2026-05-15)
First public release on the Apify Store.
Coverage: Berlin, Munich, Hamburg, Frankfurt, Cologne, Vienna, Zurich.
Output: WG-Zimmer listings only (Wohngemeinschaft / flat-share). Full apartments coming in v1.2.
Verified field fill-rate on a 10-record Berlin smoke run (build 0.1.4):
40%: available_until (rest are unbefristet / open-ended — normal)
Ground-truth verified: Spot-check on listing 9883205 (Berlin Wedding) matched every scraped field byte-for-byte against the live page.
Known caveats:
description field contains raw HTML whitespace from the source page. Use .trim().replace(/\s+/g, ' ') if you need a clean string.
contact_method is always in_app_message — wg-gesucht intermediates all contact, no direct phone/email is exposed.
photos array includes both full-size (.sized.JPEG) and thumbnail (.small.JPEG) URLs for the same image.
0.1.4 — internal (2026-05-15)
fix: Kosten panel parsing — switched from DOM heading walk to body-text regex with word boundaries. rent_kalt_eur now 100%, utilities_eur 90%, deposit_eur 60% (was all 0%).
0.1.3 — internal
Skipped (aborted push).
0.1.2 — internal (2026-05-15)
fix:max_results cap was being silently ignored because the emission counter was stored in serialized request userData. Replaced with module-level counter in routes.ts. Now exact: input max_results=10 ⇒ exactly 10 records emitted.
fix: District field had embedded newlines from raw DOM; added cleanDistrict() helper.
fix: Room count was null; added parseRooms() for the Xer WG pattern in listing-card location row.
0.1.1 — internal (2026-05-15)
First cloud build. Scaffolded with Crawlee + Playwright + residential DE proxy. End-to-end crawl through Cloudflare challenge: 57/83 pages, 0 failures.