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 (500 on a key granted bulk pages). 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. Link out with source_url (the ad on the origin portal) and fall back to source_url_redirect when it is null; /api/classifieds/resolve resolves one listing on demand.
- 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
resolve_urlsboolean · query stringDefault true: listings on the page whose source_url has never been looked up are resolved during the request, in parallel, and remembered. false answers faster with whatever has been resolved so far; source_url_redirect works either way.
Example false·Where the value comes from Your latency choice.
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 (up to 500 on a key granted bulk pages), 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/...",
"source_url": "https://www.mobile.de/...",
"source_url_redirect": "https://www.theparking.eu/tools/ETHCMOLB/0/F.html",
"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_urlstringThe aggregator’s own detail page for the listing — a theparking.eu URL, not the ad itself. Read source_site, not this URL, to know which portal the listing belongs to.
source_urlstring | nullThe ad on the origin portal named by source_site. Null until it has been resolved, and on a listing the portal has already dropped — fall back to source_url_redirect.
source_url_redirectstring | nullThe aggregator’s outbound tracker, which redirects to the origin ad. Present whenever offer_url is, so it is the link to use while source_url is null.
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.
Resolve the origin portal URL of one classified listing.
Requires the classifieds scope.
Parameters
reference_idstring · query stringThe listing’s stable identifier. One of reference_id, offer_url or slug is needed.
Example 9190319266·Where the value comes from /api/classifieds/listings -> listings[].reference_id
offer_urlstring · query stringThe aggregator detail URL, as an alternative to reference_id.
Example https://www.theparking.eu/used-cars-detail/vehicle/ad/CODU642L.html·Where the value comes from /api/classifieds/listings -> listings[].offer_url
slugstring · query stringThe aggregator listing slug, as an alternative to reference_id.
Example CODU642L·Where the value comes from The last path segment of offer_url.
redirectboolean · query stringtrue answers with a 302 straight to the origin ad (or the tracker fallback) instead of JSON — usable as the href of an outbound link. Default false.
Example true·Where the value comes from Your link-handling choice.
Example requests
GET https://api.thecarapi.com/api/classifieds/resolve?reference_id=9190319266GET https://api.thecarapi.com/api/classifieds/resolve?slug=CODU642L&redirect=trueExample response
{
"success": true,
"reference_id": "9190319266",
"slug": "CODU642L",
"offer_url": "https://www.theparking.eu/used-cars-detail/vehicle/ad/CODU642L.html",
"source_site": "autoscout24.be",
"source_url": "https://www.autoscout24.be/fr/offres/-ac3cffef-3c79-4a97-b1e3-a08f3e776a00",
"source_url_redirect": "https://www.theparking.eu/tools/ETHCMOLB/0/F.html",
"status": "resolved"
}What you get back
source_urlstring | nullThe ad on the origin portal named by source_site. Null when it could not be resolved.
source_url_redirectstring | nullThe aggregator’s outbound tracker, which redirects to the origin ad. Use it whenever source_url is null.
statusenumresolved (source_url is set), expired (the portal no longer has the ad) or unresolved (the lookup did not answer this time).
Bulk export of the classifieds feed, up to 1,000 listings per request at any depth.
LockedApproved accounts only. Bulk export is its own permission, granted only to accounts we have approved: the classifieds scope does not include it, and any other key gets 403. Contact us to apply for access.
Requires the classifieds-export scope.
Parameters
afterinteger · query stringCursor. Omit (or send 0) for the first page, then pass each response’s next_after until it comes back null.
Example 0·Where the value comes from The previous page’s next_after.
limitinteger · query stringListings per page. Default and maximum 1000; larger values are lowered to 1000.
Example 1000·Where the value comes from Page size chosen by your sync job.
fieldsstring · query stringComma-separated columns to return, in this order. Defaults to all of them. An unknown name is a 400 that lists the valid ones.
Example reference_id,brand,model,year,price_eur,source_url·Where the value comes from Any of: reference_id, title, brand, model, engine, year, price_eur, mileage_km, fuel_norm, gearbox_norm, colour, doors, country, country_code, region, seller_type, source_site, photo_count, offer_url, source_url, image_url, published, first_seen_at, last_seen_at, source_url_redirect.
countrystring · query stringComma-separated country codes, case-insensitive.
Example de,at·Where the value comes from /api/classifieds/facets -> facets.countries[].value
brand / modelstring · query stringComma-separated, exact and case-sensitive as on /api/classifieds/listings.
Example BMW / 3 Series·Where the value comes from /api/classifieds/facets, /api/classifieds/models
fuel / gearbox / sellerstring · query stringComma-separated normalized values, exact and case-sensitive.
Example diesel / automatic / dealer·Where the value comes from /api/classifieds/facets
source / source_excludestring · query stringComma-separated origin portals to keep or leave out, case-insensitive.
Example mobile.de·Where the value comes from /api/classifieds/facets -> 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 stringSubstring match on title and description. Unindexed, so slow on a narrow match.
Example touring·Where the value comes from Free text.
with_photoboolean · query stringOnly listings that carry a thumbnail.
Example true·Where the value comes from Your filter choice.
Example requests
GET https://api.thecarapi.com/api/classifieds/export?country=de&fields=reference_id,brand,model,year,price_eur,source_urlGET https://api.thecarapi.com/api/classifieds/export?country=de&after=91744022Example response
{
"success": true,
"columns": [
"reference_id",
"brand",
"model",
"year",
"price_eur",
"source_url"
],
"rows": [
[
"tp-91744022",
"BMW",
"3 Series",
2016,
12500.5,
"https://www.mobile.de/..."
],
[
"tp-91744023",
"Audi",
"A4",
2018,
17900,
null
]
],
"count": 2,
"next_after": null,
"contract_version": "2026-10-05"
}What you get back
columnsstring[]The name of each position in a row — your fields, in your order.
rowsarray[]One array per listing, values in columns order. Each key is sent once per page rather than once per listing, which keeps a 1,000-row page small.
countintegerRows on this page.
next_afterinteger | nullPass as after for the next page. null on the last page.