---
title: "Used Car Listing Data: Fields for Price Analysis"
description: "Which fields a used-car price model needs (mileage, year, trim, seller type, days listed) and how AutoScout24, CarGurus and AutoTrader UK return them."
url: https://perceptlayer.com/blog/used-car-listing-data-price-analysis
---

[Blog](https://perceptlayer.com/blog) / [Web data by industry](https://perceptlayer.com/blog/category/web-data)

# Used Car Listing Data: Fields for Price Analysis

21 Aug 2026 Perceptlayer 7 min read

A used-car price model needs a target and six candidate features from every listing. The target is the advertised price. The features are mileage, first-registration year, make with model and trim, power or engine, seller type (dealer or private) and how long the car has been listed. The AutoScout24, CarGurus and AutoTrader UK search endpoints return most of these as named JSON fields. None returns all of them in the same shape, so the real work is normalising them.

## Key takeaways

-   Price is the target. Mileage, year, trim, power and seller type are the candidate features; `days_on_market` (CarGurus) is the only listing-age field in the recorded search responses.
-   AutoScout24 reports mileage as `mileage.value_km`, CarGurus as `mileage.value` with a `MILES` unit, and the recorded AutoTrader UK search results carry no mileage at all.
-   Prices come in three currencies ( `EUR`, `USD`, `GBP`). Don't compare them without converting. The recorded responses have a single price field and no sale-price field.
-   Each marketplace returns its own deal-rating field ( `evaluation`, `rating`, `price_indicator`) with its own values, so use them as features inside one market, never across markets.
-   Pulling the 193 BMW 316 listings matching `market=de`, `model_id=1639` and EUR 5,000 to 20,000 in the recorded AutoScout24 search takes 10 calls at 1 credit each: 10 credits.

## Which listing fields matter for a used-car price model?

The advertised price is the target. The candidate features are mileage, first-registration year, make-model-trim, power or engine, seller type and listing age. Treat listing age as a feature to test rather than assume; your own data will show whether it carries signal. Everything else (colour, photo count, dealer name) is secondary until those six are clean.

The table maps the target and those features to what each endpoint returned in the recorded responses.

| Feature | AutoScout24 `search` | CarGurus `search` | AutoTrader UK `search` |
| --- | --- | --- | --- |
| Price | `price.amount`, `price.currency` ( `EUR`) | `price.amount`, `price.currency` ( `USD`) | `price.amount`, `price.currency` ( `GBP`) |
| Mileage | `mileage.value_km` | `mileage.value`, `mileage.unit` ( `MILES`) | not in the recorded excerpt |
| Year | `first_registration.year`, `.month` | `year` | `tracking_context.year` |
| Make, model | `make`, `model`, `model_group` | `make`, `model`, `make_id`, `model_id` | `title`, `tracking_context.make`, `.model` |
| Trim | `motor_type` (engine designation); `variant` is the body variant | `trim` | `sub_title` (free text) |
| Power | `power.kw`, `power.ps` | `power` (hp), `engine` | no power field in the recorded search record |
| Seller type | `seller.type` ( `Dealer`, `PrivateSeller`) | `seller_type` ( `DEALER`) | `seller_type` ( `PRIVATE`) |
| Listing age | not in the recorded excerpt | `days_on_market` | not in the recorded excerpt |
| Identifier | `listing_id` | `listing_id`, `vin` | `advert_id` |

Blank cells in this table mean the field wasn't in the recorded search response. Each marketplace also has a single-listing endpoint ( `listing` with `listing_id` on [AutoScout24](https://perceptlayer.com/apis/autoscout24/listing), `advert_id` on [AutoTrader UK](https://perceptlayer.com/apis/autotrader-uk/listing)). Run one in the playground on the API page to see what the detail view adds before you build around a gap.

## How do you pull comparable listings from AutoScout24?

Call `GET /v1/autoscout24/search` with a make, a model and a price band, and page through the results. The endpoint filters on `make_id`, `model_id`, `registration_year_min`, `registration_year_max`, `mileage_min`, `mileage_max` and `seller_type`, so you can cut the sample to the cars you want to compare before any code runs. Each call costs 1 credit.

```bash
curl "https://api.perceptlayer.com/v1/autoscout24/search?market=de&make_id=13&model_id=1639&price_min=5000&price_max=20000&sort=price&page=2&limit=20" \
  -H "X-API-Key: $API_KEY"
```

The `make_id` and `model_id` values come from the [taxonomy endpoint](https://perceptlayer.com/apis/autoscout24/taxonomy) ( `include[]=makes`, `include[]=models`). Here is an excerpt of the recorded response, trimmed:

```json
{
  "price": { "amount": 5800, "currency": "EUR", "evaluation": 1, "is_evaluation_enabled": true },
  "mileage": { "value_km": 177000, "unit": "km" },
  "first_registration": { "raw": "01/2012", "year": 2012, "month": 1 },
  "power": { "kw": 85, "ps": 116 },
  "make": "BMW",
  "model_group": "3er",
  "variant": "Limousine",
  "motor_type": "316d",
  "seller": { "id": "…", "type": "PrivateSeller" },
  …
}
```

That one record already carries price, mileage, year and month, power, body variant, engine designation and seller type. The pagination block in the same response reports `total: 193` across `total_pages: 10` at `limit: 20`, so the whole sample is 10 calls: 10 × 1 credit = 10 credits. The [pagination guide](https://perceptlayer.com/blog/paginate-web-data-api-python) covers safe page loops.

## What do CarGurus and AutoTrader UK return instead?

CarGurus returns the richest record for pricing work in the recorded sample: a VIN, a `trim`, a drivetrain, `days_on_market` and a `seller_type`. AutoTrader UK returns a clean price and year but keeps trim inside a text string. Both are single calls per page at 1 credit, so the difference is in the fields, not the cost.

```bash
curl "https://api.perceptlayer.com/v1/cargurus/search?make_model_trim_paths=m26%2Fd126&distance=50000&sort=best_match" \
  -H "X-API-Key: $API_KEY"
```

From the recorded CarGurus response:

```json
{
  "listing_title": "1996 GMC Suburban",
  "vin": "…",
  "year": 1996,
  "trim": "K1500 4WD",
  "price": { "amount": 7995, "currency": "USD", "rating": "NA" },
  "mileage": { "value": 175456, "unit": "MILES" },
  "days_on_market": 14,
  "seller_type": "DEALER",
  …
}
```

The [CarGurus search endpoint](https://perceptlayer.com/apis/cargurus/search) takes `make_model_trim_paths` ( `m26/d126` above is a make and model path), `price_min`, `price_max`, `distance`, `sort` and `page`. You can sort by `date` or `deal_score` as well as `price` and `mileage`. The [makes](https://perceptlayer.com/apis/cargurus/makes) and [models](https://perceptlayer.com/apis/cargurus/models) endpoints list the IDs.

The [AutoTrader UK search endpoint](https://perceptlayer.com/apis/autotrader-uk/search) requires a `postcode` and filters on `min_mileage`, `max_mileage`, `min_year_manufactured`, `max_year_manufactured` and `seller_type` ( `private` or `trade`). The recorded excerpt looks like this:

```json
{
  "title": "BMW 5 Series",
  "sub_title": "2.0 518d SE Euro 6 (s/s) 4dr",
  "price": { "amount": 2200, "currency": "GBP" },
  "seller_type": "PRIVATE",
  "tracking_context": { "make": "BMW", "model": "5 Series", "year": 2014, "price_indicator": "NOANALYSIS" },
  …
}
```

Mileage isn't in that excerpt. You can still get at it: filter with `min_mileage` and `max_mileage` to build mileage bands, or sort by `mileage`. Set `price_search_type=total` so you collect full prices rather than monthly finance figures.

## Where does cross-market comparison break down?

It breaks in five places: currency, mileage units, trim vocabulary, seller-type labels and the marketplace's own deal rating. Each is a mechanical fix, but only if you handle it before pooling the data. Skip any one and a "UK cars are cheaper" result may just be pounds against euros.

-   **Currency and units.** Prices arrive as `EUR`, `USD` and `GBP`. CarGurus mileage is in miles, AutoScout24 in kilometres. Convert mileage to one unit, and model each market's price in its own currency until you've chosen an exchange-rate source and date.
-   **Trim.** CarGurus gives `trim` as a field. AutoScout24 has no trim field in the recorded record: `variant` is a body variant ( `Touring`, `Limousine`) and `motor_type` the engine designation. AutoTrader UK embeds trim wording in `sub_title`. Matching "the same car" across markets means parsing, and some parsing will fail.
-   **Seller type.** `Dealer` or `PrivateSeller` on AutoScout24, `DEALER` on CarGurus, `PRIVATE` on AutoTrader UK. Map them to one vocabulary. Keep the flag as a feature and let your data show whether it matters.
-   **Deal ratings.** AutoScout24 has `price.evaluation`, CarGurus `price.rating`, AutoTrader UK `price_indicator`. They are separate fields with different values ( `1` and `2`, `NA`, `NOANALYSIS` in the recorded responses), and the responses don't say how each is computed. Don't pool them, and don't use one as your target if you're predicting price.
-   **Localised text.** The recorded AutoScout24 `transmission` value is `Schaltgetriebe`, not "manual". Filter with the coded values from the taxonomy endpoint and normalise display text yourself.

One caveat applies everywhere: the price in each record is the advertised price as found at the time of the call. The recorded responses carry no sale-price field, and a negotiated sale can land away from the ask. If you need mileage you can trust, official records beat adverts: in the UK, the [GOV.UK MOT history service](https://www.gov.uk/check-mot-history) shows the mileage recorded at each test. For decoding a CarGurus `vin` into factory specs, the [NHTSA vPIC API](https://vpic.nhtsa.dot.gov/api/) decodes a VIN into key-value pairs.

## How do you normalise three marketplaces into one table?

Write one small mapper per marketplace that outputs the same keys, and keep the currency as a column. The script below fetches one page from each source and prints a pooled table; the AutoTrader UK mileage stays `None` because the search record doesn't carry it.

```python
import os
import requests

BASE = "https://api.perceptlayer.com"
HEADERS = {"X-API-Key": os.environ["API_KEY"]}
KM_PER_MILE = 1.609344

def listings(path, **params):
    r = requests.get(BASE + path, headers=HEADERS, params=params, timeout=30)
    r.raise_for_status()
    return r.json()["data"]["listings"]

def from_autoscout24(l):
    return {
        "source": "autoscout24",
        "currency": l["price"]["currency"],
        "price": l["price"]["amount"],
        "km": (l.get("mileage") or {}).get("value_km"),
        "year": (l.get("first_registration") or {}).get("year"),
        "trim": f'{l.get("variant", "")} {l.get("motor_type", "")}'.strip(),
        "seller": "dealer" if l["seller"]["type"] == "Dealer" else "private",
        "days_listed": None,
    }

def from_cargurus(l):
    m = l.get("mileage") or {}
    km = m["value"] * KM_PER_MILE if m.get("unit") == "MILES" else None
    return {
        "source": "cargurus",
        "currency": l["price"]["currency"],
        "price": l["price"]["amount"],
        "km": km,
        "year": l.get("year"),
        "trim": l.get("trim"),
        "seller": l["seller_type"].lower(),
        "days_listed": l.get("days_on_market"),
    }

def from_autotrader_uk(l):
    return {
        "source": "autotrader-uk",
        "currency": l["price"]["currency"],
        "price": l["price"]["amount"],
        "km": None,
        "year": (l.get("tracking_context") or {}).get("year"),
        "trim": l.get("sub_title"),
        "seller": l["seller_type"].lower(),
        "days_listed": None,
    }

rows = [
    *map(from_autoscout24, listings("/v1/autoscout24/search", market="de", make_id=13, model_id=1639, limit=20)),
    *map(from_cargurus, listings("/v1/cargurus/search", make_model_trim_paths="m26/d126", distance=50000)),
    *map(from_autotrader_uk, listings("/v1/autotrader-uk/search", postcode="SW1A1AA", price_search_type="total", make="BMW")),
]
for row in rows:
    print(row)
```

That's 3 calls × 1 credit = 3 credits. Add `page` loops to build a real sample, and keep a `collected_at` timestamp on each row so repeat pulls become a price history.

## What does a monthly price snapshot cost?

A repeatable snapshot is the pages in your sample times the number of pulls. Using the recorded AutoScout24 search, 193 listings at 20 per page is 10 calls. Pulled weekly for a year, that's 52 × 10 = 520 credits, which fits inside the free tier's 1,000 credits a month. Failed calls cost nothing.

Add a second marketplace and the arithmetic stays visible: 10 pages from each of three sources is 30 credits per snapshot. Credits come in prepaid packs that last 12 months; the [pricing page](https://perceptlayer.com/pricing) has what credits cost, and [credits in the docs](https://docs.perceptlayer.com/credits) explains debits. If a snapshot job runs unattended, read the [rate limit headers](https://docs.perceptlayer.com/rate-limits) and wait on a 429 for the `Retry-After` seconds.

Next step: [get a free API key](https://perceptlayer.com/signup), run the AutoScout24 call above in the playground on its [API page](https://perceptlayer.com/apis/autoscout24), and check which fields come back for the make you care about. For the same field-by-field approach on property data, see [real estate listing data for valuation](https://perceptlayer.com/blog/real-estate-listing-data-valuation-fields).

## APIs in this post

-   [AutoScout24 **1 credit per call** · 6 endpoints](https://perceptlayer.com/apis/autoscout24)
-   [CarGurus **1 credit per call** · 4 endpoints](https://perceptlayer.com/apis/cargurus)
-   [AutoTrader UK **1 credit per call** · 6 endpoints](https://perceptlayer.com/apis/autotrader-uk)

## Frequently asked questions

### Which field matters most for predicting a used car's price?

Mileage and first-registration year are the first features to test, alongside make, model and trim; your own data will show their weights. In the recorded AutoScout24 results, a 316d Touring from a dealer (215,000 km, first registered 06/2013) asks EUR 5,700, while a 316d Limousine from a private seller (177,000 km, 01/2012) asks EUR 5,800. A 38,000 km gap moved the ask by only EUR 100 because body, seller and age differ too, which is why you test fields together.

### Do these endpoints return the price a car actually sold for?

Not in the recorded responses. Each has one price field, `price.amount`, with no separate sale-price field, and data is returned as found at the time of the call. Treat listing data as a view of advertised levels, and confirm any sale-price need in the playground before you build around it.

### How do I get listing age for AutoScout24 or AutoTrader UK?

The recorded search responses for those two don't include a listing-age field; CarGurus returns `days_on_market`. For the others you can sort by `age` (AutoScout24) or `most_recent` (AutoTrader UK) to order by recency, or record the first date you see each `listing_id` or `advert_id` in repeated pulls and compute age yourself.

### Can I cover several countries with one key?

Yes. One key works across the whole catalogue, including these three marketplaces. AutoScout24 takes a `market` parameter with values `de`, `at`, `be`, `it`, `fr`, `nl`, `es`, `com` and `pl`. Each call costs 1 credit. Keep the currency and mileage unit per row, since they differ by market.

### What happens if a call fails?

A failed call costs nothing and returns `X-Credits-Used: 0`. Errors come back as an HTTP status with a JSON body holding `code`, `message` and `request_id`, such as `rate_limited` (429) or `invalid_parameters` (422). A client timeout is the exception: the request may have succeeded and been billed. The [errors docs](https://docs.perceptlayer.com/errors) list every code.

used cars car listings price analysis autoscout24 cargurus autotrader uk

## More from the blog

1.  [API guides](https://perceptlayer.com/blog/category/api-guides) 7 Aug 2026 Perceptlayer 7 min read
    
    ## [AutoScout24 API: Search European Car Listings as JSON](https://perceptlayer.com/blog/autoscout24-api-car-listings-json)
    
    Search AutoScout24 listings as JSON: make\_id and price filters, a recorded BMW response, and what a monthly price sweep costs in credits.
    
2.  [API guides](https://perceptlayer.com/blog/category/api-guides) 23 Oct 2026 Perceptlayer 7 min read
    
    ## [Cars.com API: Used Car Listings and Price Evaluations](https://perceptlayer.com/blog/cars-com-api-listings-price-evaluation)
    
    Search Cars.com listings with its six required parameters (zip, radius\_miles, stock\_type, sort, page, page\_size), then listing, dealer and price-eval calls.
    
3.  [Web data by industry](https://perceptlayer.com/blog/category/web-data) 21 Oct 2026 Perceptlayer 8 min read
    
    ## [Job Posting Data for Labour-Market Research](https://perceptlayer.com/blog/job-posting-data-labour-market-research)
    
    Which Indeed posting fields support trend analysis, where postings mislead versus hires, and a weekly collection plan that costs 3,000 credits a month.
