Most car-data projects begin by building a valuation model, because the obvious question — “is this car cheap?” — needs a reference price. Coches.net publishes one. Two fields, filled on 77.6% of listings, that answer the question the model was going to answer.
What the two fields are
price_average_indicator_eur— coches.net's own estimate of what this model is worth on the Spanish market.price_rank_indicator— where this particular listing sits against that estimate.
The marketplace computes the estimate itself and publishes it next to the asking price, in the search results. This Actor passes both through unchanged rather than deriving anything from them, which is deliberate: dressing somebody else's estimate up as your own valuation is how a dataset acquires an error nobody can trace.
Coverage, and the dealer/private split
Measured on 550 listings across 35 makes and 38 provinces:
| Segment | Valuation present |
|---|---|
| All listings | 77.6% |
| Dealer listings | 86.6% |
| Private listings | 38.2% |
That gap is the single most important thing on this page. A screen filtered on the valuation is not a screen of the market — it is a screen of the dealer market plus a third of the private market, and any conclusion about private-versus-dealer pricing drawn from it inherits the bias.
Coches.net does not document why the coverage differs. The measurement stands; the explanation is not mine to give.
Using them to find underpriced cars
The naive version is one comparison: asking price below the estimate. The version that survives contact with the data uses both fields and a percentage:
SELECT ad_id, make, model, year, km, price_eur,
price_average_indicator_eur AS market_eur,
ROUND(100.0 * (price_average_indicator_eur - price_eur)
/ price_average_indicator_eur, 1) AS gap_pct
FROM listings
WHERE price_average_indicator_eur IS NOT NULL
AND price_eur < price_average_indicator_eur * 0.90
AND price_rank_indicator IN ('below_market', 'good_price')
AND data_age_hours < 48
ORDER BY gap_pct DESC;The data_age_hours condition is not decoration. A bargain from a week-old cached row is frequently a car that has already sold, and the freshness fields exist precisely so this can be a condition rather than a hope.
The full workflow, including the gaps that look like bargains and are not, is in finding used cars priced below market.
Three honest limits
- It is the marketplace's estimate, not an independent one. That is its value — it is the number the market itself publishes and buyers are shown — and it is not a claim about accuracy. Coches.net does not publish the methodology behind it.
- It is missing on 22.4% of listings, unevenly.
- It is a model-level average. A 320d Touring with 40,000 km and one with 180,000 km are compared against the same reference, which is why mileage has to be in your screen even though the valuation appears to have priced it in. It has not.
Handling the missing 22.4%
The dangerous failure is silent exclusion. A query with price_eur < price_average_indicator_eur * 0.9 and no null handling quietly drops every listing without a valuation — which is most private sellers, often the cheapest segment.
Three defensible approaches:
- Exclude explicitly and report the count you removed. Honest and easy.
- Impute from your own rows: group by make, model and year band and use the median asking price of the group. Weaker than the site's estimate but it covers everything.
- Segment the analysis: run dealers and private sellers separately and never compare the two directly, since their coverage differs by more than two to one.
Building your own valuation instead
Worth doing if valuation is your product rather than a filter. The inputs are all at 100% coverage — make, model, year, mileage, power, province, fuel type, seller type — which is a better feature set than most public car datasets offer, and the site's own estimate becomes a benchmark to test yours against rather than a dependency.
For everyone else, two fields that already exist beat a model you have to maintain. Of the eleven coches.net scrapers on Apify at the time of writing, one other exposes them — which is the actual reason this page exists.



