AutoScout24 Scraper — Used Car Listings, 9 European Markets
Pricing
from $30.00 / 1,000 listing page harvesteds
AutoScout24 Scraper — Used Car Listings, 9 European Markets
Filter by make, model, fuel, year, mileage. Full 34-field rows incl. seller phone & address, equipment, CO2 class, AS24 price rating, price-drop flag — or compact 22-field mode for dashboards/LLM. 9 markets. Incremental: idle runs $0. FREE webhook + Telegram. $0.03/page.
Pricing
from $30.00 / 1,000 listing page harvesteds
Rating
0.0
(0)
Developer
B
Maintained by CommunityActor stats
0
Bookmarked
1
Total users
0
Monthly active users
2 days ago
Last modified
Categories
Share
AutoScout24 Listings — 9 European Markets
Flat, normalised vehicle listings from AutoScout24 search results — one clean JSON row per vehicle, across all 9 country sites (de/at/ch/fr/it/es/nl/be/pl). Built for daily price-monitoring and inventory schedules, not one-off human searches.
Independently validated: a from-scratch comparator (zero shared code with the actor) re-parsed the same-minute raw HTML for 40/40 rows — every field exact across all 22 fields validated then; v0.7 adds two more (priceEvaluation, see Changelog) with its own independent re-derivation gate — 0 mismatches on live data.
Why this one
| typical store scraper | this actor | |
|---|---|---|
| Markets | 5–8 domains | 9, incl. Poland |
| Broken page / site change | emits garbage or partial rows | fails loudly, zero charge |
| Failed or empty run | you still pay compute events | harvest events only fire on written pages |
| Output | ad-hoc shapes per run | stable schema, identical across all 9 markets |
A 31k-run competitor in this niche holds a 1.75/5 rating — broken runs and inconsistent output are the norm. This actor is the boring, reliable alternative: same schema every run, and you are never charged for a page that failed to parse.
What you get (per listing)
id, url, make, model, variant, trim, offerType (U=used / N=new /
A=all), priceEur + priceFormatted, priceEvaluation +
priceEvaluationLabel (AutoScout24's own deal rating:
1=very-good-price … 4=somewhat-expensive-price, null when unrated),
priceDropFrom (the on-site "Super Deal" previous price — the price-drop
signal), currency, mileageKm,
firstRegistration (MM/YYYY), fuelType, gearbox, powerKw,
engineDisplacementCc, consumptionL100Km + co2Class (WLTP, EU 2023 A–G
label; null when AS24 does not publish them), equipment (the listing's own
equipment line), sellerType
(Dealer/Private), sellerName, sellerId, sellerPhone (formatted dealer
phone), sellerStreet, city, zip, countryCode,
imageCount, cover image, source page, scrapedAt (ISO 8601 UTC).
34 fields total, all extracted from the search results page we already
fetch — no extra per-listing requests. compact: true trims to the 22
core fields (see Input).
Sample output (real run, de/bmw — rendered)

Above: an unedited run from 2026-09-13 (dataset rendered as a table, 12 of 20 rows shown). Raw JSON for one real row:
{"id": "76be9f75-646e-4328-8448-58c364367224","url": "https://www.autoscout24.de/angebote/bmw-5er-d-touring-m-optic-navi-klima-shz-diesel-blau-…","make": "BMW","model": "520","variant": "520d","trim": "d Touring M-Optic Navi Klima SHZ","offerType": "A","priceEur": 23990,"priceFormatted": "€ 23.990","priceEvaluation": 1,"priceEvaluationLabel": "very-good-price","currency": "EUR","mileageKm": 84990,"firstRegistration": "03/2021","fuelType": "Diesel","gearbox": "Automatik","powerKw": 140,"sellerType": "Dealer","sellerName": "Narin´s Automobile e.K.","sellerId": "15221647","city": "Nürtingen","zip": "72622","countryCode": "DE","image": "https://prod.pictures.autoscout24.net/listing-images/….jpg/250x188.webp","page": 1,"scrapedAt": "2026-08-20T00:04:56+00:00"}
Input example
{"domain": "de","make": "bmw","model": "3er","priceFrom": 5000,"priceTo": 25000,"firstRegistrationFrom": 2018,"mileageToKm": 80000,"fuel": "D","pages": 2,"incremental": true}
domain— country site:de,at,ch,fr,it,es,nl,be,plmake— URL slug (bmw,audi,volkswagen, …); empty = all makesmodel— URL slug (3er,golf,a4, …); requiresmakepriceFrom/priceTo— EUR band filter (optional)firstRegistrationFrom/firstRegistrationTo— first-registration year window (optional, v0.8)mileageFromKm/mileageToKm— km band filter (optional, v0.8)fuel— fuel code:Bpetrol,Ddiesel,Eelectric,2hybrid-petrol,3hybrid-diesel,LLPG,Hhydrogen (optional, v0.8)pages— 1–50 results pages; each page = 20 listings, ~1.5 s fetch intervalincremental— deliver only listings not delivered before for this query; pages with nothing new are not charged (idle scheduled run = $0). Defaultfalse= full listing set every run.compact— deliver only the 22 core fields per row (id, url, make, model, variant, offerType, both price fields + AS24 price rating + price-drop flag, mileage, first registration, fuel, gearbox, power, seller type, city, country, page, scrapedAt). Same rows, same charges — ~40% smaller payloads for dashboards and LLM contexts. Incremental change fields (changeType,previous*) are always kept. Defaultfalse= full 34-field schema.
Incremental mode also detects changes (v0.5)
With incremental: true the actor tracks price, mileage, offer type and
seller per listing between runs. A listing that changed is re-delivered
with a changeType field (price, mileage, seller, offer-type, or a
+-joined combination) plus the previous values (previousPriceFormatted,
previousMileageKm, previousOfferType, previousSellerType). A change is
delivered exactly once; the next run with no further change costs $0 again.
So each scheduled run returns exactly what a price-watch pipeline needs:
new listings and re-priced/edited listings.
Use it from an AI agent (MCP)
This actor exposes an MCP server. Ask your agent:
Use the autoscout24-listings actor to fetch the first 2 pages of BMWlistings on autoscout24.de between €5,000 and €25,000, then summarisethe median price by model.
Or call it directly:
$apify call halobartku~autoscout24-listings --input='{"domain":"de","make":"bmw","priceFrom":5000,"priceTo":25000,"pages":2}'
For AI agents & LLM apps (compact reference)
- Purpose: flat AutoScout24 search-results rows for price monitoring, dealer-inventory watches and market analysis across 9 European markets.
- Minimal input:
{"domain":"de","make":"bmw","pages":2}(all other fields optional). - Output fields per row:
id,url,make,model,variant,trim,offerType,priceEur,priceFormatted,priceEvaluation,priceEvaluationLabel,currency,mileageKm,firstRegistration,fuelType,gearbox,powerKw,sellerType,sellerName,sellerId,city,zip,countryCode,image,page,scrapedAt. - Agent behaviors you can rely on:
- billing is per 20-listing results page written, never per message or per listing;
- a query the site answers with zero listings is a SUCCEEDED run with 0 rows and 0 charges — safe to probe;
- a site layout change fails the run loudly (exit non-zero, no partial garbage rows) — never interpret empty output as "no cars";
scrapedAt+ stableidmake rows diff-able across scheduled runs for "new since yesterday" alerts;- in incremental mode a changed listing arrives with
changeType(price,mileage,seller,offer-type,+-joined combos) andprevious*fields — you get re-priced listings without diffing yourself, each change delivered exactly once; - schema is identical across all 9
domainvalues — one parser, no per-market branching in your pipeline.
Use it from Python
from apify_client import ApifyClientclient = ApifyClient("<YOUR_APIFY_TOKEN>")run = client.actor("halobartku~autoscout24-listings").call(run_input={"domain": "de", "make": "bmw","priceFrom": 5000, "priceTo": 25000, "pages": 2,})rows = list(client.dataset(run["defaultDatasetId"]).iterate_items())print(len(rows), "listings, median €",sorted(r["priceEur"] for r in rows)[len(rows)//2])
Pricing (with the honest comparison)
$0.03 per results page (20 listings) + $0.00005 per actor start. A failed parse raises before the charge event fires — a page that yields nothing is never billed. In incremental mode an idle scheduled run costs $0.
At depth, per-listing competitors can be cheaper — here is the real break-even, computed from their live prices (checked 2026-09-11):
| listings pulled | this actor (page-based) | blackfalcondata $0.00049/item + $0.005 start | memo23 $0.0009/item + $0.005 start |
|---|---|---|---|
| 20 (1 page) | $0.03005 | $0.0148 | $0.023 |
| 100 (5 pages) | $0.15005 | $0.054 | $0.095 |
| 400 | $0.60005 | $0.201 | $0.365 |
| 1,000 (max/run) | $1.50005 | $0.495 | $0.905 |
Read it straight: for one-off bulk pulls, the per-item leaders are cheaper. Where this actor wins:
- Scheduled monitoring — incremental idle runs are $0; per-item actors re-bill every listing on every run, forever.
- Coverage — 9 markets incl.
plin one schema; several leaders are single-market. - Change detection + free webhook/Telegram alerts built in — with the per-item leaders you re-pull and re-bill to diff yourself.
- Failed pages are never billed — the charge fires only on written pages.
Alternatives (and when to pick them)
- blackfalcondata/autoscout24-scraper (58k runs, 61 users/30d) — the volume leader; $0.00049/result is the cheapest bulk pull. Pick it for large one-off extracts. Expect re-billing on every monitoring run and no change detection.
- memo23/autoscout24-scraper (6k runs) — per-result pricing with
additional-dataevents; mid-priced bulk. - ivanvs/autoscout-scraper (32k runs) — $0.004/result tiered by plan; convenient if you already standardise on their output shape.
- Single-country actors (3x1t CH, fayoussef, others) — if you need exactly one market and nothing else.
- This actor — pick it for recurring price/inventory watches across markets, incremental $0 idle runs, change alerts, and a stable 34-field schema.
Troubleshooting
- Run failed with exit non-zero, 0 charges — a page failed to parse;
most often a transient AS24 response or a layout change. Re-run (free).
If it repeats on one
domainbut not others, report it — that's a parser gap, not your input. - 0 rows, 0 charges, status SUCCEEDED — the query genuinely matched
nothing. This is a valid empty answer, not a failure. Widen price/year
bands or drop
model. - Incremental run suddenly returns everything again — the filter set
changed (state is keyed per exact filter combo), or the state entry
(>20k ids) was rotated. Deduplicate on
iddownstream; the next run returns to new/changed only. previousPriceFormattedpresent but price looks identical —priceEuris the compared field; formatted strings can differ by formatting only. Diff onpriceEur.- Webhook/Telegram silent — check the run log; delivery is fail-soft and errors are logged, never fatal. $0 idle runs still POST the webhook (heartbeat by design).
Scheduler recipe (the intended use)
- Create one schedule per filter combo you track (e.g.
de/bmw/5–25k,at/audi/all,pl/volkswagen/under 40k). - Set
incremental: true— the actor remembers every delivered listing per query and delivers only new or changed ones on each run. A scheduled run where nothing changed costs $0: pages whose listings were all delivered before and unchanged are not charged. Your downstream never re-processes history. - Set
pages: 5for a stable daily snapshot of the top 100 listings (full mode) or of the new/changed-listings window (incremental mode).
State lives in the actor's key-value store, keyed per query
(domain+make+model+price/year/km/fuel set), bounded to the 20,000 most recent ids —
no unbounded growth, and each schedule/filter combo keeps its own stream.
Notifications (free — webhook & Telegram)
Close the loop without polling the dataset:
- Webhook (
webhookUrl): every finished run POSTs a JSON summary — query, mode, delivered/new/changed counts, pages charged, and up to 5 sample listings — including $0 idle runs, so your pipeline gets a heartbeat, not silence. Machine-readable, one endpoint, any receiver. - Telegram (
telegramBotToken+telegramChatId): a human-readable message ("3 new + 1 changed — de/bmw €5000-25000 • [price] BMW 320d € 19.900 (was € 20.900)…") sent only when there is something to read.
Both are free, forever — zero billing events, and fail-soft: a dead endpoint is logged and the run still succeeds with its dataset. Pair with incremental mode + a schedule for a complete new/changed-listings alert pipeline that costs $0 on quiet days.
FAQ
How many results can I get per run?
pages accepts 1–50; each page is 20 listings, so up to 1,000 rows per run.
For more, run multiple filter combos (make / model / price / year / km / fuel) — each is a cheap
separate run.
Which countries are covered?
Nine AutoScout24 country sites: de, at, ch, fr, it, es, nl,
be, pl — the same normalised schema from all nine, with countryCode
on every row.
Does it support recurring monitoring?
Yes — that is what it is built for. Two ways: schedule a run per filter
combo with incremental: true and get only the new or changed listings
each run — a price drop re-delivers the listing with changeType: "price"
and its previous price; a run with nothing new or changed costs $0. Or
leave incremental off and dedupe on the stable id + scrapedAt
(ISO 8601 UTC) fields yourself.
What happens if AutoScout24 changes their page?
The run fails loudly instead of emitting garbage rows — and you are not
charged: the listing-page-harvested event only fires after a page is
successfully parsed and written.
What if my query matches zero listings? The run SUCCEEDS with 0 rows and 0 charges — a valid empty answer, not a failure. Widen the make/price range and re-run (free).
Can I use it through an MCP server? Yes. The actor exposes an MCP server, so AI assistants can call it directly (see the MCP section above).
Can I pull the data into Python or Node?
Yes — the snippet above shows apify-client for Python; the same pattern
works in Node with apify-client from npm, or plain HTTP against the
Apify API.
Is there an official AutoScout24 API? No — AutoScout24 does not offer a public listings API. This actor is the practical alternative: structured JSON ready for a database, dashboard or model, no HTML parsing on your side.
Is it legal to scrape AutoScout24? The actor extracts publicly available listing data. Scraping public information is generally considered legal, but review the target site's terms and ensure your use case complies with applicable law, including GDPR where relevant.
Keywords
autoscout24 scraper, autoscout24 api, autoscout24 listings, car listings scraper, used car data europe, vehicle inventory feed, car price monitoring, dealer stock monitor, automotive market data, second hand car prices, autoscout24 deutschland, autoscout24 daten, gebrauchtwagen scraper, auto listings json, car market analysis europe, price watch schedule, vehicle data for ai agents, european car market dataset, incremental scraper, car search filters, filter by fuel diesel petrol electric, filter by mileage, filter by first registration year, bmw 3er monitor, new listings alert, new since yesterday, car monitor scheduler, webhook notifications, telegram alerts, price drop alert, price change monitor, price change alert, price drop monitor, car price tracker, listing change detection
Changelog
-
0.12 (2026-09-13) — Sample-output screenshot. The sample section now leads with a rendered table of a real run (de/bmw, 1 page, compact, 2026-09-13) hosted on our site, above the raw-JSON row. README-only change; no code, schema or pricing changes.
-
0.10.1 (2026-09-11) — README truth fixes + honest pricing. The field list and "Honest limits" still described the pre-0.9 output (denied sellerPhone/equipment/CO2 existed) — corrected to the real 34-field schema. Added pricing-at-depth break-even table vs live competitor prices (2026-09-11), Alternatives and Troubleshooting sections. No code changes; charges and schema unchanged.
-
0.10 (2026-09-07) — Compact mode. New
compact: trueinput: deliver only the 22 core fields per row — identity, price + AS24 price rating + price-drop flag, mileage, first registration, fuel, gearbox, power, seller type, city. Same rows, same charge events, identical incremental behaviour (change detection runs on the FULL row before compaction, so togglingcompactnever re-delivers the world or corrupts state). Built for dashboards and LLM contexts where the full 34-field schema is overhead. Independent gate: 20 live rows, 22/22 projected values byte-identical to the full rows, 0 mismatches (smoke/test_v10_compact.py, 10/10 PASS). -
0.9 (2026-09-06) — Detail enrichment at zero cost. 8 new fields per row, all extracted from the search page we already fetch — no extra requests, no new billing events, identical charge contract (per page with deliverable rows):
sellerPhone(formatted dealer phone, 19/20 in sample),sellerStreet,equipment(the listing's own equipment line),engineDisplacementCc,consumptionL100Km+co2Class(WLTP, EU 2023 A–G label; null when AS24 does not publish them),imageCount, andpriceDropFrom(AS24 "Super Deal" previous price — the on-site price-drop signal). Verified against a from-scratch re-parse of the same payload: 20/20 rows exact, 0 mismatches. -
0.8 (2026-09-06) — Search filters: model, year, mileage, fuel. Narrow the harvest before paying for pages:
model(URL path segment, e.g. bmw/3er),firstRegistrationFrom/firstRegistrationTo(year window),mileageFromKm/mileageToKm(km band) andfuel(7 codes: B/D/E/2/3/L/H). Every filter verified live against returned content on 2026-09-06 — afuel=Dquery returns only Diesel listings, a 2018–2020 window only 2018–2020 cars. Incremental state is keyed per full filter set, so overlapping queries never pollute each other's seen-listings. Same billing: one event per results page that carries deliverable rows. Zero-result filtered query = free, valid empty answer. -
0.7 (2026-09-06) — AS24 price-rating labels. Every row now carries
priceEvaluation(1–4) andpriceEvaluationLabel(very-good-price / good-price / fair-price / somewhat-expensive-price) — AutoScout24's own deal classification, the same signal buyers see on site. Rank deals in your pipeline without a separate evaluation step. Null when AS24 has not rated the listing. Zero new requests, zero new billing events; incremental fingerprints unchanged (rating drift ≠ listing change). -
0.6 (2026-09-01) — Free notifications: optional
webhookUrl(JSON run summary on every finished run, including $0 idle runs) andtelegramBotToken+telegramChatId(human-readable message when there are new/changed listings). Zero billing events, fail-soft — a broken endpoint never fails a run. No changes to scraping, incremental state or pricing. -
0.5 (2026-09-01) — Change detection in incremental mode: the actor now tracks price, mileage, offer type and seller per listing between runs. A changed listing is re-delivered with
changeType(price,mileage,seller,offer-type, or+-joined) andprevious*fields showing the old values. Changes are delivered exactly once; a run with nothing new or changed still costs $0. Backward compatible with 0.3 incremental state (ids without fingerprints are treated as unchanged until first seen in 0.4). Full mode unchanged. -
0.3 (2026-09-01) — Incremental mode: set
incremental: trueand the actor remembers delivered listings per query (key-value store, bounded to 20k ids) and delivers only new ones. Pages with no new listings are not charged — an idle scheduled run costs $0. Full mode unchanged (defaultfalse). -
0.1.8 (2026-08-26) — README v3: restored the full store listing (FAQ, sample output, AI-agent reference, keywords) that a hotfix deploy had silently replaced with an early draft. No code changes.
-
0.1.7 (2026-08-24) — Empty-answer correctness gate: a query the site answers with zero listings now SUCCEEDS with 0 rows and 0 charges instead of failing red. Bad input is still rejected before any charge.
-
0.2 / 0.1.6 (2026-08-20) — Public store release. Pay-per-event pricing ($0.03 / results page, failures never charged). Poland (
pl) added — 9 markets total. Loud-fail parser guardrails. -
0.1 (2026-08-19) — Initial build: 8 markets, normalised 23-field schema, scheduler-oriented design, private QA runs.
Honest limits
- Search-result depth: the 34 fields above, from the search page (v0.9 added phone/street/equipment/CO2 at zero extra cost). Not included: the full free-text description and image galleries — that is a per-listing detail-page product, slower and costlier.
- Prices on non-EUR sites (e.g.
ch) are normalised to a raw integer in the listing's local currency;currencyis set per row accordingly. - Server-rendered source; if AutoScout24 changes its page structure the actor fails loudly (zero charge) rather than emitting garbage.
- Politeness: ~1.5 s between page fetches. 50 pages ≈ 2 minutes.
Made by an AI agent
This actor was designed, built and tested by an autonomous AI agent (Jarvis Turbo, operator: Bartosz). [AI-authored — no human wrote this code.]