European classifieds
A retail price surface of 9.8M listings in the 2026-08-18 coverage snapshot gathered from 681 origin portals — national classifieds sites, dealer groups and manufacturer stock pages — across 39 European countries: mobile.de, kleinanzeigen.de, autoscout24, leboncoin.fr, lacentrale.fr, autosupermarket.it, njuskalo.hr and hundreds more. Every listing keeps its origin portal in source_site, so the same feed answers a national question and a portal-level one. These are retail listings, not auction inventory: no bidding, no auction end date, no detail payload and no gallery, just a single remote thumbnail per listing. They live in their own tables with their own vocabulary (seller type, origin portal), which is why they get their own query surface instead of a site slug on /api/search. Ended and paid-placement ("promoted") rows are excluded from every response, and all three endpoints return 503 while the dataset has not been built yet. Scope: classifieds. Legacy /api/theparking/* paths and theparking grants remain compatible aliases.
Calling it end to end
- 1Call GET /api/classifieds/facets once and cache it. Everything sits under a facets key: countries, brands, fuels, gearboxes, sellers, sources, value_counts and totals. It takes no filters — it always describes the whole feed. Never hard-code these values: brand, model, fuel, gearbox and seller are compared case-sensitively, so copy the spellings from here.
- 2When the user picks a brand, call GET /api/classifieds/models?brand=BMW,Audi to fill the model select. Models come back most common first, capped at 400.
- 3Query GET /api/classifieds/listings with the chosen filters. Multi-value filters are comma-separated: they OR within a parameter and AND across parameters. Page with limit/offset or page/page_size — limit caps at 100. If you do not need a match count, pass include_total=false: it is the fastest way to page this feed.
- 4Render each row directly. There is no detail endpoint and no gallery: the listing object you receive is the entire record, with one remote thumbnail in image_url and a deep link out in offer_url.
- 5To use it as a market reference, query the same brand, model, and year window you are about to bid on, read the price_eur spread by seller_type, and diff it against the auction lot’s public_price_eur.
Coverage by country
9,808,689 active listings as of 2026-08-18, across 39 countries and 681 origin portals. The figures move with every refresh — read them as proportions, and take live counts from /api/classifieds/facets.
| Country | country= | Listings | Portals | Largest origin portals |
|---|---|---|---|---|
| Germany | de | 2,218,902 | 101 | mobile.de, kleinanzeigen.de, autoscout24.de, volkswagen.de, pkw.de, instamotion.com |
| France | fr | 1,328,466 | 148 | leboncoin.fr, lacentrale.fr, zoomcar.fr, autocadre.com, spoticar.fr, paruvendu.fr |
| Italy | it | 1,076,206 | 61 | subito.it, autoscout24.it, quattroruote.it, autosupermarket.it, automobile.it, automoto.it |
| Spain | es | 710,370 | 68 | coches.net, milanuncios.com, autoscout24.es, autocasion.com, motorflash.com, coches.com |
| Netherlands | nl | 640,482 | 63 | autowereld.nl, marktplaats.nl, autotrack.nl, autoscout24.nl, viabovag.nl, autokopen.nl |
| Poland | pl | 548,623 | 51 | otomoto.pl, olx.pl, sprzedajemy.pl, autoplac.pl, allegro.pl, motogratka.pl |
| Bulgaria | bg | 381,265 | 24 | car24.bg, mobile.bg, cars.bg, auto.bg, bazar.bg, olx.bg |
| Austria | at | 280,203 | 35 | willhaben.at, gebrauchtwagen.at, autoscout24.at, zweispurig.at, dasweltauto.at, kleinanzeigen.at |
| Belgium | be | 264,931 | 91 | autoscout24.be, 2ememain.be, gocar.be, vroom.be, carselect.touring.be, okasie.be |
| Albania | al | 252,511 | 5 | merrjep.al, albania.landrover.com, carandclassic.com, motorsportmarkt.de, oldcar24.com |
| Switzerland | ch | 222,766 | 33 | autoscout24.ch, autolina.ch, tutti.ch, ricardo.ch, emilfrey.ch, auto.amag.ch |
| Sweden | se | 187,869 | 29 | blocket.se, bytbil.com, bilweb.se, volkswagen.se, riddermarkbil.se, hedinautomotive.se |
A country figure is a mix of portals, not a single market — half of German inventory is one site. When that matters, narrow with source or widen with source_exclude. Only the largest portals are listed here; /api/classifieds/facets?limit=0 returns all 681.
Query retail classifieds aggregated from portals across Europe.
Requires the classifieds scope.
Parameters
page / page_sizeinteger · query string1-based page and rows per page, as alternatives to offset and limit. Do not combine page with offset or page_size with limit.
Example 1 / 50·Where the value comes from Pagination state in your application.
countrystring · query stringComma-separated country codes, case-insensitive.
Example de,at·Where the value comes from /api/classifieds/facets -> countries[].value
brandstring · query stringComma-separated brands, exact as published. Compared as stored — case-sensitive. bmw matches nothing where BMW matches. Take the spelling from the facets endpoint.
Example BMW,Audi·Where the value comes from /api/classifieds/facets -> facets.brands[].value
modelstring · query stringComma-separated models. Compared as stored — case-sensitive.
Example 3 Series·Where the value comes from /api/classifieds/models?brand=BMW -> models[].value
fuelstring · query stringComma-separated normalized fuels. Exact, case-sensitive.
Example diesel·Where the value comes from /api/classifieds/facets -> facets.fuels[].value
gearboxstring · query stringComma-separated normalized gearboxes. Exact, case-sensitive.
Example automatic·Where the value comes from /api/classifieds/facets -> facets.gearboxes[].value
sellerstring · query stringComma-separated seller types, such as dealer or private. Exact, case-sensitive.
Example dealer·Where the value comes from /api/classifieds/facets -> facets.sellers[].value
sourcestring · query stringComma-separated origin portals, case-insensitive. Unlike site on the auction side, an unrecognised portal is not an error — this vocabulary is drawn from the data itself rather than fixed, so an unknown value simply matches nothing.
Example mobile.de·Where the value comes from /api/classifieds/facets -> sources[].value
source_excludestring · query stringComma-separated origin portals to leave out, case-insensitive. With ~681 portals in the vocabulary this is the only practical way to say “everything but”. A listing with no recorded portal survives an exclusion.
Example mobile.de·Where the value comes from /api/classifieds/facets -> sources[].value
price_from / price_tointeger · query stringEUR bounds.
Example 5000 / 15000·Where the value comes from EUR budget chosen by your user.
year_from / year_tointeger · query stringYear bounds.
Example 2016 / 2022·Where the value comes from Year bounds chosen by your user.
kilometers_from / kilometers_tointeger · query stringMileage bounds.
Example 0 / 200000·Where the value comes from Mileage bounds chosen by your user.
qstring · query stringCase-insensitive substring match on the listing title or its description. The description itself is not returned, so a match can look unexplained — it is text you cannot see. Rare q values are also the usual cause of total_unavailable.
Example touring·Where the value comes from Free text entered by your user.
with_photoboolean · query stringOnly listings that carry a thumbnail.
Example true·Where the value comes from Your filter choice.
sortenum · query stringDefault newest.
Example price_low·Where the value comes from Choose newest, price_low, price_high, year_new, year_old, or mileage_low.
limit / offsetinteger · query stringOr page_size / page. Default 50, max 100, offset capped at 5000. This envelope carries total, limit, offset and total_pages only — no page, page_size or max_page. Page by offset.
Example 50 / 0·Where the value comes from Pagination state in your application.
include_totalboolean · query stringDefault true. Pass false to skip the match count entirely — total comes back null and the request is markedly faster.
Example false·Where the value comes from Your pagination strategy.
Example requests
GET https://api.thecarapi.com/api/classifieds/listings?country=de,at&brand=BMW&price_to=15000GET https://api.thecarapi.com/api/classifieds/listings?seller=dealer&source=mobile.de&sort=price_low&with_photo=trueGET https://api.thecarapi.com/api/classifieds/listings?country=de&source_exclude=mobile.de,kleinanzeigen.de&include_total=falseExample response
{
"success": true,
"listings": [
{
"reference_id": "tp-91744022",
"title": "BMW 320d Touring",
"brand": "BMW",
"model": "3 Series",
"engine": "320d",
"year": 2016,
"price_eur": 12500.5,
"mileage_km": 180000,
"fuel_norm": "diesel",
"gearbox_norm": "automatic",
"colour": "black",
"doors": "5",
"country": "Germany",
"country_code": "de",
"region": "Bayern",
"seller_type": "dealer",
"source_site": "mobile.de",
"photo_count": 12,
"offer_url": "https://www.theparking.eu/...",
"image_url": "https://img.leparking.fr/...",
"published": "2026-07-30",
"first_seen_at": "2026-07-30T04:11:02",
"last_seen_at": "2026-08-05T04:09:55"
}
],
"total": 4412,
"total_capped": false,
"total_unavailable": false,
"limit": 50,
"offset": 0,
"total_pages": 89
}What you get back
reference_idstringStable identity for the listing, prefixed tp-. Use it to de-duplicate across polls.
titlestringListing headline as published by the origin portal.
brand / model / enginestringBrand and model as published, plus the engine or trim string when the portal supplies one.
yearintegerRegistration year.
price_eurnumberRetail asking price in EUR. This is an asking price, not a transaction price.
mileage_kmintegerOdometer reading in kilometres.
fuel_normstringNormalized fuel, e.g. diesel, petrol, electric, hybrid. Matches the fuel filter vocabulary.
gearbox_normstringNormalized gearbox, e.g. automatic, manual. Matches the gearbox filter vocabulary.
colourstringExterior colour as published.
doorsstringDoor count as published by the portal.
country / country_codestringCountry the car is listed in — display name and lower-case code. country_code is what the country filter accepts.
regionstringSub-national region or state when the portal publishes one.
seller_typestringdealer or private. The single most useful axis for separating trade from retail asking prices.
source_sitestringOrigin portal the listing came from, e.g. mobile.de. Matches the source / source_exclude filter vocabulary, ~681 values wide. This is the attribution that makes a country figure readable — half of all German inventory is one portal.
photo_countintegerHow many photos the origin listing carries. Only one thumbnail is exposed here.
offer_urlstringDeep link out to the listing, routed through the aggregator that indexes it — the URL is a theparking.eu one, not a direct link on the origin portal. Read source_site, not this URL, to know which portal the listing belongs to.
image_urlstringSingle remote thumbnail on the aggregator’s own CDN. Not copied into our image vault — treat it as a hotlink that disappears with the listing.
publisheddateDate the origin portal published the listing.
first_seen_at / last_seen_attimestampWhen our sweep first and most recently observed the listing. Use last_seen_at to judge staleness.
total / limit / offset / total_pagesintegerStandard pagination envelope for the matching set. total is exact for ordinary filters, and null when total_unavailable is true.
total_cappedbooleanTrue when counting stopped at 100,000. Read total as “100,000+” and page by offset rather than trusting total_pages. An unfiltered total is precomputed and never capped.
total_unavailablebooleanTrue when total is null because the count did not finish inside its budget — typically a q= search or a rare source. The listings themselves are complete and correct; only the count is missing, and the verdict is cached for 5 minutes.
Counted filter vocabulary for the classifieds dataset.
Requires the classifieds scope.
Parameters
limitinteger · query stringValues returned per dimension, default 50. 0 returns all of them — the only way to get the full 681-portal sources list.
Example 0·Where the value comes from How many values your picker can hold.
Example requests
GET https://api.thecarapi.com/api/classifieds/facetsGET https://api.thecarapi.com/api/classifieds/facets?limit=0curl -H "X-API-Key: $API_KEY" "https://api.thecarapi.com/api/classifieds/facets"Example response
{
"success": true,
"facets": {
"countries": [
{
"value": "de",
"count": 1840221
}
],
"brands": [
{
"value": "BMW",
"count": 402118
}
],
"fuels": [
{
"value": "diesel",
"count": 4110882
}
],
"gearboxes": [
{
"value": "manual",
"count": 5233901
}
],
"sellers": [
{
"value": "dealer",
"count": 8901233
}
],
"sources": [
{
"value": "mobile.de",
"count": 913442
}
],
"value_counts": {
"countries": 41,
"brands": 128,
"fuels": 7,
"gearboxes": 3,
"sellers": 2,
"sources": 683
},
"totals": {
"total": 9714882,
"total_capped": false,
"price_min": 50,
"price_max": 4500000,
"year_min": 1920,
"year_max": 2027
}
}
}What you get back
facets.countries / brands / fuels / gearboxes / sellers / sources{value, count}[]Each dimension is a list of {value, count}, most common first, nested under the facets key rather than at the top level. The values are exactly what the listings feed’s filters match on, so copy them verbatim: brands, fuels, gearboxes and sellers are compared case-sensitively downstream.
facets.value_counts.<dimension>integerHow many distinct values that dimension really has, before limit trimmed it. Check value_counts.sources against the length of sources to know whether you are looking at all of them.
facets.totals.totalintegerListings in the feed.
facets.totals.total_cappedbooleanTrue when counting stopped at 100,000 — read total as "100,000+".
facets.totals.price_min / price_max / year_min / year_maxnumber | integerEUR and year bounds across the feed, for sizing sliders.
List models available for one or more brands.
Requires the classifieds scope.
Parameters
brandstring · query stringrequiredComma-separated brand list. Required. Matched exactly and case-sensitively, like the same parameter on the listings feed — pass the spellings from the brands facet.
Example BMW,Audi·Where the value comes from /api/classifieds/facets -> facets.brands[].value
Example requests
GET https://api.thecarapi.com/api/classifieds/models?brand=BMWGET https://api.thecarapi.com/api/classifieds/models?brand=BMW,AudiExample response
{
"success": true,
"models": [
{
"value": "3 Series",
"count": 8841
},
{
"value": "5 Series",
"count": 6002
}
]
}What you get back
models{value, count}[]Model names available for the requested brands, most common first, capped at 400. value goes straight back into the model filter on /api/classifieds/listings.