willhaben Car Scraper
Used cars from willhaben.at as clean JSON: make, model, year, mileage, fuel, transmission and price as first-class columns.
Used cars from willhaben.at as clean JSON: make, model, year, mileage, fuel, transmission and price as first-class columns. Dealer or private as a flag - seller identity and exact coordinates are never collected. Pay per result.
$3.00 / 1,000 · 93.1% success over 29 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 | Optional keyword, exactly as you would type it in the willhaben car search, e.g. "golf tdi" or "tesla model 3". Leave empty to browse the newest cars across Austria. Leave it out when you only re-check cars through listingIds. | golf |
listingIds |
array | Re-check cars 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, the specs and the site's own status (active, reserved, ...) whether or not Fetch full descriptions is on. A car that is gone from the site is skipped, named in the log and not billed. When given, the search fields of this form are ignored and the run status says which. Up to 50. |
[] |
priceMinEur |
integer | Only cars costing at least this much. | - |
priceMaxEur |
integer | Only cars costing at most this much. | - |
sortBy |
string | Order of results: date (newest first, best for monitoring), price_asc, price_desc, or relevance. | date |
postedAfter |
string | Only listings posted on or after this date. With newest-first sorting the run stops early once it reaches older listings. 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 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 cars. 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 500. | 500 |
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:
{
"bodyType": "Sportwagen / Coupé",
"city": "Ungarn",
"condition": "Gebrauchtwagen",
"currency": "EUR",
"description": "BMW 650i xDrive Gran Coupé M-Paket | 4.4L V8 | 540 PS | Vollausstattung | Unfallfrei | Stage 2 | Indv. Auspuffsteuerung Exportpreis: € 22.00...",
"fuel": "Benzin",
"imageUrls": [
"https://cache.willhaben.at/mmo/1/199/811/6461_-1486500177.jpg",
"https://cache.willhaben.at/mmo/1/199/811/6461_-714381784.jpg",
"https://cache.willhaben.at/mmo/1/199/811/6461_1676787470.jpg",
"https://cache.willhaben.at/mmo/1/199/811/6461_-35572143.jpg",
"https://cache.willhaben.at/mmo/1/199/811/6461_918188601.jpg",
"https://cache.willhaben.at/mmo/1/199/811/6461_1761075485.jpg",
"https://cache.willhaben.at/mmo/1/199/811/6461_-1800001098.jpg",
"https://cache.willhaben.at/mmo/1/199/811/6461_187546616.jpg",
"https://cache.willhaben.at/mmo/1/199/811/6461_-922446622.jpg",
"https://cache.willhaben.at/mmo/1/199/811/6461_-312874984.jpg",
"https://cache.willhaben.at/mmo/1/199/811/6461_1358628551.jpg",
"https://cache.willhaben.at/mmo/1/199/811/6461_1555907344.jpg",
"https://cache.willhaben.at/mmo/1/199/811/6461_-1182758649.jpg",
"https://cache.willhaben.at/mmo/1/199/811/6461_-1480098676.jpg",
"https://cache.willhaben.at/mmo/1/199/811/6461_-920348079.jpg",
"https://cache.willhaben.at/mmo/1/199/811/6461_1598380451.jpg",
"https://cache.willhaben.at/mmo/1/199/811/6461_-1229274035.jpg",
"https://cache.willhaben.at/mmo/1/199/811/6461_330795181.jpg",
"https://cache.willhaben.at/mmo/1/199/811/6461_-234765325.jpg",
"https://cache.willhaben.at/mmo/1/199/811/6461_1045916040.jpg",
"https://cache.willhaben.at/mmo/1/199/811/6461_1054549407.jpg"
],
"listingId": "1998116461",
"make": "BMW",
"mileageKm": 175617,
"model": "6er-Reihe",
"modelSpec": "650i xdrive V8 4,4l TwinTurbo",
"postcode": "9700",
"postedAt": "2026-10-18T07:30:08Z",
"powerKw": 400,
"previousOwners": 2,
"priceCents": 2100000,
"priceDisplay": "€ 21.000",
"seats": 5,
"sellerType": "private",
"state": "Szombathely",
"status": "active",
"title": "BMW 6er-Reihe 650i xdrive V8 4,4l TwinTurbo",
"transmission": "Automatik",
"url": "https://www.willhaben.at/iad/gebrauchtwagen/d/auto/bmw-6er-reihe-650i-xdrive-v8-4-4l-twinturbo-1998116461/",
"year": 2012
}
| Field | Type | Meaning |
|---|---|---|
listingId |
string | willhaben listing ID. |
url |
string | Direct link to the listing. |
title |
string | Listing title as posted. |
description |
['string', 'null'] | 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). |
make |
['string', 'null'] | Car make from the site's own car model data. |
model |
['string', 'null'] | Car model from the site's own car model data. |
modelSpec |
['string', 'null'] | Model specification line, e.g. trim and engine. |
year |
['integer', 'null'] | Model year. |
mileageKm |
['integer', 'null'] | Mileage in kilometers. |
powerKw |
['integer', 'null'] | Engine power in kW. |
fuel |
['string', 'null'] | Fuel type as resolved by the site (Diesel, Benzin, Elektro, ...). |
transmission |
['string', 'null'] | Transmission as resolved by the site (Automatik, Schaltgetriebe). |
bodyType |
['string', 'null'] | Body type, e.g. Limousine, Kombi, SUV, Cabrio / Roadster. |
condition |
['string', 'null'] | Condition as resolved by the site (Gebrauchtwagen, Neuwagen, ...). |
previousOwners |
['integer', 'null'] | Number of previous owners when stated. |
seats |
['integer', 'null'] | Number of seats when stated. |
priceCents |
['integer', 'null'] | Asking price in euro cents. |
currency |
['string', 'null'] | Always EUR. |
priceDisplay |
['string', 'null'] | Price as displayed on the site. |
postedAt |
['string', 'null'] | When the listing was published (ISO timestamp). |
city |
['string', 'null'] | Municipality-level location. Exact coordinates are deliberately never collected. |
postcode |
['string', 'null'] | Postcode of the listing location. |
district |
['string', 'null'] | District (Bezirk). |
state |
['string', 'null'] | Austrian state (Bundesland). |
sellerType |
string | private or dealer. Seller identity is never collected. |
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
93.1% success over 29 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.
The history behind this tool
This tool answers what a source shows today. Its output also feeds a series recorded every day and kept: Used car asking prices and listing lifecycles. A run gives you the current market; the series is the part that cannot be reconstructed afterwards, because the source overwrites it.