willhaben Scraper
willhaben.at is Austria's largest marketplace, and it keeps no export and no price history, everything lives inside the search page you refresh by hand.
willhaben.at is Austria's largest marketplace, and it keeps no export and no price history, everything lives inside the search page you refresh by hand. Rows give price in cents, the seller's own display price, posting date, city, postcode, district and Bundesland. No seller identity collected.
$3.00 / 1,000 · 98.8% success over 762 public runs in the last 30 days.
Run it on Apify → Free to try - runs bill per result on your own account.
What you give it
Every field is optional unless marked; sensible defaults do the rest.
| Field | Type | What it does | Default |
|---|---|---|---|
searchQuery |
string | What to search for on willhaben's Marktplatz, exactly as you would type it in the site's search box, e.g. "fahrrad" or "iphone 15". Leave it out when you only re-check listings through listingIds. | fahrrad |
listingIds |
array | Re-check listings you already know instead of searching: one ad ID per line (the number at the end of every ad address, and the listingId of every dataset item), or the ad's full address. Each one is read from its own page, so it carries the full description, every photo and the site's own status (active, reserved, ...) whether or not Fetch full descriptions is on. A listing that is gone from the site is skipped, named in the log and not billed. Marktplatz ads only; car ads belong to the willhaben Car Scraper. When given, the search fields of this form are ignored and the run status says which. Up to 50. |
[] |
priceMinEur |
integer | Only include listings costing at least this many euros. | - |
priceMaxEur |
integer | Only include listings costing at most this many euros. | - |
sortBy |
string | Order of results: date (newest first, best for monitoring), price_asc, price_desc, or relevance. | date |
postedAfter |
string | Only include listings posted on or after this date. With newest-first sorting the run stops early once older listings are reached. Format: YYYY-MM-DD (for example 2026-09-08) or a full ISO timestamp such as 2026-09-08T14:30:00Z. Slash dates like 08/09/2026 are refused on purpose: they are read as September in Europe and August in the United States, and this actor will not guess which you meant. |
- |
postedBefore |
string | Only include listings posted on or before this date. Format: YYYY-MM-DD (for example 2026-09-08) or a full ISO timestamp such as 2026-09-08T14:30:00Z. Slash dates like 08/09/2026 are refused on purpose: they are read as September in Europe and August in the United States, and this actor will not guess which you meant. |
- |
maxItems |
integer | Stop after this many listings. Free-plan runs are capped at 5 items. The form starts at 25 for a cheap first run - that is the form's prefill, not a cap on your plan; clear it to use the default of 1000. | 1000 |
scrapeDetails |
boolean | The search truncates the description to about 256 characters. Turn this on to read each ad's own page for the seller's full description. This makes one extra request per listing, so a run is slower and costs one more page fetch each. Only the description text reaches the output; contact attributes are never read. Leave off for a fast search-only sweep. | False |
reportFailures |
boolean | When a run fails, send the developer the actor name and build, an error category, the error message (truncated) and a one-way hash of your input - so a bug can be fixed without anyone asking you to reproduce it. Your input itself, your results and your identity are never sent, and successful runs send nothing at all. Switch this off and the actor behaves exactly the same. | True |
What you get back
One JSON object per result, with exactly these fields - no seller identities, no contact data, ever.
A real result row from a recent run:
{
"changedAt": "2026-10-14T08:57:02Z",
"city": "Taufkirchen an der Trattnach",
"currency": "EUR",
"description": "Verkaufen wenig gefahrenes Kinderfahrrad. Infos zum Fahrrad siehe Fotos. Nur leichte Kratzer an den Pedalen, funktionsfähig und einwandfrei....",
"district": "Grieskirchen",
"imageUrls": [
"https://cache.willhaben.at/mmo/3/130/995/5933_-757614301.jpg",
"https://cache.willhaben.at/mmo/3/130/995/5933_1490393894.jpg",
"https://cache.willhaben.at/mmo/3/130/995/5933_684845269.jpg",
"https://cache.willhaben.at/mmo/3/130/995/5933_570972086.jpg",
"https://cache.willhaben.at/mmo/3/130/995/5933_1640294069.jpg",
"https://cache.willhaben.at/mmo/3/130/995/5933_744452260.jpg",
"https://cache.willhaben.at/mmo/3/130/995/5933_690771821.jpg",
"https://cache.willhaben.at/mmo/3/130/995/5933_-1706009375.jpg",
"https://cache.willhaben.at/mmo/3/130/995/5933_529519621.jpg",
"https://cache.willhaben.at/mmo/3/130/995/5933_-1591845039.jpg",
"https://cache.willhaben.at/mmo/3/130/995/5933_1271527857.jpg",
"https://cache.willhaben.at/mmo/3/130/995/5933_-1494378272.jpg",
"https://cache.willhaben.at/mmo/3/130/995/5933_-1485603535.jpg",
"https://cache.willhaben.at/mmo/3/130/995/5933_972142549.jpg"
],
"listingId": "1309955933",
"postcode": "4715",
"postedAt": "2026-10-14T08:57:02Z",
"priceCents": 7000,
"priceDisplay": "€ 70",
"sellerType": "private",
"state": "Oberösterreich",
"status": "active",
"title": "Kinderfahrrad",
"url": "https://www.willhaben.at/iad/kaufen-und-verkaufen/d/kinderfahrrad-1309955933/"
}
| Field | Type | Meaning |
|---|---|---|
listingId |
string | willhaben listing ID. |
url |
string | Direct link to the listing. |
title |
string | Listing title as posted. |
description |
string | Listing description. The ~256-character search snippet by default, or the seller's full free-text description when Fetch full descriptions is on (read from the ad's own page; contact attributes are never read). |
priceCents |
integer | Asking price in euro cents. Absent when the listing has no numeric price. |
currency |
string | Always EUR when a price is present. |
priceDisplay |
string | The price exactly as willhaben displays it, e.g. '€ 50' or 'zu verschenken'. |
postedAt |
string | When the listing was published (ISO timestamp). |
changedAt |
string | When the listing was last changed by the seller. |
city |
string | Listing municipality. Municipality-level only - exact coordinates are never collected. |
postcode |
string | Austrian postcode of the listing. |
district |
string | Political district (Bezirk). |
state |
string | Austrian federal state (Bundesland). |
sellerType |
string | Whether the listing comes from a business or a private seller. The only seller-related field in the output. |
status |
string | The site's own listing status as it reports it: active, reserved, or whatever else willhaben shows. Present when the site sends one. |
imageUrls |
array | Every photo of the listing, in the site's order. |
Health
98.8% success over 762 public runs in the last 30 days. Live record, failures included: status page.
Full documentation, examples and the AI-assistant prompt live on the store page.
Questions
Is scraping willhaben legal in Austria?
This is not legal advice. The actor reads what any logged-out visitor sees on willhaben.at, with no login, no CAPTCHA solving and no private endpoints, and it extracts no seller name, contact detail or profile, so the output holds no personal data. Whether your own use of the listings is allowed under the site's terms and your jurisdiction's rules is yours to assess.
Can I get only the newest listings?
Yes. Set postedAfter to a date, yesterday for a daily watch, and the dataset holds only listings posted since then. With the default newest-first order the run stops paging as soon as it reaches older listings, so the watch stays fast and cheap.
How much do 10,000 listings cost?
$30.00, billed per delivered listing at $3.00 per 1,000. That price covers the run's platform usage, and a run that fails or returns nothing bills nothing.
Does it return seller phone numbers?
No. The only seller field is whether the seller is a business or a private person. Names, phone numbers, profiles and exact addresses are never extracted, and a test on every build fails if one ever appears, so this is not a setting that can be switched off.
Do I need residential proxies?
No. Datacenter proxies work for the vast majority of runs. The form's example input is pinned to a residential proxy so a first run is guaranteed clean; switch back to datacenter for real searches once you have seen the output. The price is the same either way.
Does it cover cars and property too?
This actor searches willhaben's Marktplatz, the general-goods section. Cars have their own tool, the willhaben Car Scraper, with make, model, mileage and fuel as columns; property is not covered.