TheCarApi European classifieds API

A retail price surface of roughly 9.8M live listings 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: theparking — that is the scope name in the path, not the name of a source.

Operations 3

GET /api/theparking/listings Query retail classifieds aggregated from portals across Europe #
GET /api/theparking/facets Counted filter vocabulary for the classifieds dataset #
GET /api/theparking/models List models available for one or more brands #

Work with this as data

Every API here is available over the APIs.io API and to AI agents over MCP.

MCP server

One button, every client — Claude, Cursor, VS Code and the rest.

https://apis.io/mcp

Tools for apis

7 MCP tools reach this
  • find_apisBrowse and filter every API in the catalog.
  • get_api_artifactsOne API's artifacts, grouped by type.
  • get_openapiThe primary OpenAPI for this API.
  • find_similar_apisAPIs that look like this one.
  • apis_io_searchSTART HERE — APIs, providers and tags for one query, each with its total.
  • resolveTurn a domain, URL or GitHub org into the provider it belongs to.
  • find_cohortsEvery scored population of providers in the catalog.
All 92 tools →

Call it yourself

curl for this page
This API
curl "https://apis.io/api/v1/apis/thecarapi-european-classifieds-api"
All apis
curl "https://apis.io/api/v1/apis?limit=25"

Discovery needs no key. Ratings and market analysis are Pro.

Get an API key

Free tier, no form to fill in. Signing in shares your email address with us — we store it to create your key and to recognise you if you sign in with another provider. See our Privacy Policy and Terms.

A second provider on the same verified email joins the account you already have.

OpenAPI Specification

thecarapi-european-classifieds-api-openapi.yml Raw ↑
openapi: 3.2.0
info:
  title: TheCarApi — Public European classifieds API
  version: '2026-08-19'
  summary: Multi-source vehicle auction inventory API
  description: 'Normalized vehicle auction inventory from Auto1, OpenLane, Schadeautos, Copart Germany,

    eCarsTrade, Encar and the Japanese auction houses, plus a European retail classifieds network.


    A vehicle is addressed by the pair site_name + auction_id_str, for example encar/38112900.

    Primary envelopes carry contract_version, request_id, server_time and data_updated_at; a handful of routes omit those.

    Price fields are JSON numbers, never strings.


    Full documentation: https://thecarapi.com/docs'
  contact:
    name: TheCarApi API support
    email: api@thecarapi.com
    url: https://thecarapi.com/contact
  termsOfService: https://thecarapi.com/terms
servers:
- url: https://api.thecarapi.com
  description: Production
security:
- apiKeyHeader: []
- bearerAuth: []
tags:
- name: European classifieds
  description: 'A retail price surface of roughly 9.8M live listings 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.'
  externalDocs:
    url: https://thecarapi.com/docs/theparking
paths:
  /api/theparking/listings:
    get:
      operationId: get_api_theparking_listings
      summary: Query retail classifieds aggregated from portals across Europe
      description: 'Query retail classifieds aggregated from portals across Europe.


        Every multi-value filter is OR within the parameter and AND across parameters — country=de,at&brand=BMW,Audi means (DE or AT) and (BMW or Audi). A non-numeric value on a numeric parameter is a 400, not a dropped filter. Match values exactly: country, source and source_exclude are case-insensitive; brand, model, fuel, gearbox and seller are compared as stored, so take the spellings from /api/theparking/facets rather than typing them. An unknown value is never an error here, it simply matches nothing. Counting is bounded rather than exhaustive on a feed this size: read total together with total_capped and total_unavailable, or skip it with include_total=false. Responses are served with Cache-Control: public, max-age=60 and no ETag, so conditional requests do not help here — include_total=false is the lever that does. There is no detail endpoint for these rows: those 23 keys are the whole record. Returns 503 while the dataset has not been built yet.


        Response fields — reference_id (string): Stable identity for the listing, prefixed tp-. Use it to de-duplicate across polls. title (string): Listing headline as published by the origin portal. brand / model / engine (string): Brand and model as published, plus the engine or trim string when the portal supplies one. year (integer): Registration year. price_eur (number): Retail asking price in EUR. This is an asking price, not a transaction price. mileage_km (integer): Odometer reading in kilometres. fuel_norm (string): Normalized fuel, e.g. diesel, petrol, electric, hybrid. Matches the fuel filter vocabulary. gearbox_norm (string): Normalized gearbox, e.g. automatic, manual. Matches the gearbox filter vocabulary. colour (string): Exterior colour as published. doors (string): Door count as published by the portal. country / country_code (string): Country the car is listed in — display name and lower-case code. country_code is what the country filter accepts. region (string): Sub-national region or state when the portal publishes one. seller_type (string): dealer or private. The single most useful axis for separating trade from retail asking prices. source_site (string): Origin 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_count (integer): How many photos the origin listing carries. Only one thumbnail is exposed here. offer_url (string): Deep 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_url (string): Single remote thumbnail on the aggregator’s own CDN. Not copied into our image vault — treat it as a hotlink that disappears with the listing. published (date): Date the origin portal published the listing. first_seen_at / last_seen_at (timestamp): When our sweep first and most recently observed the listing. Use last_seen_at to judge staleness. total / limit / offset / total_pages (integer): Standard pagination envelope for the matching set. total is exact for ordinary filters, and null when total_unavailable is true. total_capped (boolean): True 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_unavailable (boolean): True 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.'
      tags:
      - European classifieds
      security:
      - apiKeyHeader: []
      - bearerAuth: []
      x-scope: theparking
      x-examples:
      - GET https://api.thecarapi.com/api/theparking/listings?country=de,at&brand=BMW&price_to=15000
      - GET https://api.thecarapi.com/api/theparking/listings?seller=dealer&source=mobile.de&sort=price_low&with_photo=true
      - GET https://api.thecarapi.com/api/theparking/listings?country=de&source_exclude=mobile.de,kleinanzeigen.de&include_total=false
      parameters:
      - name: country
        in: query
        required: false
        description: 'Comma-separated country codes, case-insensitive. Value comes from: /api/theparking/facets -> countries[].value'
        schema:
          type: string
        example: de,at
      - name: brand
        in: query
        required: false
        description: 'Comma-separated brands, exact as published. Compared as stored — case-sensitive. bmw matches nothing where BMW matches. Take the spelling from the facets endpoint. Value comes from: /api/theparking/facets -> facets.brands[].value'
        schema:
          type: string
        example: BMW,Audi
      - name: model
        in: query
        required: false
        description: 'Comma-separated models. Compared as stored — case-sensitive. Value comes from: /api/theparking/models?brand=BMW -> models[].value'
        schema:
          type: string
        example: 3 Series
      - name: fuel
        in: query
        required: false
        description: 'Comma-separated normalized fuels. Exact, case-sensitive. Value comes from: /api/theparking/facets -> facets.fuels[].value'
        schema:
          type: string
        example: diesel
      - name: gearbox
        in: query
        required: false
        description: 'Comma-separated normalized gearboxes. Exact, case-sensitive. Value comes from: /api/theparking/facets -> facets.gearboxes[].value'
        schema:
          type: string
        example: automatic
      - name: seller
        in: query
        required: false
        description: 'Comma-separated seller types, such as dealer or private. Exact, case-sensitive. Value comes from: /api/theparking/facets -> facets.sellers[].value'
        schema:
          type: string
        example: dealer
      - name: source
        in: query
        required: false
        description: 'Comma-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. Value comes from: /api/theparking/facets -> sources[].value'
        schema:
          type: string
        example: mobile.de
      - name: source_exclude
        in: query
        required: false
        description: 'Comma-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. Value comes from: /api/theparking/facets -> sources[].value'
        schema:
          type: string
        example: mobile.de
      - name: price_from
        in: query
        required: false
        description: 'EUR bounds. Value comes from: EUR budget chosen by your user.'
        schema:
          type: integer
        example: '5000'
      - name: price_to
        in: query
        required: false
        description: 'EUR bounds. Value comes from: EUR budget chosen by your user.'
        schema:
          type: integer
        example: '5000'
      - name: year_from
        in: query
        required: false
        description: 'Year bounds. Value comes from: Year bounds chosen by your user.'
        schema:
          type: integer
        example: '2016'
      - name: year_to
        in: query
        required: false
        description: 'Year bounds. Value comes from: Year bounds chosen by your user.'
        schema:
          type: integer
        example: '2016'
      - name: kilometers_from
        in: query
        required: false
        description: 'Mileage bounds. Value comes from: Mileage bounds chosen by your user.'
        schema:
          type: integer
        example: '0'
      - name: kilometers_to
        in: query
        required: false
        description: 'Mileage bounds. Value comes from: Mileage bounds chosen by your user.'
        schema:
          type: integer
        example: '0'
      - name: q
        in: query
        required: false
        description: 'Case-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. Value comes from: Free text entered by your user.'
        schema:
          type: string
        example: touring
      - name: with_photo
        in: query
        required: false
        description: 'Only listings that carry a thumbnail. Value comes from: Your filter choice.'
        schema:
          type: boolean
        example: 'true'
      - name: sort
        in: query
        required: false
        description: 'Default newest. Value comes from: Choose newest, price_low, price_high, year_new, year_old, or mileage_low.'
        schema:
          type: string
        example: price_low
      - name: limit
        in: query
        required: false
        description: 'Or 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. Value comes from: Pagination state in your application.'
        schema:
          type: integer
        example: '50'
      - name: offset
        in: query
        required: false
        description: 'Or 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. Value comes from: Pagination state in your application.'
        schema:
          type: integer
        example: '50'
      - name: include_total
        in: query
        required: false
        description: 'Default true. Pass false to skip the match count entirely — total comes back null and the request is markedly faster. Value comes from: Your pagination strategy.'
        schema:
          type: boolean
        example: 'false'
      responses:
        '200':
          description: Success.
          content:
            application/json:
              schema:
                type: object
              example:
                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
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '429':
          $ref: '#/components/responses/RateLimited'
  /api/theparking/facets:
    get:
      operationId: get_api_theparking_facets
      summary: Counted filter vocabulary for the classifieds dataset
      description: 'Counted filter vocabulary for the classifieds dataset.


        Takes no filters — it always describes the whole feed. This is the discovery endpoint for every other classifieds filter: always build selects from here rather than hard-coding values, because brand/model/fuel/gearbox/seller are compared case-sensitively. The default trim of 50 matters most for sources (~680 origin portals); value_counts.sources tells you how many exist and limit=0 returns them all. The vocabulary changes only when the feed is rebuilt, so it is cached for an hour and served with Cache-Control: public, max-age=600. One cached vocabulary answers every limit, so asking for limit=0 once and trimming client-side costs the same as asking for limit=10. Returns 503 while the dataset has not been built yet.


        Response fields — 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. (integer): How 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.total (integer): Listings in the feed. facets.totals.total_capped (boolean): True when counting stopped at 100,000 — read total as "100,000+". facets.totals.price_min / price_max / year_min / year_max (number | integer): EUR and year bounds across the feed, for sizing sliders.'
      tags:
      - European classifieds
      security:
      - apiKeyHeader: []
      - bearerAuth: []
      x-scope: theparking
      x-examples:
      - GET https://api.thecarapi.com/api/theparking/facets
      - GET https://api.thecarapi.com/api/theparking/facets?limit=0
      - 'curl -H "X-API-Key: $API_KEY" "https://api.thecarapi.com/api/theparking/facets"'
      parameters:
      - name: limit
        in: query
        required: false
        description: 'Values returned per dimension, default 50. 0 returns all of them — the only way to get the full 681-portal sources list. Value comes from: How many values your picker can hold.'
        schema:
          type: integer
        example: '0'
      responses:
        '200':
          description: Success.
          content:
            application/json:
              schema:
                type: object
              example:
                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
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '429':
          $ref: '#/components/responses/RateLimited'
  /api/theparking/models:
    get:
      operationId: get_api_theparking_models
      summary: List models available for one or more brands
      description: 'List models available for one or more brands.


        brand is required — calling without it returns 400. Because brands are published verbatim by each portal, always take the brand value from /api/theparking/facets rather than typing it. Cached for 600 seconds. Returns 503 while the dataset has not been built yet.


        Response fields — 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/theparking/listings.'
      tags:
      - European classifieds
      security:
      - apiKeyHeader: []
      - bearerAuth: []
      x-scope: theparking
      x-examples:
      - GET https://api.thecarapi.com/api/theparking/models?brand=BMW
      - GET https://api.thecarapi.com/api/theparking/models?brand=BMW,Audi
      parameters:
      - name: brand
        in: query
        required: true
        description: 'Comma-separated brand list. Required. Matched exactly and case-sensitively, like the same parameter on the listings feed — pass the spellings from the brands facet. Value comes from: /api/theparking/facets -> facets.brands[].value'
        schema:
          type: string
        example: BMW,Audi
      responses:
        '200':
          description: Success.
          content:
            application/json:
              schema:
                type: object
              example:
                success: true
                models:
                - value: 3 Series
                  count: 8841
                - value: 5 Series
                  count: 6002
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '429':
          $ref: '#/components/responses/RateLimited'
components:
  responses:
    Forbidden:
      description: Revoked key, or scope, IP, or origin denial.
      content:
        application/json:
          schema:
            type: object
            properties:
              success:
                type: boolean
                enum:
                - false
              error:
                type: string
                description: Sanitized failure message.
    RateLimited:
      description: Authentication lockout or quota exceeded. Honour Retry-After.
      content:
        application/json:
          schema:
            type: object
            properties:
              success:
                type: boolean
                enum:
                - false
              error:
                type: string
                description: Sanitized failure message.
    BadRequest:
      description: Invalid filter, pagination, source, parameter, or request body.
      content:
        application/json:
          schema:
            type: object
            properties:
              success:
                type: boolean
                enum:
                - false
              error:
                type: string
                description: Sanitized failure message.
    NotFound:
      description: Source-aware resource not found.
      content:
        application/json:
          schema:
            type: object
            properties:
              success:
                type: boolean
                enum:
                - false
              error:
                type: string
                description: Sanitized failure message.
    Unauthorized:
      description: Missing, invalid, or expired API key.
      content:
        application/json:
          schema:
            type: object
            properties:
              success:
                type: boolean
                enum:
                - false
              error:
                type: string
                description: Sanitized failure message.
  securitySchemes:
    apiKeyHeader:
      type: apiKey
      in: header
      name: X-API-Key
    bearerAuth:
      type: http
      scheme: bearer
externalDocs:
  description: API reference
  url: https://thecarapi.com/docs