AutoScout24 Price Market — True Population Price Quantiles
Pricing
from $20.00 / 1,000 model market summaries
AutoScout24 Price Market — True Population Price Quantiles
Population price statistics for any car make/model on AutoScout24 in one call: the exact stock count and the true p10/p25/median/p75/p90 of the whole listing population, read from the site's own exact hit counts at price ceilings. Listing dumps stop at 200 pages and cannot reach these numbers.
Pricing
from $20.00 / 1,000 model market summaries
Rating
0.0
(0)
Developer
h ichi
Maintained by CommunityActor stats
0
Bookmarked
2
Total users
1
Monthly active users
2 days ago
Last modified
Categories
Share
What is the median asking price of a BMW 3 Series in Germany? There are 11,013 of them listed on AutoScout24 right now. No listing scraper on this Store can answer that question — and the reason is not effort, it is arithmetic.
AutoScout24 stops paginating at 200 pages. Measured 2026-08-02: numberOfPages returns 200 for a 4,981-car result set, 200 for an 11,013-car result set, and 200 for the 62,236-car BMW population. At ~20 cars a page that is a hard ceiling of about 4,000 listings. A dump-style Actor cannot reach the middle of an 11,013-car market in principle, however many pages it pays for — and the 13 AutoScout24 scrapers already on the Store are all dump-style.
priceto=X is a different door. It is a search filter, and the site reports the exact hit count for any filter, so priceto=8600 answers "2,352 cars cost €8,600 or less" — a population CDF, exactly. Twelve of those requests give the real p10 / p25 / median / p75 / p90 with zero sampling error, in about 40 seconds.
That is what this Actor sells: one compact market record per make/model, with
price— p10 / p25 / median / p75 / p90 of the whole listing population, read out of the site's own exact counts and interpolated inside population bands. Never a page sample. In EUR and USDtotalFound— the exact live stock count, andpageCapReachedtelling you whether this is a market a listing dump could have reached at allladderandbands— the raw CDF, so you can rebuild any quantile or histogram yourselfsampleStats— dealer vs private split, median mileage, median registration year, fuel and gearbox mix, drawn newest-first (an ordering independent of price)- Optionally every sampled listing (price, mileage, first registration, fuel, gearbox, power, dealer or private)
Eight country front-ends: Germany, Austria, France, Italy, Spain, Netherlands, Belgium and the English-language international site. No login, no API key, no proxy, nothing stored between runs.
Pricing — from $0.02 per make/model, no subscription
| Event | Price | When |
|---|---|---|
| Make/model market summary | $0.02 | Per make/model analyzed |
| Individual listing | $0.002 | Only if you enable Include individual listings |
A default run (1 model, summary only) costs $0.02 and makes 14 requests in about 40 seconds — roughly 2.4 MB on the wire, since every AutoScout24 page is ~170 KB gzipped (~720 KB decompressed). Two models fit comfortably in one call; beyond that the run's time budget starts trimming the ladder and says so in the record. A make/model that returns nothing is never charged.
Input
| Field | Example | Notes |
|---|---|---|
models | ["bmw/3er"] | make or make/model slugs, or a full AutoScout24 search URL. Each costs $0.02 |
country | "de" | de, at, fr, it, es, nl, be, com. Sets the market, the domain and the currency |
ladderSteps | 9 | Price ceilings to get exact counts for. One request each |
refineSteps | 3 | Extra requests spent bisecting whichever band a quantile is stuck in, widest first |
mileageMax | 100000 | Optional. Conditions the whole analysis on cars at or below this mileage |
firstRegistrationFrom | 2018 | Optional. Conditions the whole analysis on cars first registered from this year |
maxListings | 20 | Listings kept for the mix sample. Does not affect the price quantiles |
includeIndividualItems | false | Also emit each sampled listing |
convertToUsd | true | Adds USD stats at the current exchange rate |
mileageMax and firstRegistrationFrom condition the entire record — the stock count, the ladder and the quantiles all become "given this filter". {"models": ["bmw/3er"], "mileageMax": 100000, "firstRegistrationFrom": 2018} is the price distribution of a 2018-or-newer 3 Series under 100,000 km: the shape a trade-in quote or a residual-value model actually needs, and one no listing dump can produce.
Model slugs are localised — bmw/3er on de/at, bmw/serie-3 on fr, bmw/3-series on it/es/nl/be/com. You do not have to know which: AutoScout24 308-redirects to its own slug and the Actor follows it while re-attaching your filters, which the redirect itself strips. resolvedName on the record tells you what the site decided you meant ("BMW Série 3" when bmw/3er is sent to France).
The one thing to understand: counts are exact, the mix is a sample
Every block carries its own basis and the record never lets the two blur:
| Block | basis | Why |
|---|---|---|
price, ladder, bands, totalFound | count-ladder | Each rung is a filter, and AutoScout24 prints the exact hit count for whatever filter you send. priceto=17500 returning 4,410 means 4,410 cars cost €17,500 or less, full stop. The quantiles are exact at every band edge and linearly interpolated inside the band they land in |
sampleStats | sample | Dealer share, mileage and age come from the ~20 listings actually fetched, with n stated. They are drawn sort=age&desc=1 — newest first — because that ordering is independent of price. A price-sorted page would tell you what the cheap end of the market looks like, which is a different question |
If the ladder ever comes back non-monotonic, or flat (the signature of a filter the site did not apply), the Actor does not publish it as a population figure: it falls back to statistics over the listings it fetched, flips priceBasis to "sample", and adds a caveat saying so. You never have to guess which kind of number you are holding.
Output example (type: "market_summary", real measured output)
BMW 3er on autoscout24.de, 2026-08-02, 14 requests, 40 seconds:
{"type": "market_summary","model": "bmw/3er","make": "bmw","modelSlug": "3er","country": "de","countryName": "Germany","currency": "EUR","totalFound": 11013,"numberOfPages": 200,"pageCapReached": true,"resolvedCategory": "ma13gr100038","resolvedName": "BMW 3er","price": {"p10": 4584, "p25": 10182, "median": 23030, "p75": 35857, "p90": 46228,"min": 1, "max": 1000000, "count": 11013},"priceBasis": "count-ladder","ladder": [{ "priceTo": 500, "cumulativeCount": 6, "cumulativeShare": 0.0005 },{ "priceTo": 950, "cumulativeCount": 51, "cumulativeShare": 0.0046 },{ "priceTo": 1800, "cumulativeCount": 221, "cumulativeShare": 0.0201 },{ "priceTo": 3500, "cumulativeCount": 786, "cumulativeShare": 0.0714 },{ "priceTo": 4800, "cumulativeCount": 1164, "cumulativeShare": 0.1057 },{ "priceTo": 6700, "cumulativeCount": 1761, "cumulativeShare": 0.1599 },{ "priceTo": 12500, "cumulativeCount": 3414, "cumulativeShare": 0.3100 },{ "priceTo": 17500, "cumulativeCount": 4410, "cumulativeShare": 0.4004 },{ "priceTo": 24500, "cumulativeCount": 5798, "cumulativeShare": 0.5265 },{ "priceTo": 34000, "cumulativeCount": 7964, "cumulativeShare": 0.7231 },{ "priceTo": 46500, "cumulativeCount": 9955, "cumulativeShare": 0.9039 },{ "priceTo": 88500, "cumulativeCount": 10997, "cumulativeShare": 0.9985 }],"bands": [{ "from": null, "to": 500, "count": 6 },{ "from": 500, "to": 950, "count": 45 },{ "from": 950, "to": 1800, "count": 170 },{ "from": 1800, "to": 3500, "count": 565 },{ "from": 3500, "to": 4800, "count": 378 },{ "from": 4800, "to": 6700, "count": 597 },{ "from": 6700, "to": 12500, "count": 1653 },{ "from": 12500, "to": 17500, "count": 996 },{ "from": 17500, "to": 24500, "count": 1388 },{ "from": 24500, "to": 34000, "count": 2166 },{ "from": 34000, "to": 46500, "count": 1991 },{ "from": 46500, "to": 88500, "count": 1042 },{ "from": 88500, "to": null, "count": 16 }],"sampleStats": {"basis": "sample","sampleDesign": "newest-listings-first (sort=age), price-independent","n": 17,"dealerCount": 8, "privateSellerCount": 9,"dealerShare": 0.4706, "privateShare": 0.5294,"medianMileageKm": 190000,"medianFirstRegistrationYear": 2011,"medianAgeYears": 15,"medianPrice": 11900,"fuelTop": [["Diesel", 10], ["Benzin", 7]],"transmissionTop": [["Schaltgetriebe", 9], ["Automatik", 8]],"excludedNonOrganic": 3},"ocsResultsReported": 212,"filters": {"mileageMaxKm": null, "firstRegistrationFrom": null,"damagedListings": "excluded", "vehicleState": "new+used"},"requestsMade": 14,"priceUsd": { "p10": 5277, "p25": 11721, "median": 26511, "p75": 41277, "p90": 53215 },"exchangeRateEurUsd": 1.15115,"sourceUrl": "https://www.autoscout24.de/lst/bmw/3er?atype=C&cy=D&damaged_listing=exclude&desc=0&powertype=kw&sort=price&ustate=N%2CU","checkedAt": "2026-08-02T15:42:01Z"}
Read the ladder and the size of the problem becomes obvious. Half the German 3 Series market is under €24,500 — but 5,798 cars sit below that line, and the page cap can only ever show you about 4,000. The median is on the far side of a wall that paging cannot climb. The same call against France returns 1,371 cars and a €26,523 median: the same car, a market 8× smaller and 15% dearer.
What this Actor does not do
- No personal data, ever. AutoScout24's listing JSON does carry
seller.contactName(a named individual),seller.phones[]andlocation.street— for private sellers too. Those fields are dropped at the parser, not filtered at the end, and a guard asserts no emitted record contains them. A dealer keeps its company name; a private seller keeps nothing beyond the country its car is in. This is a market-structure tool, not a lead scraper — which is exactly where the existing AutoScout24 Actors, several of which advertise "Dealer Data" and "Phone Numbers", are pointed - No
/lst?. AutoScout24's robots.txt disallows the make-less all-inventory search, so a make is always required and there is no free-text keyword mode. It also disallows both GraphQL endpoints and the lightweight count-only API, so this Actor pays for a full HTML page per count rather than take the cheap route it is not allowed to take - No detail-page fetching.
/angebote/is disallowed. Listing URLs are emitted so you can open them; they are never requested - No
cat=in any URL (Disallow: /*?*cat=*). The site resolves the category itself and echoes it back, which is whereresolvedCategorycomes from - No browser, no proxy, no stored dataset. Plain HTTP, 256 MB, every run fetches live
Notes on the data
- Asking prices, not transaction prices. Used cars turn over slowly and get repriced often; treat these as the live ask distribution
minandmaxare outliers by construction. A measured BMW 3er is listed at €1 (flaggedpriceLabel: toolow-price) and another at €1,000,000. The ladder deliberately starts at €500 and its top rung is anchored near the 99.8th percentile rather than the maximum, so the quantiles are unaffected — but do not readmin/maxas market signal- Promoted slots are excluded from the sample.
searchResultType: "Nfm"entries look exactly like plain hits —isOcs: false,Mainsection — and only that one field gives them away.excludedNonOrganicreports how many were dropped. The site's defaultsort=standardis tier-weighted too: a measured page was 20 dealers out of 20, which is why every request here sends an explicit sort - A page renders 17-20 listings, not 20. The count varies with how many placements the page carried, so
nis always measured - No listing dates. AutoScout24's result pages carry no publication timestamp, so no turnover or days-on-market metric is possible.
firstRegistrationgives the fleet's age distribution instead - Run it without a proxy. Verified 2026-08-02 with the internal
dc-ip-probe, using the filtered URL form (&priceto=…), not just the bare one: a plain Apify datacenter IP gets 200 with and without the datacenter proxy, at every price ceiling tested - Counts drift between runs. AutoScout24's inventory changes minute to minute; the same query measured 11,008 / 11,012 / 11,013 within an hour. The ladder is internally consistent because every rung of one run is fetched within ~30 seconds