Willhaben.at Scraper — Austria Real Estate, Cars, Marketplace
Pricing
from $1.05 / 1,000 result items
Willhaben.at Scraper — Austria Real Estate, Cars, Marketplace
Willhaben.at scraper for analysts, dealers and AI agents: Austrian real estate (rent/buy, houses, plots, commercial), cars, motorbikes, vans and marketplace goods.
Pricing
from $1.05 / 1,000 result items
Rating
0.0
(0)
Developer
Samat Makatov
Maintained by CommunityActor stats
1
Bookmarked
1
Total users
1
Monthly active users
3 days ago
Last modified
Categories
Share
Structured listings from willhaben.at, Austria's largest classifieds site: flats and houses for rent or sale, plots, commercial property, holiday homes, used cars, motorbikes, vans, caravans and marketplace goods. Every search comes with willhaben's own filters (region down to Vienna districts, price, rooms, m², make/model, year, mileage, fuel, PayLivery, private/dealer…), price per m², publish time and coordinates. detail: true adds full description, all photos, seller details and the complete attribute sheet. A facets mode returns live hit counts per filter value, useful for market sizing.
Plain HTTP against the site's embedded page data. No proxies, no browser, no API key.
Use cases
- Rental market reports: all Vienna flats for rent, broken down by district with median
pricePerSqm, refreshed weekly. - Deal alerts for buyers & agents:
sinceHours: 24on a daily schedule with your price, rooms and district. Only ads published (or bumped) in the last 24 hours come back. - Used-car dealer sourcing: private-seller cars by make/model/year/mileage (
sellerType: "private"), sorted by price, with first registration and equipment from detail pages. - Price tracking for resellers: marketplace items such as
"iphone 15"withpayliveryOnly, condition and category filters, to track the going price of a product. - Supply / competition analysis:
mode: "facets"gives the number of ads per make, fuel, district, property type or price band in one request. - Dealer and agency research (B2B): dealer and agency ads (
sellerType: "dealer") with company name, website and the phone number they publish (detail: true). Contact data is personal data in many cases: see Personal data (GDPR) below before you store or use it.
Input
All fields are optional. Filters that don't apply to the chosen vertical are ignored, and a warning is logged. A filter value the actor cannot match fails the run before any ad is saved, with the valid values (and "did you mean"), so you never get an unfiltered search by mistake. Fields with a fixed list (category, mode, sellerType, transmission, wheelDrive, handover, sort) accept only the listed values: Apify refuses anything else before the run starts.
| Field | Type | Default | Allowed values / notes |
|---|---|---|---|
category | string | mietwohnungen | mietwohnungen, eigentumswohnung, haus-kaufen, haus-mieten, grundstuecke, gewerbeimmobilien-kaufen, gewerbeimmobilien-mieten, ferienimmobilien-kaufen, ferienimmobilien-mieten, auto, motorrad, nutzfahrzeuge, wohnwagen, marktplatz. v0.1 paths (immobilien/mietwohnungen, gebrauchtwagen/auto/gebrauchtwagenboerse…) still work. |
mode | string | search | search (listings), facets (filter values + hit counts), categories (marketplace category ids) |
region | string | — (prefill wien) | Bundesland slug, district/city name, Vienna district (wien-7, 1070, Neubau) or numeric areaId. St. = Sankt. A name that fits several districts (Krems) fails with the candidates; a unique start of a name (Spittal) is accepted and reported in the status. Empty = all Austria. See Reference. |
areas | string[] | [] | More districts/cities/areaIds, OR-combined with region. Same rules as region. |
keyword | string | – | Free text. |
priceFrom / priceTo | integer | – | € (monthly rent for rental verticals). |
sellerType | string | all | all, private, dealer. Server-side for vehicles & marketplace, client-side for real estate. |
roomsFrom / roomsTo | integer | – | Real estate. |
livingAreaFrom / livingAreaTo | integer | – | m², flats/houses/holiday homes. |
plotAreaFrom / plotAreaTo | integer | – | m², houses/plots. |
propertyTypes | string[] | [] | See Reference → Property types. Labels, aliases or ids; case, umlauts (ü = ue) and separators don't matter. Other values fail with "did you mean". |
features | string[] | [] | storage, accessible, carport, kitchen, lift, garage, cellar, parking, furnished, cabling (or the German labels). |
outdoorAreas | string[] | [] | balcony, roof-terrace, garden, loggia, terrace, winter-garden. |
availableNow / newBuildOnly | boolean | false | Real estate. |
make / model | string | – | Vehicles. Matched against willhaben's live make/model list. A unique start of a name (Mercedes → Mercedes-Benz) is accepted and reported in the status; an unknown or ambiguous value fails and the error lists the valid names. |
yearFrom / yearTo | integer | – | First registration year. |
mileageFrom / mileageTo | integer | – | km. |
powerKwFrom / powerKwTo | integer | – | kW. |
fuel | string[] | [] | petrol, diesel, electric, gas, hybrid, hybrid-diesel, hydrogen. |
transmission | string | – | automatic, manual. |
wheelDrive | string | – | awd, fwd, rwd. |
bodyTypes | string[] | [] | Cars: cabrio, compact, minibus, kombi, sedan, microcar, coupe, suv, or willhaben's labels (other vehicle verticals: labels from mode: "facets"). An unknown value fails with the valid list. |
vehicleCondition | string[] | [] | used, one-year, new, classic, pre-registered, accident, demo (cars), or willhaben's labels. An unknown value fails with the valid list. |
colors | string[] | [] | black, white, grey, silver, blue, red, green, brown, beige, yellow, gold, orange, bronze, purple, other. |
equipment | string[] | [] | willhaben labels, e.g. Anhängerkupplung, Navigationssystem (see mode: "facets"). An unknown or ambiguous label fails with the valid list. |
warrantyOnly / inspectionOnly | boolean | false | Vehicles with a warranty / a valid §57a condition report ("Pickerl"). |
marketCategory | string | – | Marketplace top-level name (see Reference) or any numeric ATTRIBUTE_TREE id. |
itemCondition | string[] | [] | new, like-new, refurbished, used, defective, display. |
handover | string | – | pickup, shipping. |
payliveryOnly | boolean | false | Only ads with willhaben PayLivery. |
sort | string | newest | newest, relevance, price_asc, price_desc, area_asc/area_desc (real estate), mileage_asc/mileage_desc, year_desc/year_asc, model (vehicles). |
sinceHours | integer | – | Keep ads published in the last N hours (server day filter + exact client check). |
maxItems | integer | 50 | 1–5000 ads (search mode; facets return every value of one request). Up to 100 ads per request. |
maxPages | integer | 20 | Safety cap on search pages; the status says when it stopped the run. |
detail | boolean | false | Open each ad page (+1 request per ad, ~1.5 s each, so roughly 2,000–2,500 ads per hour). |
includeTopAds | boolean | false | Keep paid top ads (Top-Anzeigen, isTopAd: true, usually under 10 % of the ads). They match your filters and sort; by default they are skipped and the status counts them. Paid highlights on ordinary ads (isHighlighted) are always kept. |
dedupe | boolean | true | No effect, kept for older inputs: each ad id is stored and charged at most once per run. |
fields | string[] | [] | Search mode: output only these fields, in this order; id always comes first unless you place it. Case slips and small typos (titel) are corrected and reported; unknown names are left out with a warning; if none is valid the run fails with the list of names. Facets rows are always complete. |
extraParams | object | {} | Raw willhaben URL parameters, e.g. {"NO_OF_DOORS_FROM": 4}. |
Reference
Regions (region, areas)
| Bundesland | Slug | areaId | Districts / cities (name → areaId) |
|---|---|---|---|
| Wien | wien | 900 | 1.–23. Bezirk → 117223–117245 (wien-1 … wien-23, or postcode 1010 … 1230, or name Innere Stadt, Leopoldstadt, Landstraße, Wieden, Margareten, Mariahilf, Neubau, Josefstadt, Alsergrund, Favoriten, Simmering, Meidling, Hietzing, Penzing, Rudolfsheim-Fünfhaus, Ottakring, Hernals, Währing, Döbling, Brigittenau, Floridsdorf, Donaustadt, Liesing) |
| Niederösterreich | niederoesterreich | 3 | Amstetten 305, Baden 306, Bruck an der Leitha 307, Gänserndorf 308, Gmünd 309, Hollabrunn 310, Horn 311, Korneuburg 312, Krems an der Donau 301, Krems Land 313, Lilienfeld 314, Melk 315, Mistelbach 316, Mödling 317, Neunkirchen 318, Sankt Pölten 302, Sankt Pölten Land 319, Scheibbs 320, Tulln 321, Waidhofen an der Thaya 322, Waidhofen an der Ybbs 303, Wiener Neustadt 304, Wiener Neustadt Land 323, Zwettl 325 |
| Oberösterreich | oberoesterreich | 4 | Braunau am Inn 404, Eferding 405, Freistadt 406, Gmunden 407, Grieskirchen 408, Kirchdorf an der Krems 409, Linz 401, Linz Land 410, Perg 411, Ried im Innkreis 412, Rohrbach 413, Schärding 414, Steyr 402, Steyr-Land 415, Urfahr-Umgebung 416, Vöcklabruck 417, Wels 403, Wels-Land 418 |
| Steiermark | steiermark | 6 | Bruck-Mürzzuschlag 621, Deutschlandsberg 603, Graz 601, Graz-Umgebung 606, Hartberg-Fürstenfeld 622, Leibnitz 610, Leoben 611, Liezen 612, Murau 614, Murtal 620, Südoststeiermark 623, Voitsberg 616, Weiz 617 |
| Tirol | tirol | 7 | Imst 702, Innsbruck 701, Innsbruck-Land 703, Kitzbühel 704, Kufstein 705, Landeck 706, Lienz 707, Reutte 708, Schwaz 709 |
| Salzburg | salzburg | 5 | Hallein 502, Salzburg Stadt 501, Salzburg-Umgebung 503, Sankt Johann im Pongau 504, Tamsweg 505, Zell am See 506 |
| Kärnten | kaernten | 2 | Feldkirchen 210, Hermagor 203, Klagenfurt 201, Klagenfurt Land 204, Sankt Veit an der Glan 205, Spittal an der Drau 206, Villach 202, Villach Land 207, Völkermarkt 208, Wolfsberg 209 |
| Vorarlberg | vorarlberg | 8 | Bludenz 801, Bregenz 802, Dornbirn 803, Feldkirch 804 |
| Burgenland | burgenland | 1 | Eisenstadt 101, Eisenstadt-Umgebung 103, Güssing 104, Jennersdorf 105, Mattersburg 106, Neusiedl am See 107, Oberpullendorf 108, Oberwart 109, Rust 102 |
| Abroad | ausland | 22000 | – |
Property types (propertyTypes)
| Group | Values (German label → alias) |
|---|---|
| Flats | Wohnung (flat), Dachgeschoßwohnung (attic), Erdgeschoßwohnung (ground-floor), Garconniere (studio-flat), Genossenschaftswohnung (cooperative), Loft/Studio (loft), Maisonette (duplex), Penthousewohnung (penthouse), Rohdachboden (raw-attic), Zimmer/WG (room) |
| Houses | Einfamilienhaus (detached), Doppelhaushälfte (semi-detached), Reihenhaus (terraced), Mehrfamilienhaus (multi-family), Villa, Bungalow, Bauernhaus (farmhouse), Landhaus (country-house), Almhütte/Berghütte (chalet), Gartenhaus, Genossenschaftshaus, Rohbau (shell), Schloss/Burg/Chalet (castle) |
| Plots | Grundstück (plot), Baugrundstück (building-plot), Gewerbegrundstück, Industriegrundstück, Kleingarten (allotment), Land-/Forstwirtschaft (agricultural) |
| Commercial | Büro/Ordination (office), Geschäfts-/Ladenlokal (shop), Gastronomie (restaurant), Hotel/Pension (hotel), Lagerhalle (warehouse), Werkstatt (workshop), Zinshaus (investment-building), Ausstellungsfläche (showroom), Jagd-/Forstwirtschaft, Teich-/Fischwirtschaft |
Marketplace categories (marketCategory)
| Name (alias) | ATTRIBUTE_TREE id |
|---|---|
Antiquitäten / Kunst (antiques) | 6941 |
Baby / Kind (baby) | 3928 |
Beauty / Gesundheit / Wellness (beauty) | 3076 |
Boote / Yachten / Jetskis (boats) | 5007823 |
Bücher / Filme / Musik (books) | 387 |
Computer / Software (computer) | 5824 |
Dienstleistungen (services) | 537 |
Freizeit / Instrumente / Kulinarik (leisure) | 6462 |
Games / Konsolen (games) | 2785 |
Haus / Garten / Werkstatt (home) | 3541 |
Kameras / TV / Multimedia (cameras) | 6808 |
KFZ-Zubehör / Motorradteile (car-parts) | 6142 |
Mode / Accessoires (fashion) | 3275 |
Smartphones / Telefonie (smartphones) | 2691 |
Spielen / Spielzeug (toys) | 5136 |
Sport / Sportgeräte (sport) | 4390 |
Tiere / Tierbedarf (pets) | 4915 |
Uhren / Schmuck (watches) | 2409 |
Wohnen / Haushalt / Gastronomie (furniture) | 5387 |
For sub-categories, run {"category": "marktplatz", "mode": "categories", "marketCategory": "smartphones"}.
Examples
Vienna rental market snapshot (2–3 rooms, 50–90 m², balcony)
{ "category": "mietwohnungen", "region": "wien", "roomsFrom": 2, "roomsTo": 3, "livingAreaFrom": 50, "livingAreaTo": 90, "outdoorAreas": ["balcony"], "maxItems": 500 }
Daily alert: new houses for sale around Graz under €600k
{ "category": "haus-kaufen", "region": "Graz-Umgebung", "areas": ["Graz"], "priceTo": 600000, "sinceHours": 24, "sort": "newest", "detail": true }
Dealer sourcing: private-seller VW Golf diesels from 2018, cheapest first
{ "category": "auto", "region": "", "make": "VW", "model": "Golf", "fuel": ["diesel"], "yearFrom": 2018, "mileageTo": 150000, "sellerType": "private", "sort": "price_asc", "maxItems": 200 }
Reseller price check: iPhone 15 like-new with PayLivery
{ "category": "marktplatz", "region": "", "keyword": "iphone 15", "marketCategory": "smartphones", "itemCondition": ["like-new"], "payliveryOnly": true, "maxItems": 100, "fields": ["title", "price", "location", "publishedAt", "url"] }
Market sizing: how many flats for sale per district and property type in Graz
{ "category": "eigentumswohnung", "region": "Graz", "mode": "facets" }
Output
Example item (category: "mietwohnungen", trimmed):
{"id": "819411514","url": "https://www.willhaben.at/iad/immobilien/d/mietwohnungen/wien/wien-1160-ottakring/freundliche-hausbewohner-...-819411514/","title": "freundliche Hausbewohner, schöner Innenhofgarten, ...","price": 1290,"currency": "EUR","priceDisplay": "€ 1.290","location": "Wien, 16. Bezirk, Ottakring","postcode": "1160","state": "Wien","areaId": 117238,"latitude": 48.21965,"longitude": 16.31933,"isPrivate": true,"sellerType": "private","publishedAt": "2026-09-13T08:03:17.000Z","isBumped": true,"isTopAd": false,"isHighlighted": true,"vertical": "mietwohnungen","kind": "estate","propertyType": "Wohnung","rooms": 3,"livingArea": 68,"floor": "3","features": ["Keller"],"pricePerSqm": 18.97,"images": ["https://cache.willhaben.at/mmo/..."],"imagesCount": 17,"attributes": { "…": "full raw attribute map" },"searchTotal": 4781,"searchUrl": "https://www.willhaben.at/iad/immobilien/mietwohnungen/mietwohnung-angebote?rows=40&page=1&areaId=900","fetchedAt": "2026-09-13T08:13:06.759Z"}
| Field | Kinds | Description |
|---|---|---|
id, url, title, description | all | willhaben ad id (stable), ad URL, heading, teaser text |
price, currency, priceDisplay, oldPrice | all | Price in € (monthly rent for rentals), displayed price, previous price if reduced |
location, postcode, state, district, country, areaId, latitude, longitude | all | Location |
sellerName, sellerId, isPrivate, sellerType | all | private / dealer |
publishedAt, changedAt, isBumped, isTopAd, isHighlighted | all | ISO timestamps in true UTC; bumped = re-pushed to the top; isTopAd = paid top ad (Top-Anzeige); isHighlighted = paid highlight on an ordinary listing |
vertical, kind, categoryLabel | all | estate, motor, market |
propertyType, propertyTypeId, rooms, livingArea, usableArea, plotArea, floor, outdoorArea, outdoorAreaSize, features, pricePerSqm, isNewBuildProject | estate | pricePerSqm comes from willhaben or is computed as price / living area |
make, model, modelSpec, mileage, year, fuel, transmission, powerKw, bodyType, condition, color, warranty, owners, seats, equipment, pricePerKm, isDealerAd | motor | |
categoryIds, paylivery, teaser, expiresAt | market | categoryIds: the ad's category path, top level first (ATTRIBUTE_TREE ids) |
images, imagesCount, attributes, searchTotal, searchUrl, fetchedAt | all | |
descriptionFull, firstPublishedAt, expiresAt, street, municipality, province, sellerRegisteredAt, sellerActiveAds, companyName, website, phone, details, shippingOptions, rentPerMonth, additionalCosts, deposit, availableFrom, buildingCondition, firstRegistration, detailAttributes, detailFetched, detailError | detail: true | Only fields the ad actually publishes are filled |
The dataset schema describes every field (type, title, description, example). Each run also writes a SUMMARY record to its key-value store: rows saved, ads skipped and why, pages read, detail failures, values read differently from how you typed them, and why the run stopped.
Rows from mode: "facets" / "categories" have navigatorId, navigatorLabel, param, label, value, hits, selected, howToUse (which input to put the value into), rowsFound, searchUrl, fetchedAt.
Use it from code / agents
Apify API (curl)
curl -X POST "https://api.apify.com/v2/acts/yadroo~willhaben-at/run-sync-get-dataset-items?token=$APIFY_TOKEN" \-H 'Content-Type: application/json' \-d '{"category":"auto","make":"BMW","yearFrom":2020,"sellerType":"private","maxItems":50}'
JavaScript (apify-client)
import { ApifyClient } from 'apify-client';const client = new ApifyClient({ token: process.env.APIFY_TOKEN });const run = await client.actor('yadroo/willhaben-at').call({ category: 'mietwohnungen', region: 'wien-7', maxItems: 100 });const { items } = await client.dataset(run.defaultDatasetId).listItems();
Python (apify-client)
from apify_client import ApifyClientclient = ApifyClient(os.environ["APIFY_TOKEN"])run = client.actor("yadroo/willhaben-at").call(run_input={"category": "marktplatz", "keyword": "rennrad", "priceTo": 800})items = client.dataset(run["defaultDatasetId"]).list_items().items
AI agents (MCP): add https://mcp.apify.com?actors=yadroo/willhaben-at to Claude, Cursor or any MCP client. The input schema descriptions are written so an agent can fill filters from a plain-language request.
Pricing
Pay per event: $0.005 per run start + $0.0015 per ad in the dataset.
- 50 ads (default): $0.08
- 500 ads for a market snapshot: $0.755
mode: "facets": the rows are filter values, charged like ads (a Graz flats-for-sale facet run returned 77 rows, about $0.12).
Store discounts: Bronze −10 %, Silver −20 %, Gold and above −30 % on the ad price; the start event is the same on every plan. Platform usage is included.
detail: true doesn't change the price per item. It takes longer, about 1.5 s per ad.
Spending limit: the run reads your "Maximum cost per run" before it starts and stops when the next ad would exceed it, with the status "Stopped at your spending limit: N rows delivered". You are charged only for ads saved to the dataset.
Limits & FAQ
- Speed (measured 02.10.2026): one search page of 100 ads takes about 2–4 s including a short pause, so a 500-ad search without detail pages takes about 20 s. Detail pages take about 1.4–1.6 s per ad, roughly 2,000–2,500 ads per hour.
- Run timeout and big jobs: the default run timeout is 1 hour, which fits roughly 2,000–2,500 ads with
detail: true. Ads are saved in small batches as they are ready. Near the timeout the run stops starting new pages, keeps everything saved so far and ends SUCCEEDED with "Stopped before the run timeout: N rows saved"; raise the timeout or split the job (by region, make or price range) for more. - Restarts: if Apify migrates or restarts the run, ads saved before are skipped, never saved or charged twice.
- Freshness: live data at request time.
publishedAtis willhaben's last publish time; bumped ads show the bump time (isBumped: true). - Time zones: all
…Atfields are real UTC. willhaben's ownPUBLISHED_String/CHANGED_String/ENDDATE_Stringattributes (kept raw inattributes) end inZbut are Vienna local time (CET/CEST); the actor reads the exact epoch values instead, or converts the local time with daylight saving taken into account. - Top ads: Top-Anzeigen (
isTopAd: true) are ordinary matching ads whose sellers paid for a top placement; they are skipped unlessincludeTopAds: true, and the status says how many. Many ordinary ads carry a paid highlight (isHighlighted: true, about 70 % of car ads): those are always kept. - Deep paging: willhaben occasionally serves the same result page again deep in a broad search. The actor re-reads that page once; if it is still a repeat it stops and says so in the status. Split broad searches (region, make, price range) to get further.
- Real-estate seller type: willhaben has no private/agency filter for real estate. The actor filters after fetching, so you may need more pages.
- Blocks & errors: HTTP 429/5xx are retried with backoff. If willhaben serves a 403 or challenge page on the first search page, the run fails with a clear error; if a later page fails, the run keeps the ads saved so far and names the page in the status. If detail pages get blocked, the run keeps the list data, marks items with
detailErrorand says in the status after how many ads it happened. - Unknown values (make, model, region, fuel, body type, colour, equipment…) fail early with the list of valid values instead of returning an unfiltered search. Values read differently from how you typed them (a unique start of a make or district name, a field-name typo) are listed in the status and in
SUMMARY.corrections. - Personal data (GDPR): ads of private sellers can contain personal data: the seller's name (
sellerName, already in search mode) and, withdetail: true, a published phone number, street and seller location. willhaben shows them publicly, but under the GDPR you still need a lawful basis to store and use them, and in Austria and the EU unsolicited advertising calls, SMS and e-mails generally need prior consent. If you don't need these fields, leave them out withfieldsor usesellerType: "dealer". This README is not legal advice. - Roadmap: price-drop tracking across runs (compare
oldPrice/ previous dataset), dealer inventory mode.
Made by Yadroo. Sibling actors: Otodom.pl (Poland real estate) · Kleinanzeigen.de (Germany classifieds) · AutoScout24 cars · Marktplaats.nl · Rightmove UK · Krisha.kz