Willhaben Listings Scraper & New-Ad Alerts (Austria)
Pricing
from $0.62 / 1,000 listing scrapeds
Willhaben Listings Scraper & New-Ad Alerts (Austria)
Search willhaben.at, Austria's biggest classifieds site, by keyword or any search URL: one flat row per ad with title, price, location, publish time, seller type, photos and link. Real estate and used cars too. Newest first, with a 'published after' cutoff for new-ad alerts.
Pricing
from $0.62 / 1,000 listing scrapeds
Rating
0.0
(0)
Developer
Superslow Sloth
Maintained by CommunityActor stats
0
Bookmarked
2
Total users
1
Monthly active users
12 days ago
Last modified
Categories
Share
Search willhaben.at, Austria's largest classifieds
site, by keyword or by any willhaben search URL and get one flat row per
ad: title, link, price, location with postcode and coordinates, publish
time, private or business seller, photos, and for real-estate and used-car
searches the area, rooms, property type, year and mileage. Run it on a schedule,
newest first with publishedAfter set to your last run, and you have a
new-listing alert that pays only for the new ads.
No account, no API key, no login, no browser. One request returns up to 200 ads.
Input
| Field | Notes |
|---|---|
keywords | Marketplace (kaufen und verkaufen) search terms, one per line. |
startUrls | Any willhaben search URL from your browser's address bar: a marketplace search with filters, a real-estate search (/iad/immobilien/..., rentals or sales) or a used-car search (/iad/gebrauchtwagen/...). Filters in the URL are kept; its page, rows and sort parameters are replaced. At least one of keywords and startUrls is required. |
maxItems | Ads to read per keyword and per URL (default 100, up to 100,000). |
sort | newest (default; willhaben's own newest-first), relevance, price-asc, price-desc, or as-in-url (send no sort, so a start URL keeps the one it was copied with). |
publishedAfter | Optional ISO 8601 date or time (2026-10-13, 2026-10-13T08:00:00Z; UTC when no zone). Only ads published at or after it are returned, and reading stops once a page is older than it. Needs newest. |
proxyConfiguration | Apify proxy by default. |
An ad that two searches both find is returned once, under the first.
Using it for new-listing alerts
Set sort to newest and publishedAfter to the time of your last run. Ads
come back newest first and the actor stops at the first page whose last ad is
older than the cutoff, so a run with nothing new costs the start fee and one
request. Diff on ad_id if you would rather not track a timestamp.
publishedAfter compares against published_at, willhaben's publication time.
Willhaben also lets sellers "bump" an ad back to the top of the list; a bumped
ad keeps its original published_at and is not treated as new.
Output
Prices are numbers in euro; times are ISO 8601 in UTC (2026-10-12T22:25:19Z).
| Field | Notes |
|---|---|
query | The keyword, or the start URL, that first found this ad. |
ad_id, url | Willhaben's ad id (stable for the life of the ad: diff on it) and the https://www.willhaben.at/iad/... link. |
title, description_snippet | The headline, and the opening of the ad text as willhaben cuts it for the search page (about 300 characters, ending in ... when cut). The full text is on the ad page and is not fetched. |
vertical_id | 5 marketplace, 2 real estate, 3 used cars. |
price, price_text, old_price | The ask in euro (the monthly rent for a rental), the price as shown (€ 1.390, zu verschenken), and the earlier price when the seller lowered it. |
published_at, modified_at, expires_at | When the ad went up, last changed and expires. |
location, postcode, state, district, country, address, latitude, longitude | As willhaben shows them. address only when the seller published one. |
is_private, seller_name | True for a private seller; the business name for a commercial one. |
image_url, image_urls | The cover photo and every photo willhaben lists for the ad, as full URLs. The search record names every photo but links only the first three; the rest are built with willhaben's own URL pattern (checked: a fourth photo and a .png one both answered 200). |
property_type, living_area_m2, rooms, floor, price_per_m2 | Real-estate ads only. |
year_model, mileage_km | Used-car ads only. |
Honest nulls
A field willhaben did not send is null, never 0 or "". The columns for
another kind of ad are null (a bicycle has no rooms). Two details worth
knowing:
price0 is willhaben's own value for an ad given away. It always came withprice_textzu verschenkenin the sample. An ad with no price at all (one rental in 200 had none) haspricenull.roomsandliving_area_m2are null when willhaben sends 0. It writes 0 for "not stated" (a 152 m2 penthouse hadNUMBER_OF_ROOMS0), so a 0 would read as a measurement. Ads where the seller did state a count keep it.
Pricing
Pay per event:
- $0.002 per run (
actor-start), charged only after your input is validated, so a run that fails on bad input costs nothing. - $0.00062 per ad row written (
listing-scraped), i.e. $0.62 per 1,000 ads. A row that is not written is not charged.
How it fetches
One plain HTTP request per page of up to 200 ads, no browser:
https://www.willhaben.at/iad/kaufen-und-verkaufen/marktplatz?keyword=<kw>&sort=1&rows=200&page=<n>
(or the path of your start URL). The page is a Next.js page; the ads are read
from the JSON in its __NEXT_DATA__ script tag
(searchResult.advertSummaryList), where each ad is a list of named
attributes (PRICE, PUBLISHED_String, LOCATION, ...).
Willhaben sits behind Cloudflare. Measured from an Apify datacenter exit on 2026-10-13, about 40-45% of requests were refused with a 403, interleaved per exit rather than adapting to the client. The actor presents a Chrome TLS fingerprint, treats a 403, 429, 202, 5xx or a 200 without the data block as a refusal, and retries it from a fresh proxy address, which absorbs it. From a plain home or office address the same requests answered 200 every time in the test; expect your own mileage.
Things worth knowing, all measured:
- The page cap is 999 pages, not a number of ads. Page 1000 is a 404. At
willhaben's default of 30 ads a page that would be 29,970 ads; the actor asks
for up to 200 ads a page (
rowsis clamped at 200), so a search of 95,933 ads is readable to the end. A page past the real end is an empty list. - A wrong sort fails silently on willhaben's side. An unknown sort id is a
200 in relevance order with no sort marked as applied. The actor checks the
page's own record of the applied sort for
newestand fails the search, at no charge, rather than return ads in the wrong order. - A wrong path is not an error. A category slug that willhaben does not
recognise returns the whole marketplace (13.6 million ads) instead of a 404.
Copy the URL from the address bar after choosing the category in the
browser, and check
totals foundin the log against the count the site shows. description_snippetis cut by willhaben, not by this actor.- Counts move. Ads are posted between requests, so newest-first paging can show an ad twice across a page boundary; it is returned once.
- Not offered. Filters beyond what is in the URL, and the ad detail page (full text, seller contact details, phone numbers), are not fetched.