top-offers

Live auctions priced below their market reference

The same deals /api/search?sort=top_offers surfaces, as a feed of their own — and each card additionally carries the market_reference the verdict was made against, which search does not return.

A car qualifies only when its saving clears a continuous, reference-quality-aware bar (wider price spread, thinner evidence and slower-selling models all raise it), so this is a shortlist, not "everything below average". Rows leave the feed the moment the auction ends, so total shrinks through the day and grows again after each comparison run.

A non-numeric value on any numeric parameter is a 400, not a dropped filter. These are cycle prices, never live-refreshed.

get/api/top-offers

Request

  • Base URL: https://api.thecarapi.com
  • URL: https://api.thecarapi.com/api/top-offers
  • Auth: one of:
    • API key in header X-API-Key
    • HTTP bearer
    • API key in query parameter api_key

Query parameters

sitestring
Example:openlane,ecarstrade

Comma-separated source slugs from /api/sites, OR within the parameter. Case-insensitive; padding and empty members are ignored. An unknown slug is a 400 naming the offender.

site_excludestring
Example:copart

Comma-separated source slugs to leave out. Same rules as site.

brandstring
Example:BMW

Exact clean_make, case-insensitive.

modelstring
Example:3 Series

Exact clean_model, case-insensitive.

countrystring
Example:DE

Vehicle country code, case-insensitive.

year_frominteger
Example:2018

Lower bound on registration year, inclusive.

year_tointeger
Example:2024

Upper bound on registration year, inclusive.

kilometers_frominteger

Lower bound on mileage in kilometres.

kilometers_tointeger

Upper bound on mileage in kilometres.

price_frominteger

Lower bound on the public EUR price.

price_tointeger

Upper bound on the public EUR price.

min_savings_pctinteger
Example:20

Only offers saving at least this percentage.

sort'savings_pct' | 'savings' | 'price_low' | 'price_high' | 'newest'
limitinteger

Page size. Capped at pagination.max_limit from GET /api/contract (100 by default); larger values are clamped down rather than rejected. Do not combine with page_size — that is a 400.

offsetinteger

0-based row offset. Do not combine with page — that is a 400. Bounded by pagination.max_offset (5000 by default) on archive, catalog, top-offers and classifieds; /api/search and /api/listVehicles have no offset cap.

pageinteger

1-based page number; maps to offset = (page - 1) * limit. Do not combine with offset.

page_sizeinteger

Alias for limit. Do not combine with limit.

steering'left' | 'lhd' | 'left-hand' | 'left_hand' | 'right' | 'rhd' | 'right-hand' | 'right_hand'
Example:left

Which side the steering wheel is on. The parameter takes two values, left and right; lhd/left-hand/left_hand and rhd/right-hand/right_hand are equivalent spellings of them. Any other value is a 400.

Derived rather than stored. The side is taken from the car's registration market, so a car from an ISO country that drives on the left (GB, IE, JP, CY, MT, AU, NZ, ZA, IN, TH, HK, SG) is right and everything else is left. Every listing resolves to one side or the other, so the two values partition the inventory and their totals sum to the unfiltered total. The same value is published on each result as steering.

Accepted by /api/search, /api/listVehicles, /api/top-offers and every facet endpoint, which narrow their option lists by it. Sending it to a facet endpoint takes that request off the precomputed facet table and onto a live aggregate, so it is slower than an unfiltered facet call.

Headers

If-None-Matchstring
Example:W/"6f1c0a9d8e"

Echo back the ETag from your last response for this URL. An unchanged page answers 304 Not Modified with no body. ETags are weak, so the tag stays valid whether or not the body came back compressed.

Response

Qualifying offers.

successboolean required
contract_versionstring

Matches info.version of this document.

request_idstring

Also returned as the X-Request-ID header.

server_timestring date-time

UTC ISO-8601 timestamp of the response.

data_updated_atstring date-time

Route-supplied data timestamp, falling back to server_time. Not a guaranteed source refresh time; inspect listing observation timestamps and live_price.fetched_at where available.

totalinteger nullable

null when totals are suppressed or could not be computed.

limitinteger
offsetinteger
pageinteger
page_sizeinteger
total_pagesinteger nullable

null when total is null.

max_pageinteger nullable

Deepest page reachable under the offset policy.

Example response

{
  "success": true,
  "contract_version": "2026-09-03",
  "results": [
    {
      "auction_id": 38112900,
      "site_name": "openlane",
      "clean_make": "BMW",
      "clean_model": "320d",
      "model_display": "320d M Sport",
      "registration_year": 2020,
      "production_year": 2019,
      "production_month": 11,
      "mileage": 45000,
      "fuel_group": "Diesel",
      "gearbox_group": "Automatic",
      "steering": "left",
      "public_price_eur": 21500,
      "auction_end_at": "2026-08-20T10:00:00Z",
      "country_code": "DE",
      "auction_id_str": "38112900",
      "market_reference": {
        "price_eur": 11500,
        "mileage": 165000,
        "km_difference": -15000
      }
    }
  ]
}

Changes

No recorded changes to this operation across all 1 revision of this API.